函数中的this
可以自己做一遍,先不看答案,做完再和答案对照一下看看解析。
题目1.
function f1() {
console.log(this)
}
function f2() {
'use strict'
console.log(this)
}
f1()
f2()
答案是:
window
undefined
函数在浏览器全局环境中被简单调用,非严格模式下 this 指向window;在 use strict 指明严格模式的情况下就是 undefined
题目2.
const foo = {
bar: 10,
fn: function() {
console.log(this)
console.log(this.bar)
}
}
var fn1 = foo.fn
fn1()
答案是:
window
undefined
这里的 this 任然指向的是 window。虽然 fn 函数在 foo 对象中作为方法被引用,但是在赋值给 fn1 之后,fn1 的执行任然是在 window 的全局环境中。
题目3.
const foo = {
bar: 10,
fn: function() {
console.log(this)
console.log(this.bar)
}
}
foo.fn()
答案是:
{ bar: 10, fn: f }
10
因为这个时候 this 指向的时最后调用它的对象,在 foo.fn() 语句中 this 指向 foo 对象。
请记住:
在执行函数时,如果函数中的 this 是被上一级的对象所调用,那么 this 指向的就是上一级对象;否则指向全局环境。
题目4.
const person = {
name: 'zhangsan',
brother: {
name: 'lisi',
fn: function() {
return this.name
}
}
}
console.log(person.brother.fn())
答案是:
lisi
原因就是我们刚刚总结的,this 指向最后调用它的对象,指向的是brother
题目5.
const o1 = {
text: 'o1',
fn: function() {
return this.text
}
}
const o2 = {
text: 'o2',
fn: function() {
return o1.fn()
}
}
const o3 = {
text: 'o3',
fn: function() {
var fn = o1.fn
return fn()
}
}
console.log(o1.fn())
console.log(o2.fn())
console.log(o3.fn())
答案是:
o1
o1
undefined
第一个 console 最简单,o1 没有问题。
难点在第二个和第三个上面,关键还是看调用this的哪个函数。
第二个 console 的 o2.fn(),最终还是调用 o1.fn(),因此答案当然是o1
最后一个,在进行 var fn = o1.fn 赋值之后,是“裸奔”调用,因此这里的 this 指向 window,答案当然时undefined。
如果面试者回答顺利,可以紧接着追问,如果我们需要让:
console.log(o2.fn()) 输出 o2 该怎么做?
一般开发者可能会想到使用 bind/call/apply 来对 this的指向进行干预,这确实时一种思路。但是我接着问,如果不能使用 bind/call/apply,有别的办法吗?
这样可以考察候选人基础掌握的深度及随机应变的能力。答案为:
const o1 = {
text: 'o1',
fn: function() {
return this.text
}
}
const o2 = {
text: 'o2',
fn: o1.fn
}
console.log(o2.fn()) // o2
this 指向最后调用它的对象,在 fn 执行时,挂到 o2 对象上即可
补充:
window.val = 1
var obj = {
val:2,
db1:function () {
this.val *= 2
val *= 2
console.log(val)
console.log(this.val)
}
}
//输出什么结果
obj.db1()
var func = obj.db1
func()
结果: 2 4 8 8
val变量在没有指定对象前缀,默认从函数中找,找不到则从window中找全局变量
箭头函数中的this
题目1.
const foo = {
fn: function() {
setTimeout(function(){
console.log(this)
})
}
}
console.log(foo.fn())
答案是:
window
这道题中,this 出现在 setTimeout() 中的匿名函数里,因此 this 指向 window 对象。
如果需要 this 指向 foo 这个 object 对象,可以巧用箭头函数解决:
const foo = {
fn: function() {
setTimeout(() => {
console.log(this)
})
}
}
console.log(foo.fn())
// { fn: f }
箭头函数使用 this 是根据外层(函数或者全局)上下文来决定。
根据this 的指向问题详解整理得到