如何使用Javascript';s indexOf()解析引用

如何使用Javascript';s indexOf()解析引用,javascript,arrays,reference,specifications,ecmascript-5,Javascript,Arrays,Reference,Specifications,Ecmascript 5,我有点困惑于一个思维实验,现在我在寻求一些建议。它是关于ECMAscript引用和Array.prototype.indexOf()方法的 让我们轻松开始: var container = [ ]; // more code container.push( 5 ); container.push( 7 ); container.push( 10 ); 所以现在我们将一些“原始值”放入ECMAscript数组中(不管该语句是否正确,我都会回来讨论),至少到目前为止我是这样想象的。打电话给 co

我有点困惑于一个思维实验,现在我在寻求一些建议。它是关于ECMAscript引用和
Array.prototype.indexOf()
方法的

让我们轻松开始:

var container = [ ];
// more code
container.push( 5 );
container.push( 7 );
container.push( 10 );

所以现在我们将一些“原始值”放入ECMAscript数组中(不管该语句是否正确,我都会回来讨论),至少到目前为止我是这样想象的。打电话给

container.indexOf( 7 );
将按预期返回
1
。我面临的一个大问题是,如果
.indexOf()
真的比较了原语值,或者实际上创建并存储了一个
Number()
对象,并对其引用进行了比较。如果我们这样写的话,这会变得更加明显:

var a = 5,
    b = 7,
    c = 10;

var container = [ ];

container.push( a );
container.push( b );
container.push( c );

container.indexOf( b );

在这之前,人们仍然可以很容易地争辩说,
.indexOf()
需要做的就是比较值,但现在让我们看看这样的事情:

var a = { name: 'a', value: 5 },
    b = { name: 'b', value: 10 },
    c = { name: 'c', value: 15 };

var container = [ ];
// more code
container.push( a );
container.push( b );
container.push( c );
在这里,我们用对象引用填充了该容器数组,但,
.indexOf()
仍能正常工作

container.indexOf( b ) // === 1
而像这样的电话

container.indexOf({ name: 'b', value: 10 });
显然返回
-1
,因为我们正在创建一个新对象并获得一个新引用。所以这里它必须在内部相互比较引用,对吗

一些ECMAscript规范天才能证实这一点吗,或者更好地给我链接一些关于这方面的资料


关于这一点的一个附带问题是,是否有任何可能的方法来访问lexicalEnvironment中的内部存储对象引用。我不确定是否在所有ECMAScript实现中都能保证这一点,但它使用严格相等来进行比较(==)。因此,这将显示您所描述的行为,通过原语上的值进行比较,但通过对象上的引用进行比较(请参见)。

它归结为
indexOf()
依次使用与
==
运算符相同的算法对每个数组属性进行比较

ECMAScript 5规范的相关章节为第15.4.4.14节第9步b节(突出显示):

如果kPresent为true,则

一,。让elementK是调用O的[[Get]]内部方法并使用参数ToString(k)的结果

二,。将严格相等比较算法应用于searchElement和elementK的结果也是一样的

iii.如果相同,则返回k

参考资料:


    • @Tim Down是对的
      indexOf
      进行严格的比较。我通过重写
      valueOf
      函数来演示这一点

      var MyObject = function(n, v){
         this.name = n;
         this.value = v;
      }
      
      MyObject.prototype.valueOf = function(){
          return this.value;
      }
      
      var a = new MyObject("a", 5);
      var b = new MyObject("b", 10);
      var c = new MyObject("c", 15);
      
      var container = [ ];
      
      container.push( a );
      container.push( b );
      container.push( c );
      
      console.log(b == 10); // true
      console.log(container[1] == 10); // true
      
      console.log(b === 10); // false
      container.indexOf(10); // -1
      

      如果这与其他语言类似,那么
      indexOf
      适用于对象散列,其中对象通常具有不同的值,而基元对象通常具有基于其值的常量散列(对于整数,这通常只是整数值本身)。因此,两个int对象
      5
      5
      都有哈希
      5
      ,因此都是“相同的”。我开始写答案,但后来它变成了一篇博客文章,所以我停下来不写了。但是如果您感兴趣的话:即使
      ==
      也会对对象使用引用比较。所以这与严格平等无关,我不是说这是因为严格平等。我是说它实际上使用了严格的平等,这与他描述的行为是一致的。然而,这里描述的严格相等比较并没有描述如何处理一般的对象?看起来它们只描述数字、字符串、布尔值和空/未定义值。另外,我对第一节也很好奇,它说,“调用toString()”参数。如果这确实是本机的
      toString
      那么所有对象都应该返回object object no?@jAndy:
      toString(k)
      位指的是属性名,而不是值。严格等式比较部分确实完整地描述了算法。参见11.9.6中的步骤7:“如果x和y引用同一对象,则返回true。否则,返回false。”。