2016-08-25 13 views
0

オブジェクトをパラメータとして送信し、このオブジェクトを変数answerに保存するオプションのメソッドがあります。コードは次のとおりです。オブジェクト内にforeachを持つオブジェクトを作成する

var test = Selectable.create('img'); 
undefined 

test.options({'foo': '1', 'foo2': '0'}); 
Uncaught TypeError: Cannot set property 'foo' of undefined(…) 

問題を解決するために、私はちょうどにオブジェクトをコピーすることができます:

var Selectable = { 
    create: function(type) { 
     Object.create(this); 
     this.type = type; 
     this.id = Math.random().toString(36).replace(/[^a-z]+/g, '').substring(0, 5); 

     this.cacheDom(); 
     return this; 
    }, 
    cacheDom: function(){ 
     this.$target = $('#selectable-target'); 
     this.$id = $('#selectable-' + this.id); 
     this.$options = this.$id.find('.selectable-options'); 
     this.$revise = this.$id.find('a.revise'); 
    }, 
    options: function(values){ 
     this.answers = {}; 
     Object.keys(values).forEach(function(key) { 
      this.answers[key] = values[key]; 
     }); 
    }, 
    render: function() { 
     this.$target.append(
      $('<div>') 
      .attr('id', 'selectable-'+this.id) 
      .append(
       $('<div>') 
       .addClass('selectable-options') 
      ) 
     ) 

     this.cacheDom(); 
    } 
}; 
インスタンス化として

と回答プロパティにコンソールでオブジェクトを挿入しようと、私はこれを取得しますこのようなプロパティ:

options: function(values){ 
      this.answers = values; 
} 

なぜこれが起こっているのか、それを修正する方法を知りたいのですが。 forEachを使用しているときにカスタム引数を渡さない限り、あなたはthe documentationを見れば、エラーが

Object.keys(values).forEach(function(key) { 
    this.answers[key] = values[key]; 
}); 

である

+0

を役に立てば幸い'がグローバルウィンドウオブジェクトになります。これは、 'Selectable.create()'を呼び出すときに起こっていることです – jcbp

+0

@jcbp:いいえ 'Selectable.create()'は 'this'のために' Selectable'を使って 'create'関数を呼び出します - それはメソッド呼び出しです! – Bergi

+0

@Bergiはい、そうです。すみません、私の間違いです。 – jcbp

答えて

1

、あなたはそれを参照してくださいよ、thisは、コールバックでundefinedです。

Object.keys(values).forEach(function(key) { 
    this.answers[key] = values[key]; 
}, this); 

変化は、呼び出し元でthisの値と等しくなるように、コールバックの値thisを強制:溶液は、以下のように書き換えることです。

同等に

が、ES6だけで、あなたの代わりにthisをキャプチャfunction=>を使用することができ、およびだった少し速く(少なくとも1年前だった)私がチェックした最後の時間:の

Object.keys(values).forEach(key => { 
    this.answers[key] = values[key]; 
}); 
+1

あなたがES6を使っていたら、 'this.answers = Object.assign({}、values)' – Bergi

+0

はい、うまくいきます。 – Yoric

0

ファーストあなたはObjectとは何かを理解しなければなりません。そして、これはどのインスタンスに属していますか。次のコードでは、

1 options: function(values){ // outer function 
2  this.answers = {}; 
3  Object.keys(values).forEach(function(key) { // inner function 
4   this.answers[key] = values[key]; 
5  }); 
6 }, 

最初の 'this'(2行目) - 外部関数インスタンスにリンクされています。しかし、第二の「これ」は内的機能に結びついています。それ以上 - 'this'の誰もSelectableにリンクしていません。

このような混乱を解決するには、まずオブジェクトを関数として導入する必要があります。

var Selectable = function() { 

いくつかの変数の中に 'this'を保存してください。

var that = this; 

すべての内部機能の中に「this」の代わりに「that」を使用してください。

最後に、このように選択を使用します。

var selectable = new Selectable(); 
selectable.options({'foo':'bar'}); 

はこの `オブジェクト、関数は` new`オペレータ(または `apply`と` call`法)なしで呼び出された場合、それは

関連する問題