blog

JavaScriptの thisを解明する

この記事でこのことを説明することで、この仕組みについて理解していただければと思います。プログラマーとして、これを学ぶことはあなたの開発に大いに役立ちますし、いわば利点は欠点を上回るのです。...

Mar 26, 2024 · 5 min. read
シェア

この記事では、JavaScriptにおける thisについて説明したいと思います。thisの動作メカニズムを理解する助けになれば幸いです。JavaScriptプログラマーとして、thisについて学ぶことはとても役に立ちます。この投稿は、私の最近の仕事、つまりもうすぐ完成する私の本「 Application Design」の****章に触発されて書いたもので、スコープがどのように機能するかについて書いています。スコープがどのように機能するかという側面について。

"これ "に対してあなたが感じているのは、おそらく "もっともらしい否認 "でしょう:

[]

クレイジーでしょう?この短い記事では、その謎を解き明かしたいと思います。

これ」はどのように機能するのですか?

関数がオブジェクトのメソッドとして呼び出された場合、thisはそのオブジェクトに代入されます。

var parent = { 
    method: function () { 
        console.log(this); 
    } 
}; 
  
parent.method(); 
// <- parent 

メソッドへの参照を取得してそれを呼び出すと、thisの値はもはや親ではなく、ウィンドウ・グローバル・オブジェクトになります。これはほとんどの開発者を混乱させます。

var parentless = parent.method; 
  
parentless(); 
// <- Window 

要するに、呼び出された関数がオブジェクトのプロパティなのか、それ自身なのかを理解するために、呼び出しの連鎖を見る必要があるということです。プロパティとして呼び出された場合、thisの値はそのプロパティのオブジェクトになり、そうでなければ thisの値はグローバルオブジェクトまたはウィンドウに代入されます。の値は未定義になります。

コンストラクタとして扱われる場合、newキーワードが使われると、生成されるインスタンス・オブジェクトに thisが代入されます。

function ThisClownCar () { 
  console.log(this); 
} 
  
new ThisClownCar(); 
// <- ThisClownCar {} 

この場合、関数をコンストラクタとして使うかどうかを判断する方法がないため、newキーワードを省略すると、上のように親の呼び出しがない thisがグローバルオブジェクトになることに注意してください。

ThisClownCar(); 
// <- Window 

this」を変更。

.callメソッド、.applyメソッド、.bindメソッドは、関数の呼び出し方法を操作するために使用され、thisの値や関数に渡される引数の値を定義するのに役立ちます。

Function.prototype.callは任意の数の引数を持つことができ、***1つは thisに代入され、残りは呼び出し関数に渡されます。

Array.prototype.slice.call([1, 2, 3], 1, 2) 
// <- [2] 

Function.prototype.applyは.callのような動作をしますが、任意の引数の代わりに引数の配列を関数に渡します。

String.prototype.split.apply('', ['.']) 
// <- ['13', '12', '02'] 

Function.prototype.bindは、.bindに渡された引数を常に thisの値として使用する特別な関数を作成します。また、部分的な引数を割り当てる機能もあり、元の関数のCoriolisバージョンを作成します。

var arr = [1, 2]; 
var add = Array.prototype.push.bind(arr, 3); 
  
// effectively the same as arr.push(3) 
add(); 
  
// effectively the same as arr.push(3, 4) 
add(4); 
  
console.log(arr); 
// <- [1, 2, 3, 3, 4] 

スコープチェーン内の this

次の例では、this はスコープチェインで変更されません。これはルールの欠陥であり、素人の開発者をしばしば混乱させます。

function scoping () { 
  console.log(this); 
  
  return function () { 
    console.log(this); 
  }; 
} 
  
scoping()(); 
// <- Window 
// <- Window 

this "への参照を保持するローカル変数を作成する一般的な方法があり、子スコープに同じ名前の変数を持つことはできません。子スコープの同名の変数は、親スコープの this への参照を上書きします。

function retaining () { 
  var self = this; 
  
  return function () { 
    console.log(self); 
  }; 
} 
  
retaining()(); 
// <- Window 

親スコープの thisと、現在の thisの値の両方をどうしても使いたいのでなければ、不可解な理由ですが、私はmethod.bind関数を使うことを好みます。これを使えば、親スコープの this を子スコープに代入することができます。

function bound () { 
  return function () { 
    console.log(this); 
  }.bind(this); 
} 
  
bound()(); 
// <- Window 

他に質問は?

これ」について何か質問はありますか?これ」についてはどうですか?もし私が他の境界ケースやエレガントな解決策を見逃していると思われるなら、ぜひ教えてください!

この投稿を楽しんでいただけたなら、私の近刊『JavaScript Application Design| アプリケーションデザイン』をぜひチェックしてください。

Read next

ファーウェイITが人事・社会保障情報システムをサポートする

日本の人口は約14億人。住民一人ひとりにとって、社会保障制度は衣食住や交通に関わる最も重要な生活保護制度の一つです。\n\n人材・社会保障機関は、社会経営や社会保障制度の中心的役割を担い、雇用の促進、安定した労使関係の維持、社会保障制度の充実を図っています。

Mar 24, 2024 · 2 min read