如何使用Javascript';s indexOf()解析引用
我有点困惑于一个思维实验,现在我在寻求一些建议。它是关于ECMAscript引用和如何使用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
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。”。