2016-11-11 15 views
0

printDataを呼び出すと、以下のクラスがあります。this.collectionは未定義です。javascriptのプロトタイプからオブジェクトのプロパティにアクセスするには?

printData()内のプロトタイプからthis.collectionにアクセスするにはどうすればよいですか?または、私はクラスの構造を変更する必要がありますか?実際には、オブジェクトは、internが階層構造でオブジェクトを返す関数を返します。

ありがとうございます!

サンプルクラス:

var DbProvider = (function() { 
    function DbProvider(db) { 
     var that = this; // create a reference to "this" object 
     that.collection = db; 
    } 
    DbProvider.prototype.create = function() { 
     return { 
      action: function() { 
       var y = { 
        printData: function() { 
         alert('Hello ' + this.collection.Name); 
        } 
       }; 
       return y; 
      } 
     }; 
    }; 
    return DbProvider; 
})(); 

使用法:ES5構文とコール構造を維持

var a = new DbProvider({ "Name": "John" }); 
a.create().action().printData(); 
+0

thatを使用することができますか? – MayorMonty

+0

あなたのコードでは、 'that'というラベルの' this'への参照を作成します。代わりに 'that'を使用することができますか(意図していません) – MayorMonty

+0

そのオブジェクトにアクセスできません。また、ES5でプレーンなjavascriptで作成することも可能ですか? –

答えて

1

のように、正確にこのポインタを追跡する必要があります

それとも、少しリファクタリングとDbProviderの外側のスコープにthatを移動し、ES6クラスを使用することも可能であるprintData

var DbProvider = (function() { 
 
    var that; 
 
    function DbProvider(db) { 
 
     that = this; // create a reference to "this" object 
 
     that.collection = db; 
 
    } 
 
    DbProvider.prototype.create = function() { 
 
     return { 
 
      action: function() { 
 
       var y = { 
 
        printData: function() { 
 
         alert('Hello ' + that.collection.Name); 
 
        } 
 
       }; 
 
       return y; 
 
      } 
 
     }; 
 
    }; 
 
    return DbProvider; 
 
})(); 
 

 
var a = new DbProvider({ "Name": "John" }); 
 
a.create().action().printData();

1

は、溶液は次のようになります。確かに

var DbProvider = (function() { 
    function DbProvider(db) { 
     var that = this; // create a reference to "this" object 
     that.collection = db; 
    } 
    DbProvider.prototype.create = function() { 
     var that = this; 
     return { 
      action: function() { 
       var y = { 
        printData: function() { 
         console.log('Hello ' + that.collection.Name); 
        } 
       }; 
       return y; 
      } 
     }; 
    }; 
    return DbProvider; 
})(); 

エレガントではないが、それは動作します:)

構造体を変更したくない場合は、関数をarrow functionsに変更するとこの動作が得られます。

var DbProvider = (function() { 
    function DbProvider(db) { 
     var that = this; // create a reference to "this" object 
     that.collection = db; 
    } 
    DbProvider.prototype.create = function() { 
     return { 
      action:() => { 
       var y = { 
        printData:() => { 
         alert('Hello ' + this.collection.Name); 
        } 
       }; 
       return y; 
      } 
     }; 
    }; 
    return DbProvider; 
})(); 

この「クラス」を作成する方法は間違いなく非標準です。あなたがそれをより良く構造化する方法の例を望むかどうか私に教えてください。

+0

お返事ありがとうございます。しかし、私はES5ソリューションを探していますか? ES5で達成することは可能ですか?また、最終的な呼び出し元の部分(つまり、dbProvider.create()。action()。printData();を変更せずにクラスを再構築できるかどうかを教えてください。 –

1

は、ちょうどあなたがthis参照を保存してprintData機能

var DbProvider = (function() { 
 
    function DbProvider(db) { 
 
     var that = this; // create a reference to "this" object 
 
     that.collection = db; 
 
    } 
 
    DbProvider.prototype.create = function() { 
 
     var self = this; 
 
     return { 
 
      action: function() { 
 
       var y = { 
 
        printData: function() { 
 
         alert('Hello ' + this.collection.Name); 
 
        }.bind(self) 
 
       }; 
 
       return y; 
 
      } 
 
     }; 
 
    }; 
 
    return DbProvider; 
 
})(); 
 

 
var a = new DbProvider({ "Name": "John" }); 
 
a.create().action().printData();
にバインドすることができ、この

var DbProvider = (function() { 
 
    function DbProvider(db) { 
 
    this.collection = db; 
 
    } 
 
    DbProvider.prototype.create = function() { 
 
    var self = this; 
 
    return { 
 
     action: function() { 
 
     var y = { 
 
      printData: function() { 
 
      alert('Hello ' + self.collection.Name); 
 
      } 
 
     }; 
 
     return y; 
 
     } 
 
    }; 
 
    }; 
 
    return DbProvider; 
 
})(); 
 

 

 

 
let dbProvider = new DbProvider({ 
 
    Name: "test" 
 
}); 
 
dbProvider.create().action().printData();

+0

ご回答いただきありがとうございます。しかし、私はES5ソリューションを探していますか? ES5/simple javascriptで実現することは可能ですか? - –

+0

が更新されました - no es6 class – skav

関連する問題