MST
星途 面试题库

面试题:JavaScript函数定义兼容性之严格模式影响

在严格模式和非严格模式下,JavaScript函数定义的一些规则有所不同,这可能带来兼容性问题。请阐述严格模式对函数参数处理、函数内this指向的影响,以及如何编写跨模式兼容的函数定义代码。
10.9万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

严格模式对函数参数处理的影响

  1. 禁止重复参数名:在非严格模式下,函数定义时可以有重复的参数名,浏览器通常会使用最后一个参数值。例如:
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
  1. 参数值不可被删除:在严格模式下,不能使用 delete 操作符删除函数参数。例如:
function strictFunction(a) {
    'use strict';
    delete a; // 报错:SyntaxError: Delete of an unqualified identifier in strict mode.
}

在非严格模式下,虽然删除操作不会报错,但也不会有实际效果。

严格模式对函数内this指向的影响

  1. 全局环境中:在非严格模式下,全局函数中的 this 指向全局对象(浏览器中是 window)。例如:
function nonStrictGlobalFunction() {
    return this;
}
console.log(nonStrictGlobalFunction() === window); // 输出 true

在严格模式下,全局函数中的 thisundefined

function strictGlobalFunction() {
    'use strict';
    return this;
}
console.log(strictGlobalFunction() === undefined); // 输出 true
  1. 对象方法中:在非严格模式和严格模式下,对象方法中的 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
  1. 构造函数中:在非严格模式和严格模式下,构造函数中的 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
  1. 函数调用绑定 this:在非严格模式下,通过 callapplybind 绑定 this 时,nullundefined 会被转换为全局对象。例如:
function nonStrictFunction() {
    return this;
}
console.log(nonStrictFunction.call(null) === window); // 输出 true

在严格模式下,nullundefined 作为 this 的值会保持不变。

function strictFunction() {
    'use strict';
    return this;
}
console.log(strictFunction.call(null) === null); // 输出 true

编写跨模式兼容的函数定义代码

  1. 处理函数参数
    • 避免使用重复的参数名,这样在严格模式和非严格模式下都不会出错。
    • 不尝试在函数内部删除参数,以确保跨模式兼容性。
  2. 处理 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;
}