Javascript indexOf()如何解析引用

时间:2012-09-27 10:20:11

标签: javascript arrays reference specifications ecmascript-5

我在思想实验上有点困惑,现在我正在寻找一些建议。它关于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 );

在这里,我们使用 object-references 填充了该容器数组,并且.indexOf()仍按预期工作

container.indexOf( b ) // === 1

这样的电话

container.indexOf({ name: 'b', value: 10 });

显然会返回-1,因为我们正在创建一个新对象并获得一个新引用。所以在这里它必须在内部比较参考,对吧?

一些ECMAscript spec天才可以确认甚至更好地将我的一些材料与我联系起来吗?

对此的一个附带问题是,是否有任何可能的方法分别在 lexicalEnvironment 激活对象中访问内部存储的对象引用。

3 个答案:

答案 0 :(得分:8)

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

ECMAScript 5规范的相关部分是第15.4.4.14节,第9步,第b节(突出显示我的):

  

如果kPresent为true,那么

     
    

我。设elementK是使用参数ToString(k)调用O的[[Get]]内部方法的结果。

         

II。同样是将严格的等式比较算法应用于searchElement和elementK的结果。

         

III。如果同样如此,则返回k。

  

参考文献:

答案 1 :(得分:2)

我不确定是否所有ECMAScript实现都能保证这一点,但Mozilla documentation表明它使用严格相等来进行比较(===)。因此,这将展示您描述的行为,通过基元上的值进行比较,但通过引用对象(参见strict equality)。

答案 2 :(得分:0)

@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