为什么原始变量的行为类似于对象
Why does a primitive variable act like an Object?
如果我们像这样向数字函数(或布尔值或字符串)添加一个方法
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(),它引发了一个语法错误。在此处阅读更多内容
原语和对象之间强制。在这种情况下,数字值被强制到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
- Javascript日期格式类似于ISO,但本地
- 有可能对对象中的所有键进行原子更新吗?类似于阵列拼接的东西
- HTML按钮的作用类似于从键盘按下的键,并在某些对象或整个网站上起作用
- 如何创建行为类似于本机对象的对象
- 如果闭包的行为类似于对象,它们是对象吗?(好像不像)
- 为什么原始变量的行为类似于对象
- 使用类似于 Array.prototype.map() 的方法将数组转换为键值对象
- 对闭包内对象的赋值的行为类似于指针
- 删除对象属性类似于删除带有拼接的数组元素
- javascript对象的类似于merge/concat的方法.不延伸
- 为什么String.prototype会记录它's对象类似于标准对象,而Array.prototype记录它
- 如何使用调用、应用和绑定在Ruby中的对象上强制使用类似于JavaScript的方法
- 是否可以用一些类似于浏览器警报对象的属性来扩展jquery对话框
- JavaScript -数组的行为类似于对象
- 我如何动态地添加到JavaScript对象类似于JavaScript的数组推送函数
- 如何以类似于commonJS的方式扩展对象
- Javascript对象实例化类似于php new $className();
- Java:数据类型类似于javascript对象
- 类似于对象URL的方式在Chrome for Android中播放本地音频文件
- JavaScript名称空间模式(类似于对象的属性)