前端面试——this指向

最近看到了面试题目有关于this指向的问题,网上搜了一篇文章,看了之后受益匪浅,特地总结一下。

原文章链接:前端面试中的“this”,你真的了解吗? - 哔哩哔哩

什么是this?

this是一个特殊的关键字,其值由运行时根据函数的执行环境绑定。

也就是说,this指向当前执行环境,可以使用其动态访问运行到其所在代码时候的所有变量

this的约束规则

1.默认的this指向window

这里没什么好说的,你在全局环境下使用的this,就是window对象

2.独立的函数调用,指向window

我们来对比一下,什么是独立和非独立

// 非独立函数 需要初始化,不存在变量提升
var a = function() {
    console.log("xxxx")
}
// 独立函数 存在变量提升 this指向window
function a() {
    console.log("xxxx")
}

 

        function a() {
            console.log('xxxxx',this);
            return function b() {
                console.log('yyyyy',this);
                return function c() {
                    console.log('zzzzz',this);
                }
            }
        }
        a()()()

可以看到,独立函数调用不管多深都是指向window 

 

3.自执行函数调用,指向window

        // exp1
        (function () {
            console.log(this); // Window
        })()

        // exp2
        var a = 10
        function foo() {
            (function son(that) {
                console.log(this); // Window
                console.log(that); // {a: 20, foo: ƒ}
            })(this) // 自执行函数后面加个()表示立即执行 ()里面可以塞入参数
        }

        var obj = {
            a: 20,
            foo: foo,
        }
        obj.foo() 

 

4.闭包当中的this,指向window

        var a = 10

        var obj = {
            a: 20,
            foo: function () {
                var sum = this.count + 10
                console.log('xxxxx',this.count,sum);
                console.log(this.a); // 20
                return function () {
                    console.log(this.a); // 10
                    return sum
                }
            }
        }
        console.log('xxxxx',obj.foo()() );

 

5.函数作为方法调用时,this指向函数的直接父对象

var a = 10
function foo () {
  console.log(this.a);
}

var obj = {
  a: 20,
  foo: foo,
  obj2: {
    a: 30,
    foo: foo
  }
}

// exp1
foo() // 10

// exp2
obj.foo() // 20

// exp3 
obj.obj2.foo() // 30 

隐式绑定丢失

1.隐式绑定的函数被分配为没有 this 指向的变量

var a = 10
var obj = {
  a: 20,
  foo: function () {
    console.log(this.a);
  }
}
function bar (fn) {
  fn()
}

bar(obj.foo) // 10 

2.隐式绑定的函数作为参数传给函数,丢失了this点

var a = 10
var obj = {
  a: 20,
  foo: function () {
    console.log(this.a);
  }
}
function bar (fn) {
  fn()
}

bar(obj.foo) // 10 

原作者应该写错了??这两个代码一模一样,我没太看懂??? 

3.setTimeout和setInterval函数的隐式绑定丢失

// exp1
setTimeout(function() {
  console.log(this); // Window
}, 1000)

// exp2
var a = 10
var obj = {
  a: 20,
  foo: function () {
    console.log(this.a); // 10
  }
}

setTimeout(obj.foo, 1000)

值得注意的是,这两个函数是可以传递this上下文的,只要我们将setTimeout函数的第一个参数写成箭头函数即可。

也就相当于,在这里匿名function的行为和非独立函数调用不一样,但是可以使用匿名箭头函数来实现该效果。

显式绑定

 我们使用call ,apply,bind来显式绑定this的环境

        var obj = {
            ttt: 'my name',
        }
        function test(v1,v2) {
            this.v1 = v1
            this.v2 = v2
            
            console.log('xxxxx',this.ttt);
        }
        test('a','b')
        console.log('xxxxx',obj);
        test.call(obj,'a','b')
        console.log('xxxxx',obj);
        test.apply(obj,['c','d'])
        console.log('xxxxx',obj);
        test.bind(obj,'e','f')()
        console.log('xxxxx',obj);

 

关于硬装订和new绑定,暂时没研究,感兴趣的读者可以前往原链接看看!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JSU_曾是此间年少

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值