徹底理解JavaScript中的prototype、__proto__


雖然在JavaScript里一切皆對象,但為了理解原型鏈系統,我們需要將JavaScript的對象分為對象和函數兩大類。在此基礎上,JavaScript的原型鏈邏輯遵從以下通用規則:

  • 對象有__proto__屬性,函數有prototype屬性;
  • 對象由函數生成;
  • 生成對象時,對象的__proto__屬性指向函數的prototype屬性。

在沒有手動修改__proto__屬性的指向時,以上三條便是JavaScript默認原型鏈指向邏輯。

1、一般情況:

// 創建空對象時,實際上我們是用Object函數來生成對象的:
var o = {}
o.__proto__ === Object.prototype 
// ==> true

// 我們也可以顯式的使用Object函數來創建對象:
var o = Object()
o.__proto__ === Object.prototype
// ==> true

// 當我們使用函數來創建自定義的對象時,上面的規則同樣適用:
function MyObj(){}
typeof MyObj
// ==> "function"
var mo = new MyObj()
mo.__proto__ === MyObj.prototype
// ==> true 	

2、函數對象
既然JavaScript里“一切皆對象”,那函數自然也是對象的一種。對於函數作為對象來說,上面的規則同樣適用:

// 函數對象都是由Function函數生成的:
>function fn(){}
>fn.__proto__ === Function.prototype
// ==> true

// Function函數本身作為對象時,生成它的函數是他自身!
>Function.__proto__ === Function.prototype
// ==> true

// Object函數既然是函數,那生成它的函數自然是Function函數咯:
>Object.__proto__ === Function.prototype
// ==> true

來看一個例子:

function Say(name, age) {
    this.name = name;
    this.age = age;
}
var person = new Say('jone', 30);
console.log(person instanceof Say);                     					// ==> true
console.log(person.__proto__ === Say.prototype);						    // ==> true
console.log(person.__proto__.constructor === Say.prototype.constructor);    // ==> true
var obj = {};
console.log(obj.__proto__ == Object.prototype)  							// ==> true
var fn = function() {};
console.log(fn.__proto__ === Function.prototype);							// ==> true

總結:

js里所有的對象都有__proto__屬性(對象,函數),指向構造該對象的構造函數的原型。
只有函數function才具有prototype屬性。這個屬性是一個指針,指向一個對象,這個對象的用途就是包含所有實例共享的屬性和方法(我們把這個對象叫做原型對象)。原型對象也有一個屬性,叫做constructor,這個屬性包含了一個指針,指回原構造函數。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM