完全理解JavaScript中的prototype、__proto__

雖然在JavaScript裏一切皆對象,但爲了理解原型鏈系統,咱們須要將JavaScript的對象分爲對象和函數兩大類。在此基礎上,JavaScript的原型鏈邏輯聽從如下通用規則:函數

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

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

一、通常狀況:prototype

// 建立空對象時,實際上咱們是用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

二、函數對象
既然JavaScript裏「一切皆對象」,那函數天然也是對象的一種。對於函數做爲對象來講,上面的規則一樣適用:指針

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

// Function函數自己做爲對象時,生成它的函數是他自身!
>Function.__proto__ === Function.prototype
// ==> true

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

來看一個例子:code

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,這個屬性包含了一個指針,指回原構造函數。對象

相關文章
相關標籤/搜索