JavaScript之原型解析(上)

前言

原型這個概念在JavaScript這門語言中是一個核心關鍵的知識點,可是你是否真的已經徹底理解透徹了呢?可能我我的的理解能力較差,所以通過屢次翻閱書籍和實踐我才真正瞭解原型,因此記錄下來以加深理解,也以便往後深刻探討。若有不正確的地方,歡迎斧正!javascript

原型涉及到的概念

  1. __proto__/[[prototype]]
  2. prototype
  3. constructor

區分原型指針和原型屬性

注:首先要區分的是原型指針__proto__/[[prototype]]和原型屬性prototype,不少時候咱們可能會把它們混爲一談,可是二者實際上不是同一種東西!!!前端

  • 原型指針__proto__/[[prototype]]

先來看一個例子:java

var obj = {};
function fn() {};
console.log(obj.__proto__ === Object.prototype); // true
console.log(obj.__proto__ === Object.getPrototypeOf(obj)); // true
console.log(fn.__proto__ === Function.prototype); // true
console.log(fn.__proto__ === Object.getPrototypeOf(Function)); // true

實際上,實例對象的原型指針[[prototype]]在某些宿主環境下是不能讀取到的;
但也有例外:
(1) 在瀏覽器環境下原型指針能夠使用__proto__屬性讀取到
(2) ECMAScript 5版本增長的新方法Object.getPrototypeOf()能夠進行讀取到瀏覽器

解釋:
每一個對象在建立的時候都會有個原型指針的屬性指向負責構造該對象的原型對象,以上面爲例 ->
obj是由原型對象Object.prototype構造的,等同於使用new Object構造
fn是由原型對象Function.prototype構造的,等同於使用new Function構造spa

經典的原型鏈圖示prototype

圖片描述設計

謹記,往原型鏈向上追溯,最終都是由原型對象Object.prototype進行構造!指針

  • 原型屬性prototype

再來個栗子:code

var obj = {};
function fn() {};
console.log(obj.prototype); // undefined
console.log(fn.prototype === Object.prototype); // false
console.log(fn.prototype === new fn().__proto__); // true
console.log(fn.prototype === Object.getPrototypeOf(new fn)); // true

解釋:
之前我一直混淆的概念就在這裏,
爲何obj.prototype是undefined呢?
爲何fn.prototype指向的不是Object.prototype?
若是你跟我同樣有這樣的疑惑的話,說明你理解錯了原型指針__proto__/[[prototype]]和原型屬性prototype的概念!!!對象

/**
* 1. 若是你想獲得構造某對象的原型對象,你應該讀取該對象的原型指針
* 2. 然而,讀取某對象的原型屬性prototype時,你的意圖應該是想以該對象做爲原型對象進行構造實際對象
/
// 這就解析了爲何,實例對象new fn的原型指針__proto__指向了fn.prototype(fn的原型屬性)
// 另外,由於obj是普通對象,不能夠使用new關鍵字進行構造實例,所以天然也就沒有原型屬性了 -> undefined

若是還有疑惑,建議結合上面經典的原型鏈圖示進行思考!

  • 構造器指針constructor

老規矩,上代碼

var obj = {};
function fn() {};
console.log(obj.constructor === Object); // true
console.log(fn.constructor === Function); // true
console.log(obj.hasOwnProperty('construnctor')); // false
console.log(fn.hasOwnProperty('construnctor')); // false

經過以上代碼,咱們能夠知道,其實objfn對象自身並無constructor這個屬性,實際上constructor構造他們的原型對象上面的屬性,而且指向構造對象自己!(once again,若是還有疑惑請建議結合上面經典的原型鏈圖示進行思考!)

參考文獻

  1. javascript高級程序設計(第三版)——[美]Nichilas C.Zakas 著
  2. javascript權威指南(第6版)——David Flangan 著 淘寶前端團隊 譯
相關文章
相關標籤/搜索