【前端面试题】一文搞懂JavaScript this指向问题

88 篇文章 1 订阅
3 篇文章 0 订阅

JavaScript中的this代表的是当前行为执行的主体,在JavaScript中主要研究的都是函数中的this,但并不是说只有在函数里才有thisthis实际上是在函数被调用时发生的绑定,它指向什么完全取决于函数在哪里被调用

1. 函数调用

函数执行时首先看函数名前面是否有.,若有,.前面是谁,this就是谁。没有的话this就是window

function fn() {
    console.log(this);
}

let obj = { fn: fn };

fn(); // this -> window
obj.fn(); // this -> obj

function sum() {
    fn();
}

sum(); // this -> window

let obj2 = {
    sum: function () {
        console.log(this);
        fn();
    },
};

obj2.sum();
// sum中的this -> obj2
// sum中fn中的this -> window

2. 自执行函数

自执行函数中的this永远是window

(function () {
    console.log(this); //this -> window
})();
~(function () {
    console.log(this); //this -> window
})();

3. 事件绑定

  • DOM零级事件绑定
oDiv.onclick = function () {
    // this -> oDiv
};
  • DOM二级事件绑定
oDiv.addEventListener(
    'click',
    function () {
        // this -> oDiv
    },
    false
);
  • IE6~8下使用attachEvent,默认的this就是指的window对象
oDiv.attachEvent('click', function () {
    // this -> window
});

4. 构造函数

在构造函数模式中,类中(函数体中)出现的this.xxx=xxx中的this是当前类的一个实例。

function Person(name, age) {
    this.name = name;
    this.age = age;
    this.do = function () {
        console.log(this);
    };
}
var p1 = new Person('Jack', 18);
p1.do(); // this -> p1实例对象

类中某一个属性值(方法),方法中的this需要看方法执行的时候,前面是否有.,才能知道this是谁。

function Fn() {
    this.x = 100;
    this.getX = function () {
        console.log(this.x);
    };
}
let f1 = new Fn();
f1.getX(); // this -> 100
let ss = f1.getX;
ss(); // this -> undefined

5. call()、apply()和bind()

详情请点击:JavaScript改变函数内部this指向

6. 箭头函数

(1)箭头函数不绑定this

箭头函数的this看外层的是否有函数,如果有,外层函数的this就是内部箭头函数的this。如果没有,则thiswindow

let btn1 = document.getElementById('btn1');
let obj = {
    name: 'kobe',
    age: 39,
    getName: function () {
        btn1.onclick = () => {
            console.log(this); // this -> obj
        };
    },
};
obj.getName();

(2)若上一层并不存在函数,this指向又是谁?

let btn2 = document.getElementById('btn2');
let obj = {
    name: 'kobe',
    age: 39,
    getName: () => {
        btn2.onclick = () => {
            console.log(this); // this -> window
        };
    },
};
obj.getName();

上例中,虽然存在两个箭头函数,其实this取决于最外层的箭头函数,由于obj是个对象而非函数,所以this指向为window

(3)用call()或者apply()调用箭头函数时,无法对this进行绑定,即传入的第一个参数被忽略

let obj = {
    birth: 1990,
    getAge: function (year) {
        let fn = year => year - this.birth; // this.birth -> 1990
        return fn.call({ birth: 2000 }, year); // 第一个参数被忽略,this.birth -> 1990
    },
};
console.log(obj.getAge(2018)); // 28
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

火星飞鸟

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

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

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

打赏作者

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

抵扣说明:

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

余额充值