JSON字符串/原型链/构造函数

原型链

原型对象也是普通的对象,并且也有可能有自己的原型,如果一个原型对象的原型不为null的话,我们就称之为原型链(prototype chain)。原型链是一个由对象组成的有限的对象链,用于实现继承和属性共享。

ECMAScript没有类的概念。但是,重用[reuse]这个理念没什么不同(某些方面,甚至比class-更加灵活),可以由prototype chain原型链来实现。这种继承被称为delegation based inheritance-基于继承的委托,或者更通俗一些,叫做原型继承。

简单例子:

var a = {
  x: 10,
  calculate: function (z) {
    return this.x + this.y + z
  }
};
 
var b = {
  y: 20,
  __proto__: a
};
 
var c = {
  y: 30,
  __proto__: a
};
 
// 调用继承过来的方法
b.calculate(30); // 60
c.calculate(40); // 80

原理很简单:如果在对象b中找不到calculate方法(也就是对象b中没有这个calculate属性), 那么就会沿着原型链开始找。如果这个calculate方法在b的prototype中没有找到,那么就会沿着原型链找到a的prototype,一直遍历完整个原型链。记住,一旦找到,就返回第一个找到的属性或者方法。因此,第一个找到的属性成为继承属性。如果遍历完整个原型链,仍然没有找到,那么就会返回undefined。

注意一点,this这个值在一个继承机制中,仍然是指向它原本属于的对象,而不是从原型链上找到它时,它所属于的对象。例如,以上的例子,this.y是从b和c中获取的,而不是a。当然,你也发现了this.x是从a取的,因为是通过原型链机制找到的。

如果一个对象的prototype没有显示的声明过或定义过,那么__prototype__的默认值就是object.prototype, 而object.prototype也会有一个__prototype__, 这个就是原型链的终点了,被设置为null。


构造函数

原型链通常将会在这样的情况下使用:对象拥有相同或相似的状态结构(same or similar state structure) (即相同的属性集合)与 不同的状态值(different state values)。在这种情况下,我们可以使用构造函数(Constructor) 在 特定模式(specified pattern) 下创建对象。

除了创建对象,构造函数(constructor) 还做了另一件有用的事情—自动为创建的新对象设置了原型对象(prototype object) 。原型对象存放于 ConstructorFunction.prototype 属性中。

// 构造函数
function Foo(y) {
  // 构造函数将会以特定模式创建对象:被创建的对象都会有"y"属性
  this.y = y;
 
// "Foo.prototype"存放了新建对象的原型引用
// 所以我们可以将之用于定义继承和共享属性或方法
// 所以,和上例一样,我们有了如下代码:
 
// 继承属性"x"
Foo.prototype.x = 10;
 
// 继承方法"calculate"
Foo.prototype.calculate = function (z) {
  return this.x + this.y + z;
};
 
// 使用foo模式创建 "b" and "c"
var b = new Foo(20);
var c = new Foo(30);
 
// 调用继承的方法
b.calculate(30); // 60
c.calculate(40); // 80
 
// 让我们看看是否使用了预期的属性
 
console.log(
 
  b.__proto__ === Foo.prototype, // true
  c.__proto__ === Foo.prototype, // true
 
  // "Foo.prototype"自动创建了一个特殊的属性"constructor"
  // 指向a的构造函数本身
  // 实例"b"和"c"可以通过授权找到它并用以检测自己的构造函数
 
  b.constructor === Foo, // true
  c.constructor === Foo, // true
  Foo.prototype.constructor === Foo // true
 
  b.calculate === b.__proto__.calculate, // true
  b.__proto__.calculate === Foo.prototype.calculate // true
 
);


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章