簡體   English   中英

構造函數和原型

[英]constructor and prototype

有人可以解釋一下嗎?

function Foo() {
    this.x = 1;
    this.y = 2;
}

function FooProto() {
    this.arrow = 1;
    this.bow = 1;
}

document.writeln(Foo.prototype); // [object Object] 
document.writeln(Foo.prototype.constructor); // function Foo() { x =1; y=2; }

我的理解是:Foo.prototype是一個Object,其構造函數屬性是Function Foo。 Foo。[[Prototype]]是Function.Prototype

obj = new Foo;
document.writeln(obj.constructor); // function Foo() { x =1; y=2; }
document.writeln(obj.constructor.prototype); // [object Object]

Foo.prototype = FooProto;

document.writeln(Foo.prototype); // function FooProto() { arrow = 1; bow = 2; }
document.writeln(Foo.prototype.constructor); // function Function() { [native code] }

問題1:如何使用[[Prototype]]進行查找。 如果有人能向我解釋,我將不勝感激。

document.writeln(obj.constructor); // function Foo() { x =1; y=2; } .. no change
document.writeln(obj.constructor.prototype); // function FooProto() { arrow = 1; bow = 2; }

anotherObj = new Foo;
document.writeln(anotherObj.constructor); // function Function() { [native code] }
document.writeln(anotherObj.constructor.prototype); // function Empty() {}

問題2:與問題1相同的問題.Javascript解釋器是如何執行查找的?

在解釋基於原型的代碼時,使用Object.create來解釋內容要簡單得多。 Object.create是一個函數,它接收一個原型對象並創建一個新的實例對象,該對象將原型對象作為其[[prototype]]

在對象中查找屬性時,工作方式如下:

每個對象都有自己的,不可變的[[prototype]]屬性。 這個屬性是秘密和隱藏的,除非你在Firefox中,你可以通過__proto__獲取它。

讀取屬性時,我們首先在對象本身中搜索它,如果我們在那里找不到它,我們遞歸搜索對象的[[prototype]]。

編寫屬性時,我們總是編寫一個自己的屬性(我們永遠不會改變[[prototype]],即使它也具有我們正在設置的屬性)。

proto = {a:1};
child1 = Object.create(proto);
child2 = Object.create(proto);

child1.a = 2;

console.log(proto.a);  //1
console.log(child1.a); //2
console.log(child2.a); //1

創建功能時

每當我們在Javascript中創建一個函數對象時,它都會附帶一個已經填充的prototype屬性。這個prototype是一個對象(繼承自Object.prototype)並且將constructor屬性設置為相應的函數。

使用函數構造函數實例化對象時(new Foo)

使用函數prototype作為其[[prototype]]創建一個新對象,並在該對象上運行該函數以初始化它。


  1. 我真的不想解釋第一種情況發生了什么,因為Foo.prototype = FooProto; 部分沒有意義,可能不是你想做的(記住原型應該是對象,而不是函數)

  2. 至於第二種情況,更改構造函數的prototype屬性只會影響將來的實例(anotherObj)。 已創建對象的[[prototype]]屬性是秘密且不可變的,因此您無法更改它們。

    • 請注意,如果要動態更改原型和現有對象(猴子修補),可以通過在現有原型對象中編寫和覆蓋值而不是用新的替換它來實現。

Javascript中有兩個原型概念。 (我把它當作語言設計中的名字碰撞。)

  1. 原型鏈中的原型 它是最后一個答案中提到的內部屬性。 訪問它的首選方法是Object.getPrototypeOf

     var a = {}; Object.getPrototypeOf(a); // Object {} Object.getPrototypeOf(Object.getPrototypeOf(a)); // null, the top of prototype chain. Object.getOwnPropertyNames(Object.getPrototypeOf(a)); // the methods inherited 
  2. 每個構造函數 (我認為所有聲明的函數)都有自己的屬性“prototype”。 它在new運營商中使用。

new操作員執行兩個步驟。

  1. 首先是創建一個對象,其原型(第一個,說,[[Prototype]])被指定為構造函數的原型(第二個)。
  2. 二是運行的構造函數(從仰視prototype.constructor )與服用創建對象作為隱含參數this

現在你的情況:

第一個obj是使用其[[Prototype]]屬性(某些引擎中的proto )創建的,分配為Foo.prototype。

obj.constructor === obj.__proto__.constructor === Foo.prototype.constructor === Foo
obj.constructor.prototype === Function.prototype

請注意,構造函數也是Function對象。

然后你改變了Foo的原型。 這改變了obj.constructor.prototype而不是obj.constructor ,它有不同的引用。 anotherObj從以下new運算符中獲得了一個新的[[Prototype]]。

這個問題已經存在多年了。 以下讀者可能也會像我一樣困惑。 我推薦了Axel Rauschmayer博士新出版的“ Speaking JavaScript ”一書:

術語:兩個原型

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM