Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/466.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中何时隐式调用toString()?_Javascript_Tostring - Fatal编程技术网

在javascript中何时隐式调用toString()?

在javascript中何时隐式调用toString()?,javascript,tostring,Javascript,Tostring,参考下面用Javascript编写的代码 a={ 价值:2, toString:function(){ 返回++此.value; } } 如果(a==3&&a==4){ log(“条件为真”); } 输出为“条件为真”。看起来它调用了“toString()” 功能 每次在两个不同类型的变量之间使用=运算符时,都会在内部调用toString方法,该方法将强制一个成员。看看 但是怎么做呢 您正在为a对象创建一个自定义toString函数,该函数每次使用时都会更改它返回的内容,以使它满足所有两个条件

参考下面用Javascript编写的代码

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我很高兴让您知道您在某种程度上理解了:-)仅供将来的读者阅读:“
==
将尝试将左操作数转换为右操作数类型(如果可能)”,对于示例代码(其中右操作数是一个数字),这是正确的。