JavaScript 对象和字符串之间的松散比较
JavaScript loose comparison between an object and a string
下面的代码,
var someObject = {"attr":1}; // line:1
alert(someObject == "someString"); //line:2
失败,异常:第 2 行中的 unexpected call to method or property access
。
当我将比较更改为 strict
等于时,它工作正常。
alert(someObject === "someString");
我知道进行 strict
比较不会进行 type conversion
,但我无法确定在类型转换发生时究竟是在什么时候抛出此错误。
注意:确切的对象有大约十个属性,每个属性都有一个很长的字符串值。
我能够重现此错误的最少输入:
someObject = {
"a":"RESOLVED",
"b":"A-1444779652190",
"c":"{s=Hello, id=A-1444779652190}"
}
(c
是一个string
,这里不重要)
当您执行 someObject == "someString"
时,Abstract Equality Comparison Algorithm 执行此操作:
- If Type(x) is Object and Type(y) is either String or Number, return the result of the comparison ToPrimitive(x) ==
y.
当用对象调用ToPrimitive时,
Return a default value for the Object. The default value of an object
is retrieved by calling the [[DefaultValue]] internal method of the
object, passing the optional hint PreferredType. The behaviour of
the [[DefaultValue]] internal method is defined by this specification
for all native ECMAScript objects in 8.12.8.
总结一下,当 [[DefaultValue]] 在没有提示的情况下在非日期本机对象上调用时,它会执行以下操作:
- 如果对象有一个
toString
方法,其中returns一个原语,默认值是那个原语
- 如果对象有一个
valueOf
方法,其中 returns 一个原语,默认值是那个原语
- 抛出类型错误
我的猜测是某些代码被修改了 Object.prototype.toString
or Object.prototype.valueOf
,现在它们可能会在被 ToPrimitive 调用时抛出。
下面的代码,
var someObject = {"attr":1}; // line:1
alert(someObject == "someString"); //line:2
失败,异常:第 2 行中的 unexpected call to method or property access
。
当我将比较更改为 strict
等于时,它工作正常。
alert(someObject === "someString");
我知道进行 strict
比较不会进行 type conversion
,但我无法确定在类型转换发生时究竟是在什么时候抛出此错误。
注意:确切的对象有大约十个属性,每个属性都有一个很长的字符串值。
我能够重现此错误的最少输入:
someObject = {
"a":"RESOLVED",
"b":"A-1444779652190",
"c":"{s=Hello, id=A-1444779652190}"
}
(c
是一个string
,这里不重要)
当您执行 someObject == "someString"
时,Abstract Equality Comparison Algorithm 执行此操作:
- If Type(x) is Object and Type(y) is either String or Number, return the result of the comparison ToPrimitive(x) == y.
当用对象调用ToPrimitive时,
Return a default value for the Object. The default value of an object is retrieved by calling the [[DefaultValue]] internal method of the object, passing the optional hint PreferredType. The behaviour of the [[DefaultValue]] internal method is defined by this specification for all native ECMAScript objects in 8.12.8.
总结一下,当 [[DefaultValue]] 在没有提示的情况下在非日期本机对象上调用时,它会执行以下操作:
- 如果对象有一个
toString
方法,其中returns一个原语,默认值是那个原语 - 如果对象有一个
valueOf
方法,其中 returns 一个原语,默认值是那个原语 - 抛出类型错误
我的猜测是某些代码被修改了 Object.prototype.toString
or Object.prototype.valueOf
,现在它们可能会在被 ToPrimitive 调用时抛出。