我在思想实验上有点困惑,现在我正在寻找一些建议。它关于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 激活对象中访问内部存储的对象引用。
答案 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