js中this的指向问题
前言:
在js中,this出现的位置多种多样,你会不会迷糊呢?this到底指代的是哪个对象?这篇文章带你搞懂不同场景下this的指向问题。
this出现场景:
从作用域的角度来讲,this出现的位置无非就是两种类型:全局作用域,函数作用域。
全局作用域
在全局作用域中,this
指向全局对象。在浏览器中,全局对象是 window
,而在 Node.js 中,它是 global
。
console.log(this); // 在浏览器中,输出 window 对象
函数作用域:
函数调用:
普通函数调用:在非严格模式下,this
指向全局对象(浏览器中是 window
);在严格模式下,this
是 undefined
。
function test() {
console.log(this);
}
test(); // 非严格模式下输出 window,严格模式下输出 undefined
严格模式下的函数调用:
'use strict';
function test() {
console.log(this); // 输出 undefined
}
test();
方法调用:
当函数作为对象的方法被调用时,this
指向该对象。
const obj = {
name: 'Alice',
greet: function() {
console.log(this.name);
}
};
obj.greet(); // 输出 'Alice'
构造函数调用:
当使用 new
关键字调用函数时,this
指向新创建的对象。
function Person(name) {
this.name = name;
}
const person = new Person('Bob');
console.log(person.name); // 输出 'Bob'
箭头函数:
箭头函数不绑定自己的 this
,而是继承自外围作用域的 this
。
const obj = {
name: 'Charlie',
greet: function() {
const arrowFunc = () => {
console.log(this.name);
};
arrowFunc();
}
};
obj.greet(); // 输出 'Charlie'
显示指定this指向:
call
和 apply
:允许显式设置 this
的值。
function greet(greeting) {
console.log(greeting + ', ' + this.name);
}
const person = { name: 'David' };
greet.call(person, 'Hello'); // 输出 'Hello, David'
greet.call(person,['Hello']); // 输出 'Hello, David'
apply
的用法与 call
类似,只是参数以数组形式传递。
bind
:返回一个新函数,其中 this
被永久绑定到指定的值。
const boundGreet = greet.bind(person, 'Hi');
boundGreet(); // 输出 'Hi, David'
this指向测试题
1、
const obj = {
name: 'Alice',
showThis: function() {
setTimeout(function() {
console.log(this.name);
}, 1000);
}
};
obj.showThis();
setTimeout 中的回调函数是普通函数调用,其 this 指向全局对象(浏览器中是 window,Node.js 中是 global)。
如果全局对象没有 name 属性,输出 undefined。
2、
const obj = {
name: 'Alice',
showThis: function() {
setTimeout(() => {
console.log(this.name);
}, 1000);
}
};
obj.showThis();
箭头函数不会创建自己的 this,它会继承外层作用域的 this。
在这里,外层作用域是 showThis 方法,因此 this 指向 obj。
输出结果为:Alice。
3、
const person = {
name: 'Charlie',
showThis: function() {
return () => {
console.log(this.name);
};
}
};
const arrowFunc = person.showThis();
arrowFunc();
person.showThis() 返回的是一个箭头函数,箭头函数的 this 继承自其定义时的作用域。
定义时的作用域是 showThis 方法,而 showThis 中的 this 指向 person。
因此,最终 this 指向 person,输出结果为:Charlie。
4、
const name = 'Global';
const obj = {
name: 'Alice',
showThis: function() {
console.log(this.name);
}
};
const show = obj.showThis;
show();
show 是从 obj 中提取的普通函数引用,调用时没有绑定到 obj。
普通函数调用中,this 指向全局对象(浏览器中是 window,Node.js 中是 global)。
如果全局对象有 name 属性(如浏览器中 window.name 默认是空字符串),输出该值;否则输出 undefined。
const声明的变量不会被挂载在window上,因此会输出undefined
5、
const obj = {
name: 'Alice',
showThis: function() {
console.log(this.name);
}
};
const boundFunc = obj.showThis.bind({ name: 'Bob' });
boundFunc();
bind 方法会创建一个新函数,并将 this 显式绑定到指定的对象({ name: 'Bob' })。
因此,this 指向 { name: 'Bob' },输出结果为:Bob。
以上测试题如果你都搞明白了,说明你已经有了不错的收获。恭喜你,今天的你又进步了一点点,加油!!!