最近,我偶然發現了JavaScript中的Object.create()
方法,並試圖推斷出它與使用new SomeFunction()
建立對象的新實例有何不一樣,以及什麼時候要在另外一個對象上使用它。 閉包
考慮如下示例: ide
var test = { val: 1, func: function() { return this.val; } }; var testA = Object.create(test); testA.val = 2; console.log(test.func()); // 1 console.log(testA.func()); // 2 console.log('other test'); var otherTest = function() { this.val = 1; this.func = function() { return this.val; }; }; var otherTestA = new otherTest(); var otherTestB = new otherTest(); otherTestB.val = 2; console.log(otherTestA.val); // 1 console.log(otherTestB.val); // 2 console.log(otherTestA.func()); // 1 console.log(otherTestB.func()); // 2
請注意,在兩種狀況下都觀察到相同的行爲。 在我看來,這兩種狀況之間的主要區別是: 函數
Object.create()
使用的對象實際上造成了新對象的原型,而在聲明的屬性/函數中的new Function()
則沒有造成原型。 Object.create()
語法建立閉包。 給定JavaScript的詞法(與代碼塊)類型範圍,這是合乎邏輯的。 以上說法正確嗎? 我想念什麼嗎? 您何時可使用另外一個? this
編輯:連接到上述代碼示例的jsfiddle版本: http : //jsfiddle.net/rZfYL/ spa
這是兩個調用在內部執行的步驟:
(提示:惟一的區別在於步驟3) .net
new Test()
: prototype
new Object()
obj obj.__proto__
到Test.prototype
return Test.call(obj) || obj; // normally obj is returned but constructors in JS can return a value
Object.create( Test.prototype )
code
new Object()
obj obj.__proto__
到Test.prototype
return obj;
所以,基本上Object.create
不執行構造函數。 orm
區別在於所謂的「僞古典與原型繼承」。 建議在代碼中僅使用一種類型,而不是將兩種類型混合使用。 對象
在僞古典繼承中(使用「 new」運算符),假設您先定義一個僞類,而後從該類建立對象。 例如,定義一個僞類「 Person」,而後從「 Person」建立「 Alice」和「 Bob」。
在原型繼承中(使用Object.create),您直接建立一個特定的人「 Alice」,而後使用「 Alice」做爲原型建立另外一我的「 Bob」。 這裏沒有「班級」; 都是對象。
在內部,JavaScript使用「原型繼承」。 「僞古典」方式只是一些糖。
有關兩種方法的比較,請參見此連接 。
簡而言之, new X
是Object.create(X.prototype)
,另外還要運行constructor
函數。 (並使constructor
有機會return
實際對象,該對象應該是表達式的結果而不是this
。)
而已。 :)
其他的答案只是使人困惑,由於顯然沒有其餘人會讀new
的定義。 ;)
function Test(){ this.prop1 = 'prop1'; this.prop2 = 'prop2'; this.func1 = function(){ return this.prop1 + this.prop2; } }; Test.prototype.protoProp1 = 'protoProp1'; Test.prototype.protoProp2 = 'protoProp2'; var newKeywordTest = new Test(); var objectCreateTest = Object.create(Test.prototype); /* Object.create */ console.log(objectCreateTest.prop1); // undefined console.log(objectCreateTest.protoProp1); // protoProp1 console.log(objectCreateTest.__proto__.protoProp1); // protoProp1 /* new */ console.log(newKeywordTest.prop1); // prop1 console.log(newKeywordTest.__proto__.protoProp1); // protoProp1
摘要:
1)使用new
關鍵字須要注意兩點;
a)函數用做構造函數
b)將function.prototype
對象傳遞給__proto__
屬性...或不支持__proto__
的地方,它是新對象查找屬性的第二個位置
2)使用Object.create(obj.prototype)
構造一個對象( obj.prototype
)並將其傳遞給預期的對象..區別在於如今新對象的__proto__
也指向obj.prototype(請參考xj9)
這個:
var foo = new Foo();
和
var foo = Object.create(Foo.prototype);
很是類似。 一個重要的區別是, new Foo
實際上運行構造函數代碼,而Object.create
將不會執行諸如
function Foo() { alert("This constructor does not run with Object.create"); }
請注意,若是您使用Object.create()
的兩個參數版本,則能夠執行更強大的操做。