簡體   English   中英

檢索JS對象原型的最佳方法

[英]Best way to retrieve the prototype of a JS object

試圖了解Javascript中的原型。 對於此示例:

var obj = new Function();
obj.prototype.x = "a";

為什么我從中得到不同的結果

console.log(obj.__proto__);

console.log(obj.prototype);

謝謝

根據此來源: https : //developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/prototype

Object.prototype.__proto__指向在實例化對象時用作原型的對象。

這僅表示用作創建Function對象的原型的對象是空函數,這就是為什么在輸出中有function Empty() {}的原因。 您可以在這里觀察它:

console.log(Function.prototype);
var func = new Function();
console.log(func.__proto__);
console.log(func.prototype);
// OUTPUT:
// function Empty() {}
// function Empty() {}
// Object {} 

__proto__一個空對象(例如var a = {}Object {}因為這是,什么被用來創建對象的基(換句話說Object.prototype被使用)。 而且prototype甚至不能作為的屬性a ,因為您已經創建了一個完全空的對象,因此沒有任何東西。

另請注意, __proto__現在已棄用

為什么? 我不知道,但是我從未用過,所以我不在乎:)

prototype是另一回事,例如

Object prototype object更改將傳播到所有對象,除非經受這些更改的屬性和方法沿原型鏈進一步被覆蓋。

這就是為什么您需要prototype並且在現實生活中不關心__proto__ 如果我寫錯了,請告訴我__proto__有用用法。

希望現在更清楚。 並回答您的原始問題:

只能通過使用prototype屬性來檢索JS對象的prototype ,因為__proto__包含其他內容。 如果不存在prototype屬性,那么即使在實例化過程中使用了sth,也不會存在JS對象的原型。

在:

> var obj = new Function();

創建一個新的函數對象,該對象的內部[[Prototype]] (或支持它的瀏覽器中的__proto__ )引用Function.prototype ,即內置Function構造函數的公共原型,並分配給變量obj

因為obj是一個Function對象,所以默認情況下它具有prototype屬性,以防萬一它被用作構造函數。

在:

> obj.prototype.x = "a";

新的x屬性將添加到obj.prototype中 ,該屬性被分配了字符串'a' 請注意,默認情況下, obj僅具有prototype屬性,因為它是Function對象。

所以:

obj.prototype === obj.__proto__

本質上是:

obj.prototype === Function.prototype

這顯然是錯誤的。

因此,要回答“檢索JS對象原型的最佳方法”的問題,則可以通過其原型屬性訪問構造函數的公共原型。

您可以使用ES5 Object.getPrototypeOf來訪問實例的內部[[Prototype]] ,但是可能並非在所有地方都支持該實例。

您還可以使用受支持的非標准__proto__來訪問實例的內部[[Prototype]]

更為通用的解決方案是在創建實例時保留對構造函數原型的引用(因為在以后的某個階段更改構造函數的原型不會更改已經創建的實例的[[Prototype]] )。

因此,在一般情況下,您可以這樣做:

function Foo() {
  this.internalProto = Foo.prototype;
}

var foo = new Foo();

// ES5, where supported
Object.getPrototypeof(foo) == Foo.prototype; // true

foo.internalProto == Foo.prototype; // true

// Non–standard, Where supported
foo.internalProto == foo.__proto__;     // true

根據MDN ,obj .__ proto__尚未標准化。

因此,盡管obj.prototype在所有瀏覽器中都有明確的標准化行為,但obj .__ proto__在不同瀏覽器中的行為有所不同。

您正在橫向看...

.prototype.__proto__是同一對象(或在某個特定時間點)...

BUUUUUT它們是不同對象的屬性。

var Human = function (name) {
    this.num_eyes = 2;
    this.num_heads = 1;
    this.name = name;
};
Human.prototype.die = function () { this.isAlive = false; };

var herman = new Human("Herman");

herman.__proto__.die === Human.prototype.die; // true

.__proto__是指向CONSTRUCTOR .prototype的鏈接(通常是SAME對象)

幾乎是這樣的:

var Human = function () {
    this = {};
    this.num_eyes = 2;
    // ......
    this.__proto__ = Human.prototype;
};

那不是構造函數的確切工作方式,但實際上就是這個想法。
這就是為什么.__proto__.prototype不是同一回事。
因為您找錯了地方。

因此,如果:

var herman = new Human();
herman.__proto__ === Human.prototype;
var Human = new Function ();

...因此邏輯規定Human.__proto__ === Function.prototype;

...並且如果HumanFunction不是同一對象,則它們的.prototype屬性將不會相同(除非您用另一個Human.prototype = Function.prototype; Human.__proto__ === Human.prototype; //true

暫無
暫無

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

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