Edited at

[JavaScript] Arrays.forEach内でthisを参照した時に陥った罠

More than 5 years have passed since last update.

お昼休みにこんにちわ。Qiita初心者なので,こんな投稿でいいのかいささかわかりかねるのですが。。。

Markdown記法の練習をかねて,一発ハマったことを投稿してみます。


やりたいこと


  • オブジェクトのインスタンス後からカスタマイズして関数を加える

  • 関数の内容: 配列を引数に取り,その各要素とカスタマイズされるオブジェクトのメンバ変数とを作用させる


コードで書くとこんな感じ


foreach_this.js


var hogeObj = {
hogeInt:10;
};

var customFunc = function(nums){
nums.forEach(function(num){
relation(num, this.hogeInt);
});
};

hogeObj.customFunc = customFunc;


relationはたとえば,function(hoge,piyo){console.log(hoge*piyo);}とかなわけですが,残念ながらこれはうまく動きませんでした。


原因

ひとえに勉強不足… たとえばGoogle JavaScriptスタイルガイドにおけるthis参照の項を見ると,


オブジェクトのコンストラクタとメソッド、クロージャの作成時にのみ使います。


と,書いてあります。こういうthis参照はやめて,うまいコト(継承とか使って解決できないか?)を考えるべきなのでしょうが,それはそれとして,,,

Arrays.forEachは引数が2つあります。


  • 1つ目は各配列の要素を引数とする関数

  • 2つ目は第一引数の関数内で参照されるthisの参照

そして第二引数を省略すると,グローバルオブジェクトが参照されるようになります。

window.hogeInt (node.jsならglobal.hogeInt)が定義されていないので,先ほどのロジックはうまく動きません。


解決方法


foreach_this_revised.js


var hogeObj = {
hogeInt:10;
};

var customFunc = function(nums){
nums.forEach(function(num){
relation(num, this.hogeInt);
}, this);
};

hogeObj.customFunc = customFunc;


こうやってあげると,とりあえずはうまく動きました!