[英]difference between Object.create(Object.prototype) , Object.create(Object) and Object.create(null)
我應該為其他人繼承的第一個父對象傳遞哪個參數,哪個參數更有效
Object.create(Object.prototype)
Object.create(Object)
Object.create(null)
Object.create(null)
返回一個空對象
Object.create(Object)
返回一個函數為什么????(我檢查了我的日志,它說的是函數...我使用了console.dir())
Object.create(Object)
返回一個非空對象
這一切是如何工作的......我更習慣於Classname .prototype的東西:(
無法理解這里發生了什么
前言:JavaScript使用原型繼承,這意味着一個對象可以擁有(通常有)一個原型 ,它是另一個對象。 如果您嘗試從它沒有的對象獲取屬性的值,JavaScript引擎會查找對象的原型(及其原型等)以查找它。
Object.create
創建對象。 您給Object.create
的第一個參數是用作它創建的對象的原型的對象。 所以:
// Create an object with a property 'foo'
var a = {
foo: 42
};
// Create a blank object using `a` as its prototype
var b = Object.create(a);
// Give `b` a property of its own
b.bar = "hi";
這讓我們記憶猶新:
+−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−−−−−+ | [[Prototype]] |−−−−−>| (the standard | a−−−−−−−−−−−−−−−−−−−−−−+−−>| foo: 42 | | object prototype) | | +−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−−−−−+ | +−−−−−−−−−−−−−−−+ | b−−>| [[Prototype]] |−−+ | bar: "hi" | +−−−−−−−−−−−−−−−+
證明b
使用a
:
console.log(b.foo); // 42
a.foo = 67;
console.log(b.foo); // 67
解決一些變化:
var o = Object.create(Object.prototype);
這與var o = {};
完全相同var o = {};
:它創建一個新的空白對象,其原型是對象Object.prototype
引用。
var o = Object.create(Object);
這會創建一個新的空白對象o
其原型是Object
函數。 它不會創建一個函數,只是一個具有函數作為其原型的非函數對象。 這可能很奇怪,可能不是你想要的。 :-)
var o = Object.create(null);
創建一個新的空白對象o
其原型為null
。 由於它的原型是null
,它沒有通常的Object.prototype
東西,比如toString
和valueOf
以及hasOwnProperty
。 這有點不尋常,雖然有一些用例,例如當你使用一個對象作為字典/地圖而不想要那些屬性名稱的誤報時。 (在ES2015 [aka ES6]中,另一種選擇是使用Map
代替。)
正如thg435在下面的評論中指出的那樣,關於JavaScript的一個令人困惑的事情是,對象的prototype
您在函數上看到的prototype
屬性完全不同。 如果prototype
屬性有一個不同的名稱可能會更好(雖然我無法想象沒有大規模笨重的名稱)。
一個對象(我們稱之為o
)有一個繼承屬性的原型對象。 (在ES2015 +中,您可以通過Object.getPrototypeOf
訪問該對象。)函數的prototype
屬性上的對象不一定是任何對象的原型。 相反,它是將被指定為通過new
使用該函數創建的任何對象的原型的對象。
這里有例子幫助。
function Foo() {
}
該函數Foo
具有引用對象的屬性Foo.prototype
。 那個對象還沒有用作任何東西的原型。 它只是一個分配給Foo
對象實例上名為prototype
的屬性的對象。
var f = new Foo();
現在該對象被用作原型,特別是它是new Foo
調用創建的f
對象的原型。
忽略一些細節,這行代碼:
var f = new Foo();
...基本上這樣做:
// Create a blank object, giving it `Foo.prototype` as its prototype
var f = Object.create(Foo.prototype);
// Call` Foo` using that new object as `this`
Foo.call(f);
正如我所說,這留下了一些細節,但希望它有助於明確函數的prototype
屬性是什么......
返回的是一個對象。
>>> typeof Object.create(Object)
<<< "object"
>>> Object.create(Object)
<<< Function {}
// ^^
Function
是Chrome處理對象構造Function
的名稱。 請參閱如何在Chrome Dev Tools中為自定義類計算javascript類名?
這部分答案解決了@ phenomnomnominal在問題中的評論,解釋了為什么創建的對象繼承了函數屬性,如call
。
Object
構造函數是一個函數,因此繼承自Function
原型:
>>> Object.call === Function.prototype.call
<<< true
因此,具有Object
作為原型的Object
也將通過原型鏈鏈接到Function原型:
>>> Object.create(Object).call === Function.prototype.call
<<< true
正如@TJ所提到的,使用構造函數作為原型是相當奇怪的。 您應該將對象指定為創建的對象將繼承的原型。 @TJ已經做了很好的解釋這部分的工作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.