一、prototype和_proto_的概念
1、__proto__:是一个对象拥有的内置属性,是JS内部使用寻找原型链的属性。可以理解为它是一个指针,用于指向创建它的函数对象的原型对象prototype(即构造函数的prototype)。
用chrome和FF都可以访问到对象的__proto__属性,IE不可以。
2、prototype(原型对象):是函数(Function)的一个属性(每个函数都有一个prototype),这个对象包含了此函数的所有实例共享的属性和方法,即:原型对象。
原型对象(prototype)是用来做什么的呢?主要作用是用于继承。例:
var person = function(name){ this.name = name }; person.prototype.getName = function(){ return this.name; } var Li = new person(‘LiMing’);
具体是怎么实现的继承,就要讲到下面的原型链了。
二、原型链
前面提到,JS在创建对象(不论是普通对象还是函数对象)的时候,都有一个叫做__proto__的内置属性,用于指向创建它的函数对象的原型对象prototype。
刚才的例子:
// 创建Li的构造函数为person,所以: Li.__proto__ === person.prototype // Object {} // person.prototype对象也有__proto__属性,它指向创建它的函数对象(Object)的prototype person.prototype.__proto__ === Object.prototype // Object {} // Object.prototype对象也有__proto__属性,但它比较特殊,为null Object.prototype.__proto__ == null // null
我们把这个有__proto__串起来的直到Object.prototype.__proto__为null的链叫做原型链。
new 的过程:
(1) var p={}; 也就是说,初始化一个对象p;
(2) p.__proto__ = Person.prototype;
将Person的prototype原型指向p的原型,这样p就拥有了Person中的方法。
(3) Person.call(p); 也就是说构造p,也可以称之为初始化p。
将Person中的this关键字指向p,执行Person构造函数(类)的代码。
三、更多的例子:(在Chrome浏览器中Console)
// 定义一个函数 function Foo(){} Foo.prototype //=> Object {} Foo.__proto__ //=> function () {} Foo.prototype.__proto__ //=> Object {} Foo.__proto__.__proto__ //=> Object {} Foo.prototype.__proto__.__proto__ //=> null Foo.__proto__.__proto__.__proto__ //=>null
// 实例化一个对象 let o = new Object() o.__proto__ //=> Object {} o.__proto__.__proto__ //=> null
Object.__proto__ //=> function () {} Object.__proto__.__proto__ //=> Object {} Object.__proto__.__proto__.__proto__ //=> null
Function.__proto__ //=> function () {} Function.__proto__.__proto__ //=> Object {} Function.__proto__.__proto__.__proto__ //=> null Function.prototype //=> function () {} Function.prototype.__proto__ //=> Object {} Function.prototype.__proto__.__proto__ //=> null