2016-05-28 7 views
7

を超えて私はそのために取得し、JavaScriptオブジェクトに設定学ぶことを試みている私は、私が最初のコンストラクタを使用してオブジェクトを作成して、getを使用して、設定しています。ここゲッターセッター最大コールスタックサイズはエラー

function ab(n){this.name=n;}; 
var c= new ab("abcde"); 
console.log(c); 
Object.defineProperty(c, 'name', { 
    get: function() { 
     return name; 
    }, 
    set: function(Name) { 
     this.name = Name; 
     } 
}); 
c.name="xyz"; 
console.log(c.name); 

を試してみました。しかし、私はエラー "最大呼び出しスタックサイズを超えて"を取得しています。私はこのエラーの理由を取得していません。助けてくれてありがとう

答えて

7

setterのthis.name = Nameが再びセッターを呼び出し、無限の再帰をもたらすことが既に説明されていると思います。

このaproachについてどのように:

function Ab(_name){ 
    Object.defineProperty(this, "name", { 
     //enumerable: true, //maybe? 
     get: function(){ return _name }, 
     set: function(value){ _name = value } 
    }); 
} 

var c = new Ab("abcde"); 
console.log(c, c.name); 

または原型-アプローチ
欠点:私有財産_nameなどの公共

function Ab(n){ 
    this.name = n; 
} 
Object.defineProperty(Ab.prototype, "name", { 
    get: function(){ return this._name }, 
    set: function(value){ this._name = value } 
}); 

それともES6
ほとんど同じことですプロトタイプアプローチ

class Ab{ 
    constructor(n){ 
     this.name = n; 
    } 

    get name(){ return this._name }, 
    set name(value){ this._name = value } 
} 
+0

2番目と3番目のアプローチが私の場合に最適でした。この答えをありがとう! – trickpatty

+0

これは "無限の再帰につながります"。あなたのゲッターが "戻るthis.myprop"以上のものであることを確認してください。 "return 'MyProp:' + this.myprop" – AKMorris

2

set構文は、そのプロパティを設定しようとするときに呼び出される関数にオブジェクトプロパティをバインドします。

this.name = Name; 内部設定機能はありません。 これは、スタックオーバーフローを引き起こすセッターを再帰的にトリガーします。 実際、この場合はセッターが必要ありません。 setterを使用するのは、プロパティが設定または変更されたときに余分な作業が必要な場合のみです。

More

0

あなたはObject.defineProperty()間違っを使用。この場合、初期化されていないObjectabが呼び出される必要があります。

Object.defineProperty(ab, 'name', { //.. }; 
+1

コードが正しいです。それは、セッターに変数を設定して、セッターを再び起動させることだけです。 –

1

あなたはにプロパティを追加しているオブジェクト内のバッキングフィールドと同じ(nameを)あなたの財産を命名しています。さらに、setの中のthis演算子が間違った範囲を参照しています(具体的には、オブジェクトではなくプロパティにスコープされています)。そのため、再帰的にnameプロパティを設定しているため、スタックオーバーフロー例外が発生します。次のように

あなたはあなたのコードを変更することができます。Object.defineProperty呼び出しはその関数内にあるので

function myObject(n){ 
    this.nameValue = n; 

    Object.defineProperty(this, 'name', { 
     get: function() { 
      return this.nameValue; 
     }, 
     set: function(value) { 
      this.nameValue = value; 
     } 
    }); 
} 

var c = new myObject("foo"); 
console.log(c.name);  //logs "foo" 

c.name="bar"; 
console.log(c.name);  //logs "bar" 

name財産のgetsetコンポーネントでthisキーワードは現在、myObjectという関数によって定義されたオブジェクトを参照します。

+0

コンストラクタ内にアクセサプロパティを作成するだけです。 definePropertyメソッドを使用する必要はありません。 –

関連する問題