この
https://juejin.im/post/6844903496253177863
これのポイント
これは常に最後に呼び出したオブジェクトを指します
例1:
var name = "windowsName"
function a() {
var name = "Cherry"
console.log(this.name) // windowsName
console.log("inner:" + this) // inner:Window
}
a()
console.log("outer:" + this) // outer:Window
aが最後に呼び出された場所()では、以前に呼び出されなかったオブジェクトはグローバルオブジェクトウィンドウであり、これはwindow.a()と同等です。(strictモードを使用する場合、グローバルオブジェクトは未定義であり、エラーが報告されます)
例2:
var name = "windowsName"
var a = {
name:"Cherry",
fn:function() {
console.log(this.name) // Cherry
}
}
a.fn()
関数fnはオブジェクトaによって呼び出されるため、出力される値はaのnameの値です。
例3:
var name = "windowsName"
var a = {
name:"Cherry",
fn:function() {
console.log(this.name) // Cherry
}
}
window.a.fn()
ここにチェリーが印刷されているのは、「これは常に最後に呼び出したオブジェクトを指している」からでもあります。最後に彼を呼び出したオブジェクトはまだオブジェクトaです
例4
var name = "windowsName"
var a = {
// name:"Cherry",
fn:function() {
console.log(this.name) // undefined
}
}
window.a.fn()
呼び出しfnはaオブジェクトです。つまり、fnの内部thisはオブジェクトaであり、名前はオブジェクトaで定義されていません。aに名前属性がない場合でも、次のオブジェクトに対してthis.nameの検索は続行されません。代わりに、undefinedを直接出力します。
例5
var name = "windowsName"
var a = {
name:null,
fn:function() {
console.log(this.name) // windowsName
}
}
var f = a.fn
fn()
aオブジェクトのfnメソッドは変数fに割り当てられますが、呼び出されないため、fn()はウィンドウから呼び出されます。つまり、これのポイントはウィンドウです。
例5
var name = "windowsName"
var a = {
var name = 'Cherry'
innerFunction()
function innerFunction() {
console.log(this.name) // windowsName
}
}
fn()
この点を変える
- es6矢印関数を使用する
- 関数内で_this = thisを使用します
- 適用、呼び出し、バインドを使用する
- インスタンス化された新しいオブジェクト
例7:
var name = "windowsName"
var a = {
name:"Cherry"
func1:function() {
console.log(this.name)
}
func2:function() {
setTimeout( function() {
this.func1()
},100)
}
}
a.func2() // this.func1 is not a function
アロー関数を使用しない場合、setTimeoutを呼び出す最後のオブジェクトはウィンドウですが、ウィンドウにfunc1関数がないため、エラーが報告されます。
アロー機能
矢印関数のthisは、関数が実行されたときではなく、関数が定義されたときのthisを常に指します。矢印関数にはこのバインディングはなく、その値はスコープチェーンを検索して決定する必要があります。矢印関数が非矢印関数に含まれている場合、これは最も近い非矢印関数のthisにバインドされます。それ以外の場合、これは未定義です
例8:
var name = "windowsName"
var a = {
name:"Cherry"
func1:function() {
console.log(this.name)
}
func2:function() {
setTimeout( () => {
this.func1()
},100)
}
}
a.func2() // Cherry
関数内で_this = thisを使用します
最初にこの関数を呼び出すオブジェクトを変数_thisに保存し、次にこの関数で_thisを使用して、_thisが変更されないようにします
例9:
var name = "windowsName"
var a = {
name:"Cherry"
func1:function() {
console.log(this.name)
}
func2:function() {
var _this = this
setTimeout( function() {
_this.func1()
},100)
}
}
a.func2() // Cherry
最初に_this = thisをfunc2に設定します。これはfunc2を呼び出すオブジェクトaです。func2のsetTimeoutがウィンドウから呼び出されないようにするために、これはsetTimeoutがウィンドウです。これ(変数aを指す)を変数_thisに割り当て、func2で_thisを使用するとオブジェクトaを指すようにします。
apply、call、bindの使用
例10:
// 使用apply
var a = {
name:"Cherry"
func1:function() {
console.log(this.name)
}
func2:function() {
setTimeout( function() {
this.func1()
}.apply(a),100)
}
}
a.func2() // Cherry
例 11:
// 使用call
var a = {
name:"Cherry"
func1:function() {
console.log(this.name)
}
func2:function() {
setTimeout( function() {
this.func1()
}.call(a),100)
}
}
a.func2() // Cherry
例 12:
// 使用bind
var a = {
name:"Cherry"
func1:function() {
console.log(this.name)
}
func2:function() {
setTimeout( function() {
this.func1()
}.bind(a),100)
}
}
a.func2() // Cherry
適用と呼び出しの違い
基本的にパラメーターの受け渡しと同様に、さまざまな呼び出しメソッドはいくつかのパラメーターリストを受け取りますが、applyは複数のパラメーターを含む配列を受け入れます
例 13:
var a = {
name:"Cherry"
fn:function(a,b){
console.log(a+b)
}
}
var b = a.fn
b.apply(a,[1,2]) // 3
例 14:
var a = {
name:"Cherry"
fn:function(a,b){
console.log(a+b)
}
}
var b = a.fn
b.call(a,1,2) // 3
バインドと適用および呼び出しの違い
bind()メソッドは、新しい関数を作成し、呼び出されると、thisキーワードを指定された値に設定し、新しい関数を呼び出すときに、指定されたパラメーターのシーケンスを指定前に提供します。したがって、バインドは新しい関数を作成することであり、手動で呼び出す必要があります。
var a = {
name:"Cherry"
fn:function(a,b){
console.log(a+b)
}
}
var b = a.fn
b.bind(a,1,2)() // 3