Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/396.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么JavaScript的行为是这样的?_Javascript_Coercion - Fatal编程技术网

为什么JavaScript的行为是这样的?

为什么JavaScript的行为是这样的?,javascript,coercion,Javascript,Coercion,让我们看看这些例子: var a = 1; var b = { toString:function() {return '1'} }; var c = 1; a + b + c === "111" // true 这真是令人兴奋。我知道当我们使用+运算符时,JS解释器执行ToPrimitive或ToString操作。但是,当没有提示PreferredType时,为什么对象b会转换为字符串呢。因此,它可能正在使用ToString操作 另一个注意事项:只有当对象上存在toString方法时,才

让我们看看这些例子:

var a = 1;
var b = { toString:function() {return '1'} };
var c = 1;

a + b + c === "111" // true

这真是令人兴奋。我知道当我们使用+运算符时,JS解释器执行ToPrimitive或ToString操作。但是,当没有提示PreferredType时,为什么对象b会转换为字符串呢。因此,它可能正在使用ToString操作

另一个注意事项:只有当对象上存在toString方法时,才会转换为string,为什么?如果我把这个方法叫做“toNumber”,为什么它不转换成number呢

为什么JavaScript的行为如此?

但是,当没有提示PreferredType时,为什么对象b会转换为字符串呢

当没有传递任何提示时,将首先调用对象的
valueOf
方法。但是由于
b.valueOf()
不返回原语值(默认情况下返回对象本身),因此接下来将调用
b.toString()

转换规则可以总结如下:

  • 如果没有提示或提示是
    号码
    ,请先调用
  • 如果提示是
    string
    ,请先调用
    toString
  • 如果返回值不是基元值,则调用另一个方法
  • 如果返回值仍然不是primitve,则抛出错误
只有当对象上存在toString方法时,才会转换为string,为什么

我不确定我是否理解这句话。每个对象都有一个
toString
方法。如果尝试在没有
toString
方法的对象上执行此操作(通过
object.create(null)
),则会引发错误

如果我把这个方法叫做“toNumber”,为什么它不转换成number呢

因为
toNumber
在JavaScript中没有任何意义
toString
valueOf
是将对象转换为基本体的两种“神奇”方法:

var n=1;
变量o={
toString(){return'bar';},
valueOf(){return 2;}
};
控制台日志(n+o);

log(字符串(o))
我猜,因为您的变量之一是字符串,所以它假定您正在连接。
b
是一个对象,具有您编写的
.toString
方法,该方法将“1”作为字符串返回。所以
1+'1'+1==='111'
是因为Javascript大概调用了
b.toString()
。当对对象使用
+
时,它将被强制为字符串(对象的原型上有一个toString方法)。因此,即使您自己不添加一个,它也会自动拥有一个默认值。此外,也没有像其他一些语言那样的
toNumber
“magic”方法,这就是为什么在操作中命名函数时不会自动将其转换为数字
,只有在对象上存在toString方法时才会转换为字符串,为什么
这部分是正确的,但这只是因为所有对象都有一个toString。只要
b
不是可以强制转换为数字的数字或值,它就会转换为字符串。如果您没有在原型中的某个地方定义
toString
函数,那么将使用
Object.prototype.toString
,字符串将是
“[Object Object Object]”
。实际上,您可以在这里看到它:
Object.create(null,{})+Object.create(null,{})
(这些对象保证没有任何方法,包括
toString
)将给你
类型错误:无法将对象转换为原始值
。一个对象需要
转换为字符串
,以便能够参与
+
。我必须承认:我以前从未遇到过TopPrimitive符号。看起来我需要花更多的时间阅读文档。我甚至没有读过关于这个
@@toPrimitive
到现在为止..@Felix Kling,我现在知道了。所以调用了对象内部方法toString并返回了一个字符串。当没有内部toString方法时,JS使用object.prototype.toString()。我甚至可以添加内部方法valueOf来返回我想要的任何内容,并使JS解释器按照我想要的方式运行。谢谢。@Hyphen:是的,
valueOf
基本上就是您所期望的
toNumber
的样子。