2012-06-25 43 views
5

我有一些測試類如何爲JavaScript對象

TestKlass = (function() { 

    function TestKlass(value) { 
     this.value = value != null ? value : 'hello world'; 
     console.log(this.value); 
    } 

    return TestKlass; 

})(); 

x = new TestKlass; 
x instanceof TestKlass; (gives true) 

我有新的空對象

y = {} 
y instanceof Object 

我能找到任何方式爲Ÿ設置任何屬性的東西設置的類名像這樣

y.__proto__ = x.__proto__ 
y.constructor.prototype = x.constructor.prototype 

爲了得到這個結果

y instanceof TestKlass => true 

============================================ ========

UPD:

所以。我的主要目標 - 創建CLONE功能。現在我的解決方案適用於我。請看看這個代碼:

JavaScript的JS對象克隆

Object._clone = function(obj) { 
    var clone, property, value; 
    if (!obj || typeof obj !== 'object') { 
    return obj; 
    } 
    clone = typeof obj.pop === 'function' ? [] : {}; 
    clone.__proto__ = obj.__proto__; 
    for (property in obj) { 
    if (obj.hasOwnProperty(property)) { 
     value = obj.property; 
     if (value && typeof value === 'object') { 
     clone[property] = Object._clone(value); 
     } else { 
     clone[property] = obj[property]; 
     } 
    } 
    } 
    return clone; 
}; 

CoffeeScript的JS對象克隆

# Object clone 
Object._clone = (obj) -> 
    return obj if not obj or typeof(obj) isnt 'object' 
    clone = if typeof(obj.pop) is 'function' then [] else {} 

    # deprecated, but need for instanceof method 
    clone.__proto__ = obj.__proto__ 

    for property of obj 
    if obj.hasOwnProperty property 
     # clone properties 
     value = obj.property 
     if value and typeof(value) is 'object' 
     clone[property] = Object._clone(value) 
     else 
     clone[property] = obj[property] 

    clone 

現在你可以嘗試這樣做,

A = new TestKlass 
B = Object._clone(A) 
B instanceof TestKlass => true 

它的做工精細用Moz FF 13.但我認爲這不是跨瀏覽器。和proto已棄用。

我認爲沒有通用的解決方案。但也許這對別人會有幫助。

+0

'y.constructor = x.constructor'?只是猜測......但是,真的,你不應該關心類型。我的意思是,如果有一個簡單的方法來僞造他們,他們有什麼好處呢? – cHao

+0

答案能否爲您提供足夠的信息?如果是這樣,你能否接受答案? :-) –

+0

我只是尋找最佳解決方案。深入學習這個頁面後,我將標記最佳答案http://javascript.ru/tutorial/object/inheritance(俄語) –

回答

1

也許您應該首先閱讀以下answer。你試圖達到的是非常簡單的。不過在我解釋讓我們來看看您的解決方案:

解決方案1 ​​

​​

我不建議這樣做,因爲__proto__屬性現在deprecated。以上代碼在​​中不起作用。

解決方案2

y.constructor.prototype = x.constructor.prototype; 

這是一個非常糟糕的解決方案。原因是y.constructor實際上是y.__proto__.constructor並且因爲y是對象y.__proto__Object.prototype相同。這意味着y.constructorObject相同,並且基本上更改Objectprototype屬性。這可能會破壞您網頁上的其他代碼。我強烈勸阻這種做法。

解決方案3(我的解決方案)

你想要做的是簡單地改變一個對象的內部[[proto]]財產。由於沒有跨平臺的方式,我們需要使用黑客技術。一個簡單的解決方案是創建一個具有所需__proto__屬性的新對象,並在其上設置getter和setter來更改原始對象。這將是如下:

function setPrototypeOf(object, prototype) { 
    var constructor = function() { 
     for (var key in object) { 
      if (object.hasOwnProperty(key)) { 
       (function (key) { 
        Object.defineProperty(this, key, { 
         get: function() { 
          return object[key]; 
         }, 
         set: function (value) { 
          object[key] = value; 
         }, 
         enumerable: true 
        }); 
       }).call(this, key); 
      } 
     } 
    }; 

    constructor.prototype = prototype; 

    return new constructor; 
} 

這一切後,你需要做的是:

y = setPrototypeOf(y, TestKlass.prototype); 

這裏是一個工作fiddle

編輯:

與克隆功能的問題是,它只是克隆對象和數組。您忘記說明也通過引用傳遞的函數。因此,當你克隆一個具有對象內部狀態方法的對象時,對象和它的克隆將共享相同的內部狀態。請參閱以下fiddle

function Value(value) { 
    this.get = function() { 
     alert(value); 
    }; 
    this.set = function (newValue) { 
     value = newValue; 
    }; 
} 

var a = new Value(5); 
var b = Object._clone(a); 
b.set(10);    // setting b to 10 also sets a to 10 
a.get();     // alerts 10, should alert 5 

但絕對在JavaScript沒有辦法克隆對象,因此克隆對象和數組在JavaScript中的內部狀態將僅適用於不公開的閉包方法的對象。

要了解更多關於在JavaScript中克隆對象的問題,請閱讀answer。點擊以下link來閱讀John Resig的答案。

1

obj instanceof SomeConstructor檢查在obj的原型鏈中是否找到SomeConstructor。

如果您需要繼承,則需要將FirstConstructor的.prototype設置爲新創建的SomeConstructor對象。

SomeConstructor = function() {} 
FirstConstructor = function() {} 
FirstConstroctor.prototype = new SomeConstructor(); 

var y = new FirstConstroctor(); 
y instanceof FirstConstructor; // true 
y instanceof SomeConstructor ; // true, it bubbles from FirstConstructor.__proto__ to SomeConstructor