第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()