これは質問を指します
1. 通常の機能
1.1 通常の非匿名関数:関数またはメソッドを呼び出す人は誰でも、この関数またはオブジェクトの this は誰を指しますか
let getThis = function () {
console.log(this);
}
let obj={
name:"Jack",
getThis:function(){
console.log(this);
}
}
//getThis()方法是由window在全局作用域中调用的,所以this指向调用该方法的对象,即window
getThis();//window
//此处的getThis()方法是obj这个对象调用的,所以this指向obj
obj.getThis();//obj
1.2 通常の匿名関数:匿名関数の実行はグローバルであるため、匿名関数内の this は匿名関数を呼び出すオブジェクトではなくウィンドウを指します。
let obj = {
getThis: function () {
return function () {
console.log(this);
}
}
}
obj.getThis()(); //window
上記のコードでは、obj によって getThi() メソッドが呼び出されていますが、obj.getThis() は匿名関数を返し、匿名関数内の this は window をポイントしているため、window が出力されます。上記のコードでメソッドを呼び出すオブジェクトをこのポイントにしたい場合は、事前にこの値を別の変数 (_this または that) に渡すことができます。
let obj = {
getThis: function () {
//提前保存this指向
let _this=this
return function () {
console.log(_this);
}
}
}
obj.getThis()(); //obj
2. アロー関数
- アロー関数の this は、関数が呼び出されたときではなく、関数が定義されたときに決定されます。
- アロー関数の this は、親スコープの実行コンテキストを指します。(ヒント: JavaScript では、グローバル スコープを除き、他のスコープは関数によって作成されるため、この方向を決定したい場合は、最も近いものを見つけてください。アロー関数関数、関数と同じレベルの実行コンテキスト内の this はアロー関数内の this です)
- this の値は関数の定義時に決定されるため、アロー関数は apply、call、および binding メソッドを使用して this の方向を変更することはできません。
2.1 最も近い関数を見つける:まず、アロー関数に最も近い関数は getThis(){} で、この関数と並行する実行コンテキストは obj の実行コンテキストです。アロー関数の this は、コメントされたコードの this です。 、それはobjです。
let obj = {
//此处的this即是箭头函数中的this
getThis: function () {
return ()=> {
console.log(this);
}
}
}
obj.getThis()(); //obj
2.2 関数が見つかりません:このコードには 2 つのアロー関数がありますが、対応する function(){} が見つからないため、関数が window を指すまで検索を続けます。
//代码中有两个箭头函数,由于找不到对应的function,所以this会指向window对象。
let obj = {
getThis: ()=> {
return ()=> {
console.log(this);
}
}
}
obj.getThis()(); //window
呼び出し、適用、バインド
効果:
どちらも関数内の this ポインターを変更できます。
違い:
- call と apply は関数をすぐに呼び出し、関数の内部の this ポイントを変更します。
- call と apply で渡されるパラメータは異なります。call ではパラメータ arg1、arg2... 形式で渡されます。apply は配列 [arg] の形式である必要があります。
- bind は関数をすぐには呼びませんが、関数の内部の this ポイントを変更し、arg1、arg2... の形式でパラメータを渡すことができます。
主なアプリケーションシナリオ:
- call は多くの場合継承を行います。
- apply は、数学的オブジェクトを使用して配列の最大値と最小値を実現するなど、配列に関連することがよくあります。
- bind は関数を呼び出しませんが、タイマー内の this ポイントを変更するなど、this ポイントを変更したいと考えています。
call メソッド:
関数の内部の this ポイントを変更します。call() メソッドはオブジェクトを呼び出します。これは単に関数を呼び出す方法として理解されます。関数の this ポイントを変更できます。
書き方: fun.call(thisArg, arg1, arg3, …), thisArgはポイントしたいオブジェクト、arg1, arg3はパラメータ
callのmain関数は継承も実現可能
function Person(uname, age) {
this.uname = uname;
this.age = age;
}
function Son(uname, age) {
Person.call(this, uname, age);
}
var son = new Son("zhang", 12);
console.log(son);
apply メソッド:
apply() メソッドは関数を呼び出します。これは単に関数を呼び出す方法として理解され、関数のこの点を変更できます。
記述方法:fun.apply(thisArg, [argsArray])、thisArg:fun関数実行時に指定したthisの値、argsArray:渡された値は配列に含まれる必要があり、戻り値は関数の戻り値これは呼び出し関数であるためです。
apply の主な用途。たとえば、apply を使用して配列内の最大値を見つけることができます。
const arr = [1, 22, 3, 44, 5, 66, 7, 88, 9];
const max = Math.max.apply(Math, arr);
console.log(max);
bind メソッド:
bind() メソッドは関数をすぐには呼びませんが、関数の内部の this ポイントを変更できます。
書き込みメソッド: fun.bind(thisArg, arg1, arg2, ...), thisArg: 指定された this の値fun 関数の実行時、 arg1、arg2 : 渡されるその他のパラメーター。
指定されたこの値と初期化パラメータによって変更された元の関数のコピーを返します。
var o = {
name: "lisa"
};
function fn() {
console.log(this);
}
var f = fn.bind(o);
f();
バインドアプリケーション
すぐに呼び出す必要はないが、この関数のこの点を変更する必要がある関数がある場合は、タイマーの使用など、この時点でバインドを使用する方が適切です。
const btns = document.querySelectorAll("button");
for (let i = 0; i < btns.length; i++) {
btns[i].onclick = function() {
this.disabled = true;
setTimeout(
function() {
this.disabled = false;
}.bind(this),
2000
);
};
}