js原型链
对js原型链理解:
1 在js中,万物皆为对象,分为函数对象和普通对象两种。
如上图所示,o1,o2,o3都为普通对象,f1,f2,f3都为函数对象,通过 new Function() 创建的对象都是函数对象,其他的都是普通对象。f1,f2,归根结底都是通过 new Function()的方式进行创建的。Function Object 也都是通过 New Function()创建的。
2 在js中每个对象都有_proto_属性,但是只有函数对象有prototype属性。说了半天,那什么是原型对象?原型对象其实就是普通的对象,如下图所示,Person.prototype指向Person的原型对象。可以说,Person.prototype就是Person的原型。
所有的原型对象都会自动获得一个 constructor
(构造函数)属性,这个属性(是一个指针)指向 prototype
属性所在的函数(Person),即Person.prototype.constructor == Person,并且实例的构造函数属性(constructor)指向构造函数 :person1.constructor == Person。
由此:
Person.prototype.constructor == Person
person1.constructor == Person
得出结论:原型对象(Person.prototype)是 构造函数(Person)的一个实例。
3 __proto__
JS 在创建对象(不论是普通对象还是函数对象)的时候,都有一个叫做__proto__
的内置属性,用于指向创建它的构造函数的原型对象。
对象 person1 有一个 __proto__
属性,创建它的构造函数是 Person,构造函数的原型对象是 Person.prototype ,所以:person1.__proto__ == Person.prototype
请看下图:
4. 原型链
小测试来检验一下你理解的怎么样:
-
person1.__proto__
是什么? -
Person.__proto__
是什么? -
Person.prototype.__proto__
是什么? -
Object.__proto__
是什么? -
Object.prototype__proto__
是什么?
答案:
第一题:
因为 person1.__proto__ === person1 的构造函数.prototype
因为 person1的构造函数 === Person
所以 person1.__proto__ === Person.prototype
第二题:
因为 Person.__proto__ === Person的构造函数.prototype
因为 Person的构造函数 === Function
所以 Person.__proto__ === Function.prototype
第三题:Person.prototype
是一个普通对象,我们无需关注它有哪些属性,只要记住它是一个普通对象。
因为一个普通对象的构造函数 === Object
所以 Person.prototype.__proto__ === Object.prototype
第四题,参照第二题,因为 Person 和 Object 一样都是构造函数
第五题:Object.prototype
对象也有proto属性,但它比较特殊,为 null 。因为 null 处于原型链的顶端,这个只能记住。Object.prototype.__proto__ === null