手记

重学JS(十四)—— 一直被忽略的原型链

早已认为自己已经掌握了原型链,直到遇到这几个问题

Object.__proto__ == Object.prototype  //falseObject.__proto__ == Function.prototype  //true

__proto__倒是经常见,但没有去思考它和prototype的区别。

概念

对象具有属性__proto__,可称为隐式原型,一个对象的隐式原型指向构造该对象的构造函数的原型,这也保证了实例能够访问到构造函数原型中定义的属性和方法。
方法(Function)方法这个特殊的对象,除了和其他对象一样有上述__proto__属性之外,还有自己特有的属性——原型属性(prototype),这个属性是一个指针,指向一个对象,这个对象的用途就是包含所有实例共享的属性和方法。

new

上面的理论始终离不开构造函数四个字,不如先看看new 干了什么
1.先创建了一个新的空对象
2.然后让这个空对象的__proto__指向函数的原型prototype
3.将对象作为函数的this传进去,返回创建的这个对象
看到没,第二步!将对象的__proto__指向函数的原型prototype。看文字不清楚的话,用代码模拟下

function New(Foo){  const o = new Object(); //创建了一个新的空对象o
  o.__proto__ = Foo.prototype; //让这个o对象的__proto__指向函数的原型prototype
  Foo.call(o); //this指向o对象
  return o;
}

所以很明了了,这些问题再也难不倒你

var a = {};
a.__proto__ == Object.prototype;  //a调用了Object构造函数,所以__proto__指向Object.prototypevar b = function(){}
b.__proto__ == Function.prototype  //b调用了Function构造函数,所以__proto__指向Function.prototypeb.__proto__.__proto__ == Object.prototype //Function.prototype是个对象,所以它的__proto__指向Object.prototypeObject.__proto__ == Function.prototype //Object作为一个函数对象,它的__proto__指向构造函数Function的prototypeObject.prototype.__proto__== null  //Object.prototype是一切的源头,所以它的__proto__是null。

但是也有小例外

var obj1 = {a:1};var obj2 = Object.create(obj1);
obj2.__proto__ == Object.prototype   //falseobj2.__proto__  == obj1;  //true

这函数是用现有对象为原型,即__proto__来创建一个新对象。

原型链

有如下代码

function A(){}
A.prototype.c = 1;var a = new A();
a.c;  //1

那么它对应的原型链



a寻找自己的属性c没有找到,就顺着__proto__找到了A.prototype,它有属性c,所以a.c的值是1。

总结

prototype是函数才有的属性,class也可以当作构造函数,所以它也有。__proto__是每个对象都有的属性,它指向该对象的构造函数的prototype。



作者:闪闪发光的狼
链接:https://www.jianshu.com/p/70313eeb0146


0人推荐
随时随地看视频
慕课网APP