为什么Object.prototype.toString调用时传入null不会转换为全局对象?
问题解答
核心结论
你观察到的差异和「内置方法是否运行在严格模式」无关,是用户自定义函数与内置函数的this绑定逻辑不同导致的。
具体原理说明
你提到的非严格模式下
thisArg为null/undefined时自动转换为全局对象的规则,仅适用于用户自定义的非严格模式普通函数:
当这类函数执行上下文初始化时,会自动把传入的null/undefined类型的this替换为全局对象,这也是你给出的第一段代码运行符合预期的原因:function x() { console.log(this); } x.call(null); // 浏览器环境打印window对象内置函数不遵循上述用户函数的
this替换规则,通过call/apply传入的thisArg会被原封不动地传递给内置函数的内部处理逻辑:
你提到的Object.prototype.toString的规范定义中,第一步就明确了对null和undefined的特殊处理:调用
Object.prototype.toString时,首先校验this值:- 若
this为undefined,直接返回字符串[object Undefined] - 若
this为null,直接返回字符串[object Null]
所以Object.prototype.toString.call(null)执行时,会直接用传入的null作为this做判断,返回[object Null],不会触发全局对象转换。
- 若
关于「所有内置方法是否都运行在严格模式下」的疑问:答案是否定的。内置方法的
this处理逻辑是ECMAScript规范单独为每个内置方法定义的,和严格模式的this绑定规则只是部分表现相似,本质不属于严格模式的范畴。
可以用另一个内置方法验证这个逻辑:// Array.prototype.indexOf要求this必须是类数组对象 Array.prototype.indexOf.call(null, 1); // 直接抛出TypeError,不会把null转换为全局对象如果内置方法遵循普通非严格用户函数的
this转换规则,这里会先把null转为全局对象再执行indexOf逻辑,而非直接抛出类型错误,也能佐证上述结论。
内容的提问来源于stack exchange,提问作者user3009344
相关产品推荐
相关产品推荐

