You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用严格模式与非严格模式函数时this的typeof差异

非严格模式下使用call传入原始值时,this被包装成对象是预期行为吗?有没有解决办法?

我发现当对非严格模式的函数使用func.call(12)时,this的值是new Number(12)而不是原始值12——从代码运行结果里typeof this返回'object'就能看出来。想请教下这是JS的预期行为吗?有没有办法让非严格模式下的this也保持原始值类型?

测试代码:

function a() { return this; }
function b() { 'use strict'; return this; }
const x = a.call(12);
console.log(typeof x); // 输出 'object'
console.log(x); // 输出 Number {12}
console.log(x + 3); // 输出 15
const y = b.call(12);
console.log(typeof y); // 输出 'number'
console.log(y); // 输出 12
console.log(y + 3); // 输出 15

这完全是预期行为,属于JavaScript非严格模式下的this绑定规则:

  • 在非严格模式中,当你通过call/apply/bind给函数传入原始值(数字、字符串、布尔值)作为this时,JS会自动执行装箱操作——把原始值包装成对应的包装对象(数字→Number对象,字符串→String对象,布尔值→Boolean对象)。这是早期JS设计的历史遗留行为,目的是让原始值能调用原型上的方法(比如12.toString())。
  • 而严格模式则取消了这个自动装箱行为,传入的原始值会直接作为this的值,不会被包装成对象,这也是严格模式更符合直觉的原因之一。

解决办法

如果你需要在非严格模式下让this保持原始值类型,有两种常用方式:

  1. 手动将this转换为原始值
    在函数内部,你可以通过valueOf()方法或者一元+运算符把包装对象转回原始值:

    function a() {
      // 两种方式任选其一
      return this.valueOf();
      // 或者 return +this;
    }
    const x = a.call(12);
    console.log(typeof x); // 输出 'number'
    console.log(x); // 输出 12
    
  2. 开启严格模式
    这是更推荐的方案,直接在函数内部或者整个脚本顶部添加'use strict';声明,这样call传入的原始值就不会被自动装箱了,和你代码里的函数b表现一致。严格模式不仅能解决这个问题,还能避免很多JS的怪异行为,提升代码的安全性和性能。

内容的提问来源于stack exchange,提问作者Jessy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:10:59