簡述this(2):常見面試題分析

第1題

var name = "222"

var a = {
    name: "111",
    say: function () {
        console.log(this.name)
    }
}

a.say()

say函數(shù)在執(zhí)行時是被對象a所調用的,所以this指向對象a
因此最后輸出 111

第2題

var name = "222"

var a = {
    name: "111",
    say: function () {
        console.log(this.name)
    }
}

var fun = a.say
fun()

fun拿到了a.say這個函數(shù)的引用,當我們在全局環(huán)境中執(zhí)行fun()時(并沒有被誰調用)
就相當于在全局環(huán)境執(zhí)行: function() { console.log(this.name) }
所以執(zhí)行時this指向window,因此最終輸出 222

第3題

var name = "222"

var a = {
    name: "111",
    say: function () {
        console.log(this.name)
    }
}

var b = {
    name: "333",
    say: function(fun){
        fun()
    }
}

b.say(a.say)

把a.say當作參數(shù)傳入b.say當中,相當于如下寫法:

var name = "222"
var b = {
    name: "333",
    say: function(){
        
        function s(){
            console.log(this.name)
        }
        s()
    }
}

需要注意的是,在b.say函數(shù)中,this確實指向的是對象b
但是函數(shù)s在執(zhí)行的時候并沒有被誰調用(前面沒有任何修飾符)
因此s在執(zhí)行的時候 內部的this指向window,最終輸出 222

第4題

var name = "222"

var a = {
    name: "111",
    say: function () {
        console.log(this.name)
    }
}

var b = {
    name: "333",
    say: function(fun){
        fun.call(b)
    }
}

b.say(a.say)

使用call來執(zhí)行函數(shù)fun,導致fun內部的this指向了b
因此,最終輸出333

第5題

var age = 26
var userInfo = {
  age:13,
  updateInfo:function(){
  
      setTimeout(function() {
        this.age = 39
        console.log(userInfo.age)
      },100)
      
  }
}

userInfo.updateInfo()

我們的初衷是:在upadateInfo執(zhí)行的100ms之后,修改userInfo.age的值
然而最終輸出的仍然是13(也就是說,userInfo.age并沒有被修改)

那么,this.age = 39到底修改的是誰的age呢?
答案是window
因為setTimeout是異步任務,它會等到同步任務結束后 再在全局環(huán)境中執(zhí)行
這個時候的this,無疑指向了window

那么應該如何修改呢?
方法一:利用let創(chuàng)建塊級作用域

var age = 26
var userInfo = {
  age:13,
  updateInfo:function(){
      let self = this
      setTimeout(function() {
        self.age = 39
        console.log(userInfo.age)
      },100)
      
  }
}

userInfo.updateInfo()

我們用self來緩存指向對象userInfo的this
當我們執(zhí)行userInfo.updateInfo( )的第0ms時,setTimeout的回調函數(shù)被聲明
此時它的作用域鏈為:updateInfo對應的活動對象{self} --> 全局對象{age=26, userInfo}
100ms之后,回調函數(shù)被執(zhí)行,此時它的作用域鏈為:
自身對應的活動對象{ } --> updateInfo對應的活動對象{self} --> 全局對象{age=26, userInfo}

這個寫法就不需要考慮this的綁定規(guī)則了,因為沒有出現(xiàn)過this.xxx

方法二:箭頭函數(shù)

var age = 26
let userInfo = {
  age:13,
  updateInfo:function(){
  
      setTimeout(() => {
        this.age = 39
        console.log(userInfo.age)
      },100)
    
    
  }
}
userInfo.updateInfo()
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容