瞭解Object.create()和new SomeFunction()之間的區別

最近,我偶然發現了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


#1樓

這是兩個調用在內部執行的步驟:
(提示:惟一的區別在於步驟3) .net


new Test()prototype

  1. 建立new Object() obj
  2. 設置obj.__proto__Test.prototype
  3. return Test.call(obj) || obj; // normally obj is returned but constructors in JS can return a value

Object.create( Test.prototype ) code

  1. 建立new Object() obj
  2. 設置obj.__proto__Test.prototype
  3. return obj;

所以,基本上Object.create不執行構造函數。 orm


#2樓

區別在於所謂的「僞古典與原型繼承」。 建議在代碼中僅使用一種類型,而不是將兩種類型混合使用。 對象

在僞古典繼承中(使用「 new」運算符),假設您先定義一個僞類,而後從該類建立對象。 例如,定義一個僞類「 Person」,而後從「 Person」建立「 Alice」和「 Bob」。

在原型繼承中(使用Object.create),您直接建立一個特定的人「 Alice」,而後使用「 Alice」做爲原型建立另外一我的「 Bob」。 這裏沒有「班級」; 都是對象。

在內部,JavaScript使用「原型繼承」。 「僞古典」方式只是一些糖。

有關兩種方法的比較,請參見此連接


#3樓

簡而言之, new XObject.create(X.prototype) ,另外還要運行constructor函數。 (並使constructor有機會return實際對象,該對象應該是表達式的結果而不是this 。)

而已。 :)

其他的答案只是使人困惑,由於顯然沒有其餘人會讀new的定義。 ;)


#4樓

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)


#5樓

這個:

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()的兩個參數版本,則能夠執行更強大的操做。

相關文章
相關標籤/搜索