题目 1:全局环境中的 this
javascript
function foo() {
console.log(this);
}
foo();
输出 :window(浏览器)或 global(Node.js)
原因 :非严格模式下,独立函数调用 this 指向全局对象。
题目 2:隐式绑定(对象方法)
javascript
const obj = {
name: 'Alice',
getName: function() {
console.log(this.name);
}
};
const fn = obj.getName;
fn();
输出 :undefined(严格模式报错)
原因 :fn 是独立调用,this 指向全局,而全局没有 name。
题目 3:隐式绑定的"丢失"
javascript
const obj = {
name: 'Bob',
getName() {
console.log(this.name);
}
};
setTimeout(obj.getName, 1000);
//这里传递的是 函数引用,而不是函数调用。
输出 :undefined(或空字符串)
原因 :setTimeout 回调是独立调用,this 指向全局,相当于 const fn = obj.getName; setTimeout(fn, 1000)。
题目 4:显式绑定(call / apply)
javascript
function say() {
console.log(this.name);
}
const obj1 = { name: 'Tom' };
const obj2 = { name: 'Jerry' };
say.call(obj1);
say.call(obj2);
输出 :'Tom' 然后 'Jerry'
原因 :call 强制将 this 绑定到传入对象。
题目 5:bind 绑定
javascript
function greet() {
console.log(this.name);
}
const obj = { name: 'Lily' };
const boundFn = greet.bind(obj);
boundFn();
输出 :'Lily'
原因 :bind 返回永久绑定 this 的新函数。
题目 6:new 绑定
javascript
function Person(name) {
this.name = name;
console.log(this);
}
const p = new Person('Mike');
输出 :Person { name: 'Mike' }
原因 :new 创建新对象,this 指向该新对象。
题目 7:new 与显式绑定的优先级
javascript
function Foo(name) {
this.name = name;
}
const obj = {};
const boundFoo = Foo.bind(obj);
const p = new boundFoo('Nina');
console.log(obj.name);
console.log(p.name);
输出 :undefined 然后 'Nina'
原因 :new 绑定优先级高于 bind,bind 的绑定被忽略,this 指向新对象 p。
题目 8:箭头函数(不可改变 this)
javascript
const obj = {
name: 'Eva',
getName: () => {
console.log(this.name);
}
};
obj.getName();
输出 :undefined(浏览器非严格模式下)
原因 :箭头函数的 this 继承自外层词法作用域 (此处为全局),不是 obj。
题目 9:箭头函数与 setTimeout
javascript
const obj = {
name: 'Rose',
sayLater() {
setTimeout(() => {
console.log(this.name);
}, 100);
}
};
obj.sayLater();
输出 :'Rose'
原因 :箭头函数捕获 sayLater 的 this(即 obj),不被 setTimeout 改变。
题目 10:综合混用(面试终极题)
javascript
const obj = {
name: 'Jack',
show: function() {
const inner = function() {
console.log(this.name);
};
inner();
}
};
obj.show();
输出 :undefined(严格模式报错)
原因 :inner 是普通函数独立调用,this 指向全局。
题目 11:进阶版(this 的"隐式丢失")
javascript
const length = 10;
function fn() {
console.log(this.length);
}
const obj = {
length: 5,
method(fn) {
fn();
arguments[0]();
}
};
obj.method(fn, 1, 2);
输出 :10 然后 3
原因:
fn()独立调用 →this指向全局 →length = 10arguments[0]()相当于arguments.0(),this指向arguments对象,arguments.length = 3(传入fn,1,2)
📌 快速记忆口诀
| 调用方式 | this 指向 |
|---|---|
| 独立函数调用 | 全局(严格模式 undefined) |
| 对象方法调用 | 调用该方法的对象 |
| call / apply / bind | 传入的第一个参数 |
| new 调用 | 新创建的对象 |
| 箭头函数 | 外层作用域的 this(定义时确定) |
| setTimeout 回调 | 全局(箭头函数除外) |
🧠 面试加分点
如果面试官追问"如何让第 10 题输出 'Jack'",你可以回答:
方案 1:使用箭头函数
javascript
show: function() {
const inner = () => {
console.log(this.name);
};
inner();
}
方案 2 :使用 that = this
javascript
show: function() {
const that = this;
const inner = function() {
console.log(that.name);
};
inner();
}
方案 3 :使用 bind
javascript
show: function() {
const inner = function() {
console.log(this.name);
}.bind(this);
inner();
}