面试题答案
一键面试普通函数中this的绑定规则
- 默认绑定:在非严格模式下,当函数独立调用(不是作为对象的方法调用)时,
this
指向全局对象(浏览器环境中是window
,Node.js 环境中是global
)。在严格模式下,this
会是undefined
。
function foo() {
console.log(this);
}
// 非严格模式下,在浏览器环境中会输出 window 对象
// 严格模式下,会输出 undefined
foo();
- 隐式绑定:当函数作为对象的方法调用时,
this
指向调用该函数的对象。
const obj = {
name: '张三',
sayHello: function() {
console.log(this.name);
}
};
obj.sayHello(); // 输出 '张三',此时 this 指向 obj
- 显式绑定:通过
call
、apply
和bind
方法可以显式地指定函数中this
的值。call
方法接受多个参数,第一个参数是要绑定的this
值,后面的参数依次作为函数的参数。
function greet(greeting) {
console.log(greeting + ', ' + this.name);
}
const person = {name: '李四'};
greet.call(person, '你好'); // 输出 '你好, 李四',将 this 显式绑定到 person
- `apply` 方法与 `call` 类似,不同之处在于它接受一个数组作为参数,数组的元素作为函数的参数。
function sum(a, b) {
return a + b;
}
const numbers = [2, 3];
const result = sum.apply(null, numbers); // 这里 this 绑定为 null,返回 5
- `bind` 方法会创建一个新的函数,这个新函数的 `this` 被绑定到 `bind` 方法的第一个参数,并且可以传递额外的参数。
function multiply(a, b) {
return a * b;
}
const multiplyByTwo = multiply.bind(null, 2);
const result2 = multiplyByTwo(3); // 返回 6,this 绑定为 null
- new 绑定:当使用
new
关键字调用函数时,会创建一个新的对象,this
会指向这个新创建的对象。
function Person(name) {
this.name = name;
}
const tom = new Person('Tom');
console.log(tom.name); // 输出 'Tom',此时 this 指向 tom
箭头函数中this的绑定规则
箭头函数没有自己的 this
绑定,它的 this
是继承自外层作用域的 this
。它不会根据调用方式来改变 this
的指向,始终保持在定义时外层作用域的 this
值。
const obj2 = {
name: '王五',
getArrowFunction: function() {
return () => {
console.log(this.name);
};
}
};
const arrowFunc = obj2.getArrowFunction();
arrowFunc(); // 输出 '王五',这里箭头函数的 this 继承自外层函数 getArrowFunction 的 this,即 obj2
// 对比普通函数
const obj3 = {
name: '赵六',
getNormalFunction: function() {
return function() {
console.log(this.name);
};
}
};
const normalFunc = obj3.getNormalFunction();
// 在非严格模式下,下面这行代码会输出 undefined 或 window 对象上的 name 属性值(如果存在)
// 在严格模式下,会输出 undefined
normalFunc();