JS this指向问题说难不难,本质上取决于调用
2023-12-13 22:08:23
this指向的本质
JavaScript中的this指向是一个很重要的概念,它决定了函数内部的this指向的对象。this指向问题经常困扰初学者,甚至经验丰富的开发者也可能会在某些情况下感到困惑。
在JavaScript中,this指向是由函数的调用方式决定的,而不是由函数的定义方式决定的。也就是说,this指向取决于函数被调用时的执行上下文。
执行上下文可以分为两种:全局执行上下文和函数执行上下文。全局执行上下文是脚本开始执行时创建的,函数执行上下文是在函数被调用时创建的。
在全局执行上下文中,this指向全局对象(window对象)。在函数执行上下文中,this指向函数所属的对象。
常见this指向问题
问题一:箭头函数的this指向
箭头函数(=>)是一个ES6中引入的新语法,它没有自己的this指向,而是继承其外层函数的this指向。
const obj = {
name: 'obj',
sayName: function() {
console.log(this.name); // obj
},
sayNameArrow: () => {
console.log(this.name); // undefined
}
};
obj.sayName(); // obj
obj.sayNameArrow(); // undefined
在上面的示例中,sayName()方法中的this指向obj对象,因为sayName()方法是在obj对象的上下文中被调用的。而sayNameArrow()箭头函数中的this指向undefined,因为箭头函数没有自己的this指向,而是继承其外层函数(sayName()方法)的this指向。
问题二:事件处理函数的this指向
事件处理函数(如onclick、onmousemove等)也是一种特殊的函数,其this指向也与普通函数有所不同。
在事件处理函数中,this指向事件目标元素。
const btn = document.querySelector('button');
btn.addEventListener('click', function() {
console.log(this); // <button>元素
});
在上面的示例中,按钮元素上的click事件处理函数中的this指向按钮元素本身。
问题三:bind、call、apply方法
bind、call、apply方法可以改变函数的this指向。
bind方法返回一个新的函数,该函数的this指向被固定为指定的值。
call方法立即调用函数,并将函数的this指向设置为指定的值。
apply方法也立即调用函数,并将函数的this指向设置为指定的值,不同的是,apply方法将参数作为数组传入函数,而call方法将参数逐个传入函数。
const obj = {
name: 'obj',
sayName: function() {
console.log(this.name);
}
};
const sayName = obj.sayName;
sayName(); // undefined
sayName.bind(obj)(); // obj
sayName.call(obj); // obj
sayName.apply(obj); // obj
在上面的示例中,sayName()函数的this指向是undefined,因为sayName()函数是在全局上下文中被调用的。使用bind、call、apply方法可以改变sayName()函数的this指向,使其指向obj对象。
结论
JavaScript中的this指向是一个很重要的概念,它决定了函数内部的this关键字指向的对象。理解this指向的关键在于认识到this指向并不取决于函数的定义方式,而是取决于函数的调用方式。
在JavaScript中,this指向是由函数的调用方式决定的,而不是由函数的定义方式决定的。也就是说,this指向取决于函数被调用时的执行上下文。
在全局执行上下文中,this指向全局对象(window对象)。在函数执行上下文中,this指向函数所属的对象。
常见的this指向问题包括箭头函数的this指向、事件处理函数的this指向以及bind、call、apply方法的用法。