this指向、call、apply、bind

思考下面這幾種情況下輸出的結(jié)果,來理解this的指向問題

var name = 'windowName'
function a(){
    var name = 'zhangsan'
    console.log(this.name)
}
a()

解釋:
this 指向的是調(diào)用他的對象,上面的 a() 是沒有調(diào)用者的,所以 this 指向的是默認的 window,var name = 'windowName' 就是先把 name 屬性掛到 window 上,然后再賦值為 windowName

var name = 'windowName'
var a = {
    name: 'zhangsan',
    fn: function(){
        console.log(this.name)
    }
}
a.fn()

解釋:
fn() 的調(diào)用者是 a ,所以 this 指向 a ,this.name 也就是 a.name

var name = 'windowName'
var a = {
    name: 'zhangsan',
    fn: function(){
        console.log(this.name)
    }
}
var f = a.fn
f()

解釋:
fn() 沒有調(diào)用者,所以 this 指向的是默認的 window ,所以打印的是 windowName

var name = 'windowName'
function fn(){
    var name = 'zhangsan'
    innerFun()
    function innerFun(){
        console.log(this.name)
    }
}
fn()

解析:
同理,fn() 并沒有調(diào)用者,所以 this 指向的還是 window

var name = 'windowName'
var a = {
    name: 'zhangsan',
    func1: function(){
        console.log(this.name)
    },
    func2: function(){
        setTimeout(function(){
            this.func1()
        },100)
    }
}
a.func2()

解析:
在這里,setTimeout 中的 this 沒有調(diào)用者,所以指向的是 window ,所以結(jié)果是 undefined

那如何才能使這里的 setTimeout 中的這個 this 指向 a 對象呢?

  1. 可以使用箭頭函數(shù)
setTimeout(() => {
  this.func1()
},100)
  1. 可以用一個變量存儲指針
var that = this
setTimeout(function(){
  that.func1()
},100)
  1. 使用 函數(shù).call(作用域?qū)ο?
setTimeout(function(){
  this.func1()
}.call(a),100)
  1. 使用函數(shù).apply(作用域?qū)ο?
setTimeout(function(){
  this.func1()
}.apply(a),100)

可以看到 callapply 都可以改變 this 的指向,但是他們有什么區(qū)別呢?

var a = {
    name: 'zhangsan',
    fn: function(a,b){
        console.log(a + b)
    }
}
var b = a.fn
// 多個參數(shù)是用數(shù)組的形式傳遞
b.apply(a, [1,2])
// 多個參數(shù)直接在后面追加傳遞
a.call(a,1,2)
  1. 使用 bind 綁定作用域,但不立即執(zhí)行,需要手動再執(zhí)行
setTimeout(function(){
  this.func1()
}.bind(a)(),100)

call的實現(xiàn)原理

Function.prototype.mycall = function(ctx){
    ctx = ctx || window
    ctx.fn =  this // 這個this就是調(diào)用者對象
    let arg = [...arguments].slice(1)
    let result = ctx.fn(...arg)
    return result
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容