JavaScript 系列之原型(二)

335 阅读2分钟

这是我参与8月更文挑战的第4天,活动详情查看:8月更文挑战

二、原型链

当试图得到一个对象的某个属性时,如果这个对象本身没有这个属性,那么沿着它的 __proto__(即它的构造函数的原型)中寻找,就是链式结构称为原型链。

那么如何判断这个属性是不是对象本身的属性呢?使用 hasOwnProperty,常用的地方是遍历一个对象的时候。

var item;
for (item in f) {
  // 高级浏览器已经在 for in 中屏蔽了来自原型的属性,但是这里建议大家还是加上这个判断,保证程序的健壮性
  if (f.hasOwnProperty(item)) {
    console.log(item);
  }
}

三、原型和原型链应用

为什么需要原型及原型链?

function Person(name, age) {
  this.name = name;
  this.age = age;
  this.eat = function() {
    console.log(age + "岁的" + name + "在吃饭。");
  }
}

let p1 = new Person("jsliang", 24);
let p2 = new Person("jsliang", 24);

console.log(p1.eat === p2.eat); // false

可以看到,对于同一个函数,我们通过 new 生成出来的实例,都会开出新的一块堆区,所以上面代码中 person1person2 的吃饭是不同的(返回 false)。

拥有属于自己的私有属性和方法,有时候也需要公有属性和方法,那么如何建设共享库呢?—— prototype

function Person(name) {
  this.name = name;
}

// Person 在它的原型上定义了一块空间 eat,所有的人都可以共享它
Person.prototype.eat = function() {
  console.log("吃饭");
}

let p1 = new Person("jsliang", 24);
let p2 = new Person("梁峻荣", 24);

console.log(p1.eat === p2.eat); // true

四、总结

  1. Object.prototype 是所有对象的爸爸,所有对象都可以通过 __proto__ 找到它
  2. Function.prototype 是所有函数的爸爸,所有函数都可以通过 __proto__ 找到它
  3. Function.prototypeObject.prototype 是两个特殊的对象,他们由引擎来创建
  4. 除了以上两个特殊对象,其他对象都是通过构造器 new 出来的
  5. 每个函数(比如构造函数)都有 prototype 属性(除了 Function.prototype.bind()),该属性指向原型
  6. 每个对象都有 __proto__ 属性,指向了创建该对象的构造函数的原型
  7. 原型对象的 constructor 指回构造函数
  8. 实例的 __proto__ 指向该对象的构造函数的原型对象,该对象的构造函数的原型对象中定义了共享的属性和方法,对象可以通过 __proto__ 来寻找不属于该对象的属性,__proto__ 将对象连接起来组成了原型链。

相关文章