2017-01-23 19 views
0

Object.defineProperty()を使用してデータプロパティをアクセサプロパティに変換したいと考えています。私は、なぜエラー作物を理解Uncaught RangeError: Maximum call stack size exceededエラーObject.definePropertyでのgetterとsetterの使用

var c = { name: 'abcde'}; 
Object.defineProperty(c, 'name', { 
    get: function() { 
     return this.name; //causes stack overflow 
    }, 
    set: function(x) { 
     this.name = x; //causes stack overflow 
     } 
}); 
c.name="xyz"; 
console.log(c.name); 

につながり、このためのコードを考えてみましょう。提案された解決策の 一つはゲッターとセッターから「この」を削除することであり、動作しているようです。

var c = { name: 'abcde'}; 
Object.defineProperty(c, 'name', { 
    get: function() { 
     return name; //removed this 
    }, 
    set: function(x) { 
     name = x; //removed this 
     } 
}); 
c.name="xyz"; 
console.log(c.name); 

何が起こっているか一般的に、Object.defineProperty()を使用してデータプロパティをアクセサープロパティに変換する方法を尋ねたいと思いますか?それは代わりにオブジェクトcに格納する値を格納するnameと呼ばグローバル変数を使用するため

答えて

1

第二コードが実際機能しません。

window.nameがブラウザのグローバルオブジェクトのデフォルトプロパティでない場合、ES5の "strict mode"によって拒否されます。

より適切な修正はレキシカルスコーププライベート変数に値を保存するために、次のようになります。

var c = (function() { 
    var obj = {}; 
    var name = "abcde"; 

    Object.defineProperty(obj, "name", { 
     get: function() { 
      return name; 
     }, 
     set: function(x) { 
      name = x; 
     } 
    }); 

    return obj; 
})(); 
+0

素晴らしいソリューション。しかし、ここで 'name'のようなデータプロパティをここでアクセサプロパティに変換する方法はありますか?ここでは名前を閉鎖しています。私は最初にデータプロパティとしてそれをしたい。 –

+1

@BreakingBenjamin AFAIK、唯一の他の方法は、実際のプロパティをシャドーしてから、実際のプロパティを「プライベート」とマークするための命名規則(例:先頭のアンダースコア)を使用することです。実際の値を格納するのに '._name'を使うことができますが、' .name'を使ってアクセスします。 – Alnitak

関連する問題