2017-11-07 8 views
3

オブジェクトとそのメソッドをコピーする必要があります。 したがって、私はオブジェクトを文字列化し、それを解析し、元のオブジェクトからメソッドを追加します(ただし、この新しいコピーにバインドされます)。コピーしたオブジェクトの参照に関する問題

// Taken from: https://stackoverflow.com/questions/31054910/get-functions-methods-of-a-class 
function getAllMethods(obj) { 
    let props = []; 

    do { 
     const l = Object.getOwnPropertyNames(obj) 
     .concat(Object.getOwnPropertySymbols(obj).map(s => s.toString())) 
     .sort() 
     .filter((p, i, arr) => 
       typeof obj[p] === 'function' && //only the methods 
       p !== 'constructor' &&   //not the constructor 
       (i == 0 || p !== arr[i - 1]) && //not overriding in this prototype 
       props.indexOf(p) === -1   //not overridden in a child 
       ) 
     props = props.concat(l) 
    } 
    while (
     (obj = Object.getPrototypeOf(obj)) && //walk-up the prototype chain 
     Object.getPrototypeOf(obj)    //not the the Object prototype methods (hasOwnProperty, etc...) 
    ) 

     return props; 
} 

function copyObject(obj) { 
    var copy = JSON.parse(JSON.stringify(obj)); 

    // Copy all methods 
    getAllMethods(obj) 
     .filter(prop => typeof obj[prop] === 'function') 
     .forEach(prop => copy[prop] = obj[prop].bind(copy)); 

    return copy; 
} 

そして、ここでいくつかのテスト:私は期待通り

var foo = { bar:2, f: function() { this.bar = 5 } } 
var bar = copyObject(foo); 
var baz = copyObject(bar); 

bar.f(); 
bar.bar; // 5 

baz.f(); 
baz.bar; // 2 instead of 5..?! 
baz.f.apply(baz); // not working either, baz.bar still 2 

はなぜコピーのコピーは動作しませんか?


EDIT:baz.fthis参照は、何らかの理由でまだbarにバインドされています。

+0

あなたは 'Object.assign()'だけを使っているわけではないのですか? – Barmar

+0

@Barmar通常の割り当てよりも 'Object.assign()'を使用するメリットはありますか? – HyperZ

+0

通常の割り当てはコピーを作成しません。 – Barmar

答えて

5

.bind()thisの値が1回しか機能できないため、機能しません。 this値は、基本的には石であなたがbind()を初めて使用するときに設定され、その後、あなただけの、既に結合機能の上に「別の層を塗る」している:

また

function myFunc() { 
 
    console.log(this.a); 
 
} 
 

 
var f1 = myFunc.bind({ 
 
    a: 5 
 
}); 
 
var f2 = f1.bind({ 
 
    a: 6 
 
}); 
 

 
f1(); 
 
f2();

あなたはすべての矢印の機能にthisを再バインドすることができない点に注意してください。

var a = 2; 
 

 
var myFunc =() => { 
 
    console.log(this.a); 
 
} 
 

 
var f1 = myFunc.bind({ 
 
    a: 5 
 
}); 
 
var f2 = f1.bind({ 
 
    a: 6 
 
}); 
 

 
f1(); 
 
f2();

+1

解決策は、 'copyObject()'で '.bind()'を呼び出さないことです。 – Barmar

+0

@Barmarええ、あなたが任意のオブジェクトとそのメソッドをコピーするのであれば、 '.bind()'に依存せず、 'this'メソッドが正しく動作することを信じなければなりませんオブジェクト間でコピーされます(もちろんそうではありません)。 – JLRishe

+0

さて、この明確化のおかげで!今のところ意味があります:-) – HyperZ

関連する問題