【前端工程師手冊】JavaScript之原型

又是一個比較重要的知識點——原型(prototype)。html

一個例子

function F() {}
var f = new F()
F.prototype  // {constructor: ƒ}
f.__proto__  // {constructor: ƒ}
F.prototype === f.__proto__  // true
F.prototype.constructor === F  // true

能夠看到F函數有一個屬性prototype指向了一個對象{constructor: ƒ},由F函數new出來的對象f有一個屬性__proto__指向一個對象{constructor: ƒ}。且f.__proto__和F.prototype指向了同一個對象。F.prototype有一個constructor屬性又指回了F自己。
總結一下便是:git

  • prototype:JavaScript中每一個函數都有一個prototype屬性,此屬性指向了該函數的原型對象
  • __proto__:JavaScript中每個對象(null除外),包括函數建立的對象、函數自身、原型對象,都有一個__proto__屬性,指向了建立該對象的函數的原型
  • constructor:該屬性屬於原型對象,指向相關的構造函數

繼續探究

既然剛剛說了每個對象包括原型對象都有__proto__屬性,那麼繼續來試驗:github

// 接上一段代碼
F.__proto  // ƒ () { [native code] }
F.prototype.__proto__  // {constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}
F.__proto__ === Function.prototype  // true
F.prototype.__proto__ === Object.prototype  // true

首先,F做爲一個函數的同時它也是對象,因此它擁有屬性__proto__指向了Function.prototype,由於全部的函數均可以理解爲Function的實例;一樣的,F.prototype做爲一個對象,它的__proto__指向Object.prototype,由於它是對象且沒有指明的構造函數,因此它直接是Object函數生成的實例,天然__proto__就指向Object.prototype。函數

如今再來探究一下Object.prototype做爲一個對象,它的__proto__又指向了什麼呢?this

Object.prototype .__proto__  // null

Object.prototype.__proto__指向了null,這也說明了null是原型鏈的頂端。spa

上述的全部指向關係能夠用一張圖來表示:
prototype
ps:這裏面有一個細節,Function.__proto__ === Function.prototype
Function做爲方法,它有本身的prototype;Function做爲對象,它的__proto__指向了Function.prototype,這彷佛是在說:Function方法生成了Function對象?
針對這個問題,我以爲仍是看這篇文章比較合適,我就不費口舌了。prototype

能夠是使用prototype作什麼?

建立對象的數據共享code

function Person(){}
Person.prototype.name = "Nicholas";
Person.prototype.age = 29;
Person.prototype.job = "Software Engineer";
Person.prototype.sayName = function(){
    alert(this.name);
};
var person1 = new Person();
person1.sayName();   //"Nicholas"
var person2 = new Person();
person2.sayName(); //"Nicholas"
alert(person1.sayName == person2.sayName);  //true

把一些實例共享的屬性和方法放在原型上,節約空間。htm

基於原型鏈的委託繼承

function Child(){}

function Parent(){
    this.name = 'ppp'
}

Child.prototype = new Parent()

var c = new Child()

c.name   // 'ppp'

這個原型繼承的關係能夠用圖來表示:
原型繼承對象

參考資料:
JavaScript深刻之從原型到原型鏈
強大的原型和原型鏈

相關文章
相關標籤/搜索