面试题答案
一键面试1. 跨浏览器环境下this
关键字的兼容性问题
- 全局作用域下:
- 在非严格模式下,浏览器中全局作用域的
this
通常指向window
对象。例如:
- 在非严格模式下,浏览器中全局作用域的
console.log(this === window); // 在浏览器非严格模式下返回true
- 但在Node.js环境中,全局作用域的
this
并不指向全局对象(global
),而是指向一个空对象。这就导致在浏览器和Node.js之间代码移植时,涉及全局this
的代码可能出错。 - 函数调用中的
this
:- 当函数作为普通函数调用时,在非严格模式下,
this
通常指向全局对象(浏览器中是window
)。例如:
- 当函数作为普通函数调用时,在非严格模式下,
function test() {
console.log(this);
}
test(); // 在浏览器非严格模式下输出window对象
- 然而在严格模式下,函数作为普通函数调用时,
this
的值为undefined
。这一差异会导致依赖this
指向全局对象的代码在严格模式下出错。 - 不同浏览器对构造函数中
this
的处理也可能存在细微差别。理论上,构造函数中的this
应该指向新创建的对象实例,但在一些旧版本浏览器中可能出现异常情况。
2. 严格模式改变this
的绑定规则
- 普通函数调用:在非严格模式下,普通函数调用时
this
指向全局对象(浏览器中是window
)。而在严格模式下,普通函数调用时this
的值为undefined
。例如:
// 非严格模式
function nonStrict() {
console.log(this);
}
nonStrict(); // 输出window对象
// 严格模式
function strict() {
'use strict';
console.log(this);
}
strict(); // 输出undefined
- 构造函数调用:在严格模式和非严格模式下,构造函数中的
this
都指向新创建的对象实例,没有区别。例如:
function Person(name) {
this.name = name;
}
var person = new Person('John');
console.log(person.name); // 输出John
- 作为对象方法调用:在严格模式和非严格模式下,
this
都指向调用该方法的对象。例如:
var obj = {
method: function() {
return this;
}
};
console.log(obj.method() === obj); // 在严格和非严格模式下都返回true
3. 编写跨浏览器且在严格模式下能正确处理this
的代码
- 使用
bind
方法:可以通过bind
方法将函数中的this
绑定到特定对象,确保在不同环境和模式下this
的指向一致。例如:
function greet() {
console.log('Hello, ' + this.name);
}
var person = {
name: 'Jane'
};
var boundGreet = greet.bind(person);
boundGreet(); // 输出Hello, Jane
- 使用箭头函数:箭头函数本身没有自己的
this
,它的this
继承自外层作用域。这在处理嵌套函数时可以避免this
指向混乱的问题,并且在跨浏览器和严格模式下表现一致。例如:
var obj = {
name: 'Bob',
getGreetFunction: function() {
return () => {
console.log('Hello, ' + this.name);
};
}
};
var greetFunction = obj.getGreetFunction();
greetFunction(); // 输出Hello, Bob
通过上述方法,可以有效地解决this
在跨浏览器环境和严格模式下的兼容性问题。