一、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