面試官:聊聊 this 指向問題

this- 函數(shù)作用域的情況下,才會(huì)有
this綁定問題 - 或者
class類 - 使用
call,apply, bind
- 嚴(yán)格模式 "use strict"
- 非嚴(yán)格模式
this 指向問題- 普通函數(shù),
this指向undefined,不使用call,bing,apply改變其this指向的情況下
console.log("window===>",this)?//?Window?對(duì)象
function?foo()?{
????function?bar()?{
????????console.log("bar?===>",this)?//?undefined
????}
????console.log("foo",?this)?//?undefined
????return?bar
}
var?bar?=?foo();
bar()
var?a?=?()?=>?{
????console.log("a===>",?this)?//?window?對(duì)象
????var?b?=?()?=>?{console.log("b===>",?this)}
????b()?//?window?對(duì)象
????function?c()?{console.log("c===>",?this)}
????c()?//?undefined
}
a()
- 箭頭函數(shù):在不使用
call,apply,bind改變this情況下,this指向 window
"use?strict";
var?a?=?()?=>?{
????console.log("a===>",?this)?//?window?對(duì)象
????var?b?=?()?=>?{console.log("b===>",?this)}
????b()?//?window?對(duì)象
????function?c()?{console.log("c===>",?this)}
????c()?//?undefined
}
a()
非嚴(yán)格模式下- 普通函數(shù),
this指向window,不使用call,bing,apply改變其this指向的情況下
function?foo()?{
????function?bar()?{
????????console.log("bar?===>",this)?//?window
????}
????console.log("foo",?this)?//?window
????bar()
}
foo();
- 箭頭函數(shù):在不使用
call,apply,bind改變this情況下,this指向 window
var?a?=?()?=>?{
????console.log("a===>",?this)?//?window
????var?b?=?()?=>?{console.log("b===>",?this)}
????b()?//?window
????function?c()?{console.log("c===>",?this)}
????c()?//?window
}
a()
非嚴(yán)格模式下,this 指向問題在一個(gè) obj 中定義一個(gè)函數(shù):
var?a?=?"Ken"
var?obj?=?{
????a:?"小仙女",
????fn:?function()?{console.log("fn===>",?this.a)}
}
obj.fn()?//?"小仙女"?//?此時(shí)?this?指向?obj
//?變體?1
var?fn?=?obj.fn?
fn()?//?"Ken"?此時(shí)?this?指向?window
//?變體?2
var?a?=?"Ken"
var?obj?=?{
????a:?"小仙女",
????fn:?()?=>?{console.log("fn===>",?this.a)}
}
obj.fn()?//?"Ken"?this?指向?window
var?fn?=?obj.fn
fn()?//?“Ken”?this?指向?window
//?變體?3
var?a?=?"Ken"
var?obj?=?{
????a:?"小仙女",
????b:?{
????????a:?"===>obj.b",
????????fn:?function()?{console.log("obj.b===>",?this.a)}
????}
}
obj.b.fn()?//?"===>obj.b"?this?指向?obj.b
var?fn?=?obj.b.fn
fn()?//?Ken?this?指向?window
//?變體?4
var?a?=?"Ken"
var?obj?=?{
????a:?"小仙女",
????b:?{
????????a:?"===>obj.b",
????????fn:?()?=>?{console.log("obj.b===>",?this.a)}
????}
}
obj.b.fn()?//?"Ken"?this?指向?window
var?fn?=?obj.b.fn
fn()?//?"Ken"?this?指向?window
在嚴(yán)格模式下:"use?strict";
var?a?=?"Ken"
var?obj?=?{
????a:?"小仙女",
????fn:?function()?{console.log("fn===>",?this.a)}
}
obj.fn()?//?"小仙女"?//?此時(shí)?this?指向?obj
//?變體?1
var?fn?=?obj.fn?
fn()?//?Uncaught?TypeError:?Cannot?read?property?'a'?of?undefined
//?變體?2
"use?strict";
var?a?=?"Ken"
var?obj?=?{
????a:?"小仙女",
????fn:?()?=>?{console.log("fn===>",?this.a)}
}
obj.fn()?//?“Ken”?this?指向?window
var?fn?=?obj.fn
fn()?//?"Ken"?this?指向?window
//?變體?4
????????"use?strict";
var?a?=?"Ken"
var?obj?=?{
????a:?"小仙女",
????b:?{
????????a:?"===>obj.b",
????????fn:?()?=>?{console.log("obj.b===>",?this.a)}
????}
}
obj.b.fn()?//?"Ken"?this?指向?window
var?fn?=?obj.b.fn
fn()?//?"Ken"?this?指向?window
從上面的觀察,以及實(shí)踐,我們或許可以得出一個(gè)結(jié)論:
箭頭函數(shù)
this指向問題跟作用域有關(guān)系,他會(huì)沿著作用域鏈一層層往外找,最先找到那個(gè)具有作用域,就將this綁定在那個(gè)作用域上,如果找不到,就直接綁定在全局作用域上普通函數(shù)的
this指向,取決于在那個(gè)對(duì)象上執(zhí)行,this 就執(zhí)行誰(shuí)
發(fā)現(xiàn)個(gè)小問題,貌似 箭頭函數(shù)無(wú)法在執(zhí)行階段改變 this 指向問題
var?a?=?"Ken"
var?obj?=?{
????a:?"小仙女",
????b:?{
????????a:?"===>obj.b",
????????fn:?()?=>?{console.log("obj.b===>",?this.a)}
????}
}
obj.b.fn()?//?"Ken"?this?指向?window
var?fn?=?obj.b.fn
fn.call(obj)?//?"Ken"?this?指向?window
fn.apply(obj)?//?"Ken"?this?指向?window
fn.bind(obj)()?//?"Ken"?this?指向?window
非箭頭函數(shù)情況:
var?a?=?"Ken"
var?obj?=?{
????a:?"小仙女",
????b:?{
????????a:?"===>obj.b",
????????fn:?function()?{console.log("obj.b===>",?this.a)}
????}
}
obj.b.fn()?//?"====>obj.b"?this?指向?obj.b
var?fn?=?obj.b.fn
fn.call(obj)?//?this?指向?obj?//?"小仙女"
fn.apply(obj)?//?this?指向?obj?//?"小仙女"
fn.bind(obj)()?//?this?指向?obj?//?"小仙女"
class 類class?Person?{
????constructor(name)?{
????????this.name?=?name
????????console.log("Person===>",?this)?//?this?指向?qū)嵗龑?duì)象
????}
}
var?p?=?new?Person("小仙女")
評(píng)論
圖片
表情
