在javascript中何时隐式调用toString()?
参考下面用Javascript编写的代码在javascript中何时隐式调用toString()?,javascript,tostring,Javascript,Tostring,参考下面用Javascript编写的代码 a={ 价值:2, toString:function(){ 返回++此.value; } } 如果(a==3&&a==4){ log(“条件为真”); } 输出为“条件为真”。看起来它调用了“toString()” 功能 每次在两个不同类型的变量之间使用=运算符时,都会在内部调用toString方法,该方法将强制一个成员。看看 但是怎么做呢 您正在为a对象创建一个自定义toString函数,该函数每次使用时都会更改它返回的内容,以使它满足所有两个条件
a={
价值:2,
toString:function(){
返回++此.value;
}
}
如果(a==3&&a==4){
log(“条件为真”);
}
输出为“条件为真”。看起来它调用了“toString()”
功能
每次在两个不同类型的变量之间使用=
运算符时,都会在内部调用toString
方法,该方法将强制一个成员
。看看
但是怎么做呢
您正在为a
对象创建一个自定义toString
函数,该函数每次使用时都会更改它返回的内容,以使它满足所有两个条件。
您还可以使用valueOf
方法
操作员怎么样
否则,==
运算符将不执行转换
这是什么意思
如果对两个不同类型的值使用
==
运算符==
将只返回false除了Mihai的答案之外,==
是一个严格的类型检查相等运算符,它还检查操作数的类型和值
在您的例子中,
a
的类型是一个对象,而3
和4
是数字。因此,当您执行=
时,条件的计算结果不会为true这不是一个严格的比较,因此它对条件a==3&&a==4
的作用是首先比较a==3
。因为这不是一个严格的比较,所以它将a
更改为字符串。由于在a
中有toString()
,这将a
的值从2增加到3,因此a==3
结果为true
。然后,a==4
以同样的方式进行检查,这次a
的值是3
,因此当它检查a==4
时,通过调用a
的toString()
函数得到true
a={
价值:2,
toString:function(){
返回++此.value;
}
}
如果(a==3&&a==4){
log(“条件为真”);
}
当您使用==时,它会检查对象是否有错误值,这就是为什么从a==4和a==3得到true的原因。查看类型强制。在比较变量时,它不会强制变量,这就是您无法进入block语句的原因。您可以从下面的链接中找到有关javascript中“==”和“==”如何工作的详细信息:
在此URL中,请参阅“使用==”部分
在您的情况下,您的比较结果为a==3。a是对象,3是数字。因此,比较将以ToPrimitive(a)==3的形式进行。TopPrimitive(a)所做的是试图调用a上的a.toString和a.valueOf方法的不同序列。这就是调用toString函数的方式。表面上看,你的问题看起来像是==
和==
运算符之间的根本区别,但实际上还有更多的区别
对于第一个问题,由于javascript不是严格类型化的语言,因此有两个运算符,=
将尝试将左操作数转换为右操作数类型(如果可能),而==
将在类型不同(除了NaN
之外)时给出false
一个更有趣的问题是何时调用toString
方法。通常,当您通过键入对象文字或通过构造函数创建对象时,它将从对象继承toString
,您可以轻松检查:
var u = function(){};
var w = {};
u.prototype.toString === Object.prototype.toString //true
w.toString === Object.prototype.toString //true as well
现在您可能会忘记还有一个valueOf
方法:
u.prototype.valueOf === Object.prototype.valueOf //true
w.valueOf === Object.prototype.valueOf //true as well
但是它有什么作用呢?我指出自己:
w.valueOf === w //true
u.prototype.valueOf() === u.prototype //true as well
因此,当给定一个对象时,第一个选择是使用toString
,因为valueOf
将导致对象本身。默认情况下,toString
提供了什么?它可以取决于原型链上的内容:
w.toString() //"[object Object]"
u.toString() //"function (){}"
u.prototype.toString.call(u) //"[object Function]"
因此,默认情况下,第一个选择是使用对象的最近的toString
方法。现在,为了了解如果我们同时覆盖valueOf
和toString
,会发生什么情况,让我构造这个对象:
var x = {
inner:10,
ledger:[],
result:[],
timeout:0,
toString:function(){
console.log("String");
clearTimeout(this.timeout);
this.timeout = setTimeout((function(){
this.result = this.ledger;
this.ledger = []}).bind(this)
,0) ;
this.ledger.push("toString");
this.ledger.slice(-2);
return String(this.inner);
},
valueOf:function(){
console.log("Valueof");
clearTimeout(this.timeout);
this.timeout = setTimeout((function(){
this.result = this.ledger;
this.ledger = []}).bind(this)
,0) ;
this.ledger.push("valueOf");
this.ledger.slice(-2);
return this.inner;
}
}
此对象将保留一个“分类账”,一个在类型转换期间调用的valueOf
或toString
数组或两者。它还将console.log
。下面是一些触发类型转换的操作,就像==
:
+x //10
//ValueOf
"5" + x //"510"
//ValueOf
x + [] //10
//ValueOf
x + "str"//"10str"
//ValueOf
x.toString() //"10"
//String
String(x) //"10"
//String
x + {u:""} //"10[object Object]"
//valueOf
因此,在许多情况下,如果发现使用的是非默认值。如果右操作数是字符串,则对象上的valueOf
返回值将转换为字符串,而不是toString
。要覆盖默认行为,您可以使用toString
或string(
)强制调用string,如示例所示。因此优先级列表如下所示:
Custom-valueOf>>Custom-toString>>default-toString>>>>default-valueOf注意到toString
是在插值字符串中调用的,执行优先级高于valueOf
var a = {
value: 1000,
toString: () => 'call toString method',
valueOf: () => 'call valueOf method'
};
console.log(`interpreted value: ${a}`); // interpreted value: call toString method
的可能副本不会为meI打印任何内容。我不认为这会被计算为真。输出为“Condition is true”。
对此有任何解释吗?仅供未来读者阅读:“每次在两个不同类型的变量之间使用==
运算符时,它都会在内部调用toString
方法”例如,当将一个数字与一个字符串进行比较时。这是有意义的。比其他类型更好。@Jai我很高兴让您知道您在某种程度上理解了:-)仅供将来的读者阅读:“==
将尝试将左操作数转换为右操作数类型(如果可能)”,对于示例代码(其中右操作数是一个数字),这是正确的。