序文
これがどのように機能するかについてはインターネット上にかなりの情報がありますが、私はいつもそれを完全に理解するのに十分な文字通り少しを持っていませんでした。
それにもかかわらず、最近、私はそう思われるように、これを行い、あなたと共有したいと思います。
多くの言葉なしで
単純な例と複雑な例の両方を取り上げますので、誰もが興味を持つでしょう。
ここで検討する主なポイントは2つあります。
(1)function(){}を介して宣言された関数の場合、これは呼び出し時に計算されます。
(2)矢印関数の場合、これは関数の作成時に定義されます。
いくつかの簡単な例から始めましょう。
function globalFunc() {
console.log(this);
}
const globalArrowFunc = () => {
// , this - window/undefined
// , use strict this === undefined
console.log(this);
}
globalFunc(); // undefined
globalArrowFunc(); // undefined
これらの関数をオブジェクトに追加するとどうなりますか?
const cat = {
name: 'Pirate',
globalFunc,
globalArrowFunc
};
cat.globalFunc(); // { name: 'Pirate', ... }
cat.globalArrowFunc(); // undefined
それを理解しましょう。
cat.globalFunc()を呼び出すと、catオブジェクトが返されました。わかりやすくするために、「これは、function(){}を介して宣言された関数を呼び出すと、ポイントの前のオブジェクトと等しくなります」と考えることができます。
では、なぜcat.globalArrowFunc()が未定義を返したのですか?事実、矢印関数のこの値は作成時に決定されており、作成したとき、この値は未定義でした。
次に、いくつかのメソッドを使用してオブジェクトを作成しましょう。
const dog = {
name: 'Viking',
//
//
localFunc: function() {
console.log(this);
},
localArrowFunc: () => {
console.log(this);
}
};
dog.localFunc(); // { name: 'Viking', ... }
dog.localArrowFunc(); // undefind
何故ですか?
dog.localFunc()-ポイントdogの前のオブジェクトのため。
dog.localArrowFunc()-オブジェクト内ではこれもグローバルオブジェクトであるため、未定義になります。
例を少し複雑にしましょう。
const dog = {
name: 'Viking',
localFunc: function() {
const arrowFuncInLocalFunc = () => {
console.log(this);
};
function funcInLocalFunc() {
console.log(this);
};
arrowFuncInLocalFunc(); // 1
funcInLocalFunc(); // 2
},
localArrowFunc: () => {
const arrowFuncInLocalArrowFunc = () => {
console.log(this);
};
function funcInLocalArrowFunc() {
console.log(this);
};
arrowFuncInLocalArrowFunc(); // 3
funcInLocalArrowFunc(); // 4
}
};
dog.localFunc();
// 1 - { name: 'Viking', ... }
// 2 - undefind
dog.localArrowFunc();
// 3 - undefind
// 4 - undefind
それを理解しましょう!
(1)arrowFuncInLocalFunc()// {name: 'Viking'、…}
なぜこれが起こっているのですか?
オブジェクトを作成したときに、localFunc関数を記述したためです。そして、前の例から覚えているように、彼女にとってこれはポイントの前のオブジェクト、つまり{name: 'Viking'、...}です。次に、arrowFuncInLocalFunc関数自体について説明します。localFuncが呼び出されるとすぐに作成され、作成場所にあったこの値を記憶しています。したがって、arrowFuncInLocalFuncが{name: 'Viking'、…}を返すことがわかります。
(2)funcInLocalFunc()// undefind
なぜこれが起こっているのですか?
前に述べたように、function(){}を介して宣言された関数の場合、この値は呼び出し時に決定され、ポイントの前のオブジェクトと等しくなります。この場合、ポイントの前にオブジェクトがありません。つまり、これはグローバルオブジェクトであるか、この場合は未定義です。
(3)arrowFuncInLocalArrowFunc()//未定義
なぜこれが起こっているのですか?
この例は(1)と非常によく似ていますが、同じarrow関数内にarrowFuncInLocalArrowFunc関数のみが作成されます。また、宣言時に矢印関数が環境からこの値に書き込むことも覚えています。ただし、この関数はlocalArrowFunc内に作成されており、これは未定義です。これは、arrowFuncInLocalArrowFuncの場合、これは未定義になることを意味します。
(4)funcInLocalArrowFunc()//未定義
なぜこれが起こっているのですか?
funcInLocalFuncの(2)とまったく同じ理由
別の例を見てみましょう。
const cat = {
name: 'Tom',
getFuncWithTomName: function() {
return () => {
console.log(this.name);
}
}
};
const mouse = {
name: 'Jerry',
logName: cat.getFuncWithTomName()
};
mouse.logName(); // Tom o_O !?
これは、getFuncWithTomNameが矢印関数を作成して返すためであり、矢印関数が作成されると、これはgetFuncWithTomNameと同じになります。また、getFuncWithTomNameの場合、これはドット(cat)の前のオブジェクトです。
合計
矢印関数のコンテキストは、作成時に決定されます。
関数(){}のコンテキストは、それらが呼び出されたときに定義され、ポイントの前のオブジェクトと同じです。