JS原型和原型链

47 阅读2分钟

原型和原型链

每个函数都有一个prototype属性,只有函数才有。

这是每⼀个JavaScript对象(除了 null )都具有的⼀个属性,叫 __proto__ ,这个属性会指向该对象的

原型。

构造函数和实例原型的关系图

既然实例对象和构造函数都可以指向原型,那么原型是否有属性指向构造函数或者实例呢?

指向实例倒是没有,因为一个构造函数可以生成多个实例,实例对象过多指向太复杂。constructor就可以指向构造函数。每个原型都有一个constructor属性指向关联的构造函数

function Person(){}
console.log(Person===Person.prototype.constructor)//true

根据这张图片可以得到以下:

function Person(){}
let p1=new Person()
console.log(person.__proto__===Person.prototype)//true
console.log(Person.prototype.constructor == Person)// true
//api方法获取
console.log(Object.getPrototypeOf(person) === Person.prototype)// true

实例对象与原型

当读取实例的属性时,如果找不到,就会查找与对象关联的原型中的属性,如果还查不到,就去找原型

的原型,⼀直找到最顶层为⽌。

function Person() {
}
Person.prototype.name = 'zhanglei';
var person = new Person();
person.name = 'zhanglei';
console.log(person.name) // zhanglei
delete person.name;
console.log(person.name) // zhanglei

在这个例⼦中,我们给实例对象 person 添加了 name 属性,当我们打印 person.name 的时候,结

果⾃然为 zhanglei。

但是当我们删除了 person 的 name 属性时,读取 person.name ,从 person 对象中找不到 name

属性就会从 person 的原型也就是 person.__proto__ ,也就是 Person.prototype 中查找,

结果为 zhanglei。

原型的原型

如果在原型上还没有找到呢?原型的原型⼜是什么呢?

其实原型对象就是通过 Object 构造函数⽣成的,结合之前所讲,实例的 __proto__ 指向构造函数

的 prototype ,所以我们再更新下关系图:

原型链

Object.prototy的原型是啥?打印看看

console.log(Object.prototype.__proto__ === null) // true 

从代码可以看出,Object的原型的原型为null,null表示“没有对象”,即该处不应该有值。

所以Object.prototype.__proto__的值为null和Object.prototype没有原型,表达了一个意思。

所以在实例对象上查找属性和方法的时候,根据原型链,查找到Object.prototype就可以停止了查找了。

最终的原型链的图如下: