2011-12-19 43 views
4

如何在不調用構造函數的情況下複製對象及其原型鏈?如何在不調用構造函數的情況下複製對象及其原型鏈?

換句話說,函數dup在下面的例子中看起來像什麼?

class Animal 
    @sleep: -> console.log('sleep') 
    wake: -> console.log('wake') 
end 
class Cat extends Animal 
    constructor: -> 
    super 
    console.log('create') 

    attack: -> 
    console.log('attack') 
end 

cat = new Cat()   #> create 
cat.constructor.sleep() #> sleep 
cat.wake()    #> wake 
cat.attack()   #> attack 

dup = (obj) -> 
    # what magic would give me an effective copy without 
    # calling the Cat constructor function again. 

cat2 = dup(cat)   #> nothing is printed! 
cat2.constructor.sleep() #> sleep 
cat2.wake()    #> wake 
cat2.attack()   #> attack 

,因爲它的痛苦,我看爲多,這裏的例子的jsfiddle

儘管在我的例子中只使用函數,我還需要屬性。

+1

您知道jsFiddle現在支持CoffeeScript了嗎?使用左側的**面板**菜單。 – 2011-12-19 20:26:19

+0

我沒有,太棒了! – 2011-12-19 20:32:26

回答

5
function dup(o) { 
    return Object.create(
     Object.getPrototypeOf(o), 
     Object.getOwnPropertyDescriptors(o) 
    ); 
} 

其中依靠ES6 Object.getOwnPropertyDescriptors。你可以效仿它。 Taken from pd

function getOwnPropertyDescriptors(object) { 
    var keys = Object.getOwnPropertyNames(object), 
     returnObj = {}; 

    keys.forEach(getPropertyDescriptor); 

    return returnObj; 

    function getPropertyDescriptor(key) { 
     var pd = Object.getOwnPropertyDescriptor(object, key); 
     returnObj[key] = pd; 
    } 
} 
Object.getOwnPropertyDescriptors = getOwnPropertyDescriptors; 

Live Example

轉換到這個CoffeeScript的留作練習用戶。另請注意,dup淺拷貝自己的屬性。

+0

這看起來不錯!我相信這會起作用,只是一個呃逆。我似乎得到了一個繼承自我傳入的對象的對象。這與複製確切的原型鏈略有不同。在我被欺騙之後,有沒有正確的方式來引用超級對象? – 2011-12-20 02:55:21

+0

明白了。 ''Object.getPrototypeOf(CAT)''。 – 2011-12-20 05:59:36

+0

大概重複將共享在原始對象的方法範圍內詞彙綁定的任何「本地」變量? – Alnitak 2013-07-04 15:23:24

0

您應該使用特殊的__proto__成員,該成員在每個對象中都可用,並且是指向對象類的原型的指針。以下代碼爲純javascript:

function dup(o) 
{ 
    var c = {}; 

    for (var p in o) 
    { 
     c[p] = o[p]; 
    } 
    c.__proto__ = o.__proto__; 

    return c; 
} 
+2

''__proto__''已棄用,將被刪除。 – 2011-12-20 06:00:25

相關問題