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 执行此操作:

  1. 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]] 在没有提示的情况下在非日期本机对象上调用时,它会执行以下操作:

  1. 如果对象有一个toString方法,其中returns一个原语,默认值是那个原语
  2. 如果对象有一个 valueOf 方法,其中 returns 一个原语,默认值是那个原语
  3. 抛出类型错误

我的猜测是某些代码被修改了 Object.prototype.toString or Object.prototype.valueOf,现在它们可能会在被 ToPrimitive 调用时抛出。