严格模式下call传null或undefined时this保持原值;非严格模式下自动转为全局对象(浏览器window/Node global),提升可预测性与调试效率。

严格模式下,call 传 null 或 undefined,this 就真的是 null 或 undefined;非严格模式下,它们会被自动替换成全局对象(浏览器中是 window,Node.js 中是 global)。
非严格模式:自动“兜底”
JS 会主动把 null 和 undefined 当作“没传有效对象”,于是用全局对象补上。这种宽容容易掩盖问题:
function foo() { console.log(this); }-
foo.call(null);→ 输出window(不是null) -
foo.call(undefined);→ 同样输出window - 如果函数里写
this.name = 'Alice',就意外挂到了全局上
严格模式:原样传递
加了 "use strict" 后,JS 不再猜测意图,你传什么,this 就是什么:
"use strict"; function foo() { console.log(this); }-
foo.call(null);→ 输出null -
foo.call(undefined);→ 输出undefined - 后续访问
this.xxx会直接报错,比如Cannot read property 'x' of null
为什么这个区别重要
它关系到代码的可预测性和调试效率:
- 非严格模式下,
this行为不一致,容易在跨环境(如浏览器 vs Node)时出问题 - 严格模式让
call/apply/bind的第一个参数真正“可控”,便于封装工具函数或模拟上下文 - ES6 模块默认启用严格模式,所以现代项目中这个行为更常见
顺便注意:其他值不受影响
不管是严格还是非严格模式,只要传的是对象(包括数组、函数、空对象等)或原始值(如 1、"abc"、true),this 都按预期指向它(原始值会被包装成对应对象):
-
foo.call({x: 1});→this是{x: 1} -
foo.call("hello");→this是String {"hello"} - 只有
null和undefined在两种模式下行为不同

















