面试题答案
一键面试严格模式对函数参数处理的影响
- 禁止重复参数名:在非严格模式下,函数定义时可以有重复的参数名,浏览器通常会使用最后一个参数值。例如:
function nonStrictFunction(a, a) {
return a;
}
console.log(nonStrictFunction(1, 2)); // 输出 2
而在严格模式下,重复的参数名会导致语法错误。
function strictFunction(a, a) { 'use strict'; return a; }
// 报错:SyntaxError: Duplicate parameter name not allowed in this context
- 参数值不可被删除:在严格模式下,不能使用
delete
操作符删除函数参数。例如:
function strictFunction(a) {
'use strict';
delete a; // 报错:SyntaxError: Delete of an unqualified identifier in strict mode.
}
在非严格模式下,虽然删除操作不会报错,但也不会有实际效果。
严格模式对函数内this指向的影响
- 全局环境中:在非严格模式下,全局函数中的
this
指向全局对象(浏览器中是window
)。例如:
function nonStrictGlobalFunction() {
return this;
}
console.log(nonStrictGlobalFunction() === window); // 输出 true
在严格模式下,全局函数中的 this
是 undefined
。
function strictGlobalFunction() {
'use strict';
return this;
}
console.log(strictGlobalFunction() === undefined); // 输出 true
- 对象方法中:在非严格模式和严格模式下,对象方法中的
this
都指向调用该方法的对象。例如:
const obj = {
value: 42,
nonStrictMethod: function() {
return this.value;
},
strictMethod: function() {
'use strict';
return this.value;
}
};
console.log(obj.nonStrictMethod()); // 输出 42
console.log(obj.strictMethod()); // 输出 42
- 构造函数中:在非严格模式和严格模式下,构造函数中的
this
都指向新创建的对象实例。例如:
function NonStrictConstructor() {
this.value = 42;
}
const nonStrictInstance = new NonStrictConstructor();
console.log(nonStrictInstance.value); // 输出 42
function StrictConstructor() {
'use strict';
this.value = 42;
}
const strictInstance = new StrictConstructor();
console.log(strictInstance.value); // 输出 42
- 函数调用绑定
this
:在非严格模式下,通过call
、apply
、bind
绑定this
时,null
和undefined
会被转换为全局对象。例如:
function nonStrictFunction() {
return this;
}
console.log(nonStrictFunction.call(null) === window); // 输出 true
在严格模式下,null
和 undefined
作为 this
的值会保持不变。
function strictFunction() {
'use strict';
return this;
}
console.log(strictFunction.call(null) === null); // 输出 true
编写跨模式兼容的函数定义代码
- 处理函数参数:
- 避免使用重复的参数名,这样在严格模式和非严格模式下都不会出错。
- 不尝试在函数内部删除参数,以确保跨模式兼容性。
- 处理
this
指向:- 如果函数需要访问全局对象,可以使用
typeof window === 'object'? window : global
来获取全局对象,而不是依赖this
在非严格模式下指向全局对象的特性。 - 对于需要明确
this
指向的函数,使用bind
方法预先绑定this
。例如:
- 如果函数需要访问全局对象,可以使用
const obj = {
value: 42,
method: function() {
return this.value;
}
};
const boundMethod = obj.method.bind(obj);
// 无论在严格模式还是非严格模式下,调用 boundMethod 时 this 都指向 obj
- 对于构造函数,可以使用 `new.target` 来判断函数是否是通过 `new` 调用的,以确保在不同模式下构造函数的行为一致。例如:
function Constructor() {
if (!new.target) {
throw new Error('Constructor must be called with new');
}
this.value = 42;
}