原型鏈

原型對象

JS原型對象初始化

參考函數建立的簡單步驟,以下:javascript

F = new NativeObject();

//第一步:設置Class:function;
F.[[Class]] = "Function"

//第二步:函數對象的隱式prototype指向Function的顯示原型, function的prototype也是一個對象, 是Object對象的實例, Object又是由Function構建出來的, 因此能夠循環此步驟;
F.[[Prototype]] = Function.prototype

//第三步:初始化
F.[[Call]] = <reference to function>
F.[[Construct]] = internalConstructor

//第四步:初始化當前執行上下文的做用域鏈
F.[[Scope]] = activeContext.Scope

// 若是函數經過new Function(...)來建立,那麼
F.[[Scope]] = globalContext.Scope

//第五步:初始化傳入參數的個數
F.length = countParameters

//第六步:F對象建立的原型
__objectPrototype = new Object();
__objectPrototype.constructor = F
F.prototype = __objectPrototype

return F

什麼是原型對象

  • 從上面能夠看出, 每個構造函數都有一個原型屬性, 稱爲prototype, 它指向一個對象, 這個對象稱爲原型對象;java

  • 默認全部原型對象自動得到constructor屬性;constructor又引用了函數自己,因此也造成了JS中的構造函數和prototype的循環引用;函數

原型對象的問題

  • 原型對象是由全部實例共享,對於包含引用類型值的屬性來講,修改會影響到全部的實例;
  • 原型模式普遍應用於原生的引用類型如Object、Array、String等, 但不推薦在程序中修改原生對象的原型, 容易致使命名衝突;

原型鏈

通常的解釋:this

  • 全部對象均可以有原型,而且原型也是對象,因此接着它們也能夠有原型,原型又能夠有原型,如此就造成了所謂的原型鏈。當鏈條中的對象有一個值爲null 的原型時,原型鏈終止。

ECMA的解釋:spa

  • Every object created by a constructor has an implicit reference (called the object’s prototype) to the value of its constructor’s 「prototype」 property. Furthermore, a prototype may have a non-null implicit reference to its prototype, and so on; this is called the prototype chain.

看了如上中文解釋,你確定會困擾吧?是由於它只一味的提到原型; 而沒有對隱式的原型 [[prototype]]和顯示的prototype進行區分;prototype

因此你可能會認爲, 按照第一種解釋以下代碼先尋找A.prototype, 發現A.prototype = null; 原型鏈終止,A.toString是否是會報undefined呢?指針

//分析function A的原型鏈
function A() {}

A.prototype = null;

A.toString();

再看英文解釋: Every object created by a constructor has an implicit reference (called the object’s prototype) to the value of its constructor’s 「prototype」 property;code

很是清晰:對象

  • 全部由構造器建立的對象都有一個隱式的prototype, 它指向構造器的prototype屬性
  • 因此原型鏈實際上是由當前對象的隱式prototype指針指向的對象的隱式prototype指針指向的對象的…., 直到隱式prototype指向的對象爲空爲至;有點饒;

Object的prototype是null嗎?

解釋一:Object 構造器的默認原型值爲null;blog

解釋二:15.2.4 Properties of the Object Prototype Object

    The value of the [[Prototype]] internal property of the Object prototype object is null, the value of the [[Class]] internal property is 「Object」, and the initial value of the [[Extensible]] internal property is true.

 

解釋一也存在和上面同樣的問題,而英文的解釋則很是明顯:

並不是Object.prototype = null而是function Object中的隱式的prototypenull, 以下:

function Object() {};
var obj = new Object();
obj.[[prototype]] = Object.prototype
Object.prototype.[[prototype]] = null;

示例

看了上述的描述, 若是你徹底理解了顯示prototype和隱式prototype,我想你應該會很快n能畫出以下對象的原型鏈了。試試看吧:

示例1:請描述a對象的原型鏈

var A = function() {};

A.prototype = { b: 2, c: 3 };

var a = new A();

示例二:請描述b對象的原型鏈

var A = function() {}

A.prototype = { b: 2, c: 3 };

var B = function() {}

B.prototype = new A();

var b = new B();

 

 

相關文章
相關標籤/搜索