为什么原始变量的行为类似于对象

Why does a primitive variable act like an Object?

本文关键字:类似于 对象 原始 变量 为什么      更新时间:2023-09-26

如果我们像这样向数字函数(或布尔值或字符串)添加一个方法

Number.prototype.sayMyNumber = function(){
    return "My number is " + this;
}

然后创建一个数字对象,将其分配给变量

var num1 = new Number(34); 
num1.sayMyNumber(); // it says "My number is 34"

这很好,也是意料之中的,因为我们创建了"数字"对象。

同样,如果我创建一个原始变量

num2 = 34;
num2.sayMyNumber(); // it says "My number is 34"

令人惊讶的是,num2 也有一个方法 sayMyNumber(),即使我们没有显式创建一个 Number 对象。

然后我就这样试了试,

34.sayMyNumber(); // error, this does not work 

为什么 num2 有效?

更新

这是我在评论部分提出的后续问题,我把它放在这里是为了更好的可见性

下面的答案提到 num2 在内部被视为"数字"对象。这让我更加困惑。

typeof num1 === "number" // returns false
typeof num2 === "number" // returns true
typeof num1 === "object" // returns true
typeof num2 === "object" // returns false

这不意味着 num2 不是一个"对象"吗?如果它不是"对象",那么它怎么可能是"数字"的实例?

基元类型 Number 具有相应的对象表示形式,您可以使用 new Number 创建。这是一个对象,因此与基元类型 Number 具有不同的数据类型

如果调用 Number(34)(不带 new),则不会创建对象,但 Number 函数执行类型转换为基元数字值。

var num1 = new Number(34); // object
var num2 = 34; // primitive

当您在基元数num2上调用sayMyNumber()时,JavaScript 会在内部将基元临时转换为其等效的对象版本。而且,由于您向Number.prototype添加了sayMyNumber(),因此您可以访问该功能。

34.sayMyNumber()不起作用的原因是,当 JavaScript 引擎解析你的源代码时,它必须解释点在给定上下文中的含义。在34.sayMyNumber()的情况下,点可能是模棱两可的。它的意思是小数点分隔符吗?还是意味着对象成员访问?JavaScript 选择将所有整数后跟一个点解释为表示浮点数的一部分。但是由于没有这样的数字34.sayMyNumber(),它引发了一个语法错误。在此处阅读更多内容

JavaScript 在

原语和对象之间强制。在这种情况下,数字值被强制到Number对象,以便访问原型方法sayMyNumber。实际上,通过这种方式,原语可以访问由其各自的对象构造函数定义的所有属性和方法。但是,它们与对象不同,因为它们是不可变的。

因此,(34).sayMyNumber();有效;(34).toFixed()(34).toPrecision()也是如此。

至于34.sayMyNumber();,正如后德最指出的,是一个语法错误。

对于两者,

var num1 = new Number(34); 
num2 = 34;

"Number"类型值同时分配给num1变量和num2变量。所以它调用原型,它附加到"Number".

但是调用34.sayMyNumber有语法错误,它是一个非法的语句。

如果有人对此有疑问,请参考...https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number