this的指向问题:函数中的this和箭头函数中的this

函数中的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 的指向问题详解整理得到

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值