I was confusing myself a little with a thought experiment and now I'm looking for some advice. Its about ECMAscript references and the Array.prototype.indexOf()
method.
我有点困惑于一个思想实验,现在我在寻找一些建议。它是关于ECMAscript引用和Array.prototype.indexOf()方法的。
Lets start easy:
让我们开始容易:
var container = [ ];
// more code
container.push( 5 );
container.push( 7 );
container.push( 10 );
So now we pushed some "primitive values" into our ECMAscript array (whether or not that statement is true I'll come back for), at least I imagined it like this so far. A call to
因此,现在我们将一些“原始值”推入ECMAscript数组(无论这个语句是否正确,我都将返回),至少到目前为止我是这样认为的。调用
container.indexOf( 7 );
will return 1
as expected. The big question I'm having is, if .indexOf()
really compares the primitive value or if in reality a Number()
object is created + stored and its reference is getting compared. This becomes a little more obvious if we re-write that like so:
将按预期返回1。我遇到的最大问题是,如果. indexof()真的在比较原始值,或者在现实中,一个Number()对象被创建+存储,并且它的引用正在被比较。如果我们这样写的话,这就变得更明显了
var a = 5,
b = 7,
c = 10;
var container = [ ];
container.push( a );
container.push( b );
container.push( c );
container.indexOf( b );
Until this point, one could still easily argue that all .indexOf()
needs to do is to compare values, but now lets look at something like this:
在此之前,人们仍然可以很容易地认为.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 );
Here, we filled that container array with object-references and still, .indexOf()
works as expected
在这里,我们用对象引用填充了容器数组,并且.indexOf()仍然可以按预期工作
container.indexOf( b ) // === 1
while a call like this
而像这样的电话
container.indexOf({ name: 'b', value: 10 });
obviously returns -1
since we are creating a new object and get a new reference. So here it must internally compare references with each other, right?
显然返回-1,因为我们正在创建一个新对象并获得一个新的引用。这里它必须内部比较引用,对吧?
Can some ECMAscript spec genius confirm that or even better link me some material about that ?
一些ECMAscript规范天才可以确认或者更好的链接到我那里吗?
A side question on this would be if there is any possibly way to access an internally stored object-reference within a lexicalEnvironment respectively Activation Object.
另一个问题是,是否有可能在lexicalEnvironment中分别访问内部存储的对象引用。
3 个解决方案
#1
8
It boils down to indexOf()
comparing against each array property in turn using the same algorithm as the ===
operator.
它可以归结为indexOf()与每个数组属性进行比较,使用与==运算符相同的算法。
The relevant section of the ECMAScript 5 spec is section 15.4.4.14, step 9, section b (highlighting mine):
ECMAScript 5规范的相关章节是第15.4.4.14节,第9步,b节(突出显示我的):
If kPresent is true, then
如果kPresent是真的,那么
i. Let elementK be the result of calling the [[Get]] internal method of O with the argument ToString(k).
i.让elementK作为调用带有参数ToString(k)的O的[[[[Get]]内部方法的结果。
ii. Let same be the result of applying the Strict Equality Comparison Algorithm to searchElement and elementK.
二世。让同样的结果是将严格的相等比较算法应用到searchElement和elementK中。
iii. If same is true, return k.
三世。如果相同,返回k。
References:
引用:
- indexOf()
- indexOf()
- Strict Equality Comparison Algorithm
- 严格平等比较算法
#2
2
I'm not sure if this is guaranteed across all ECMAScript implementations or not, but the Mozilla documentation states that it uses strict equality to make the comparison (===). As such this would exhibit the behaviour you describe, comparing by values on primitives, but by reference on objects (see strict equality).
我不确定这是否在所有ECMAScript实现中得到保证,但是Mozilla文档声明它使用严格的等式来进行比较(==)。因此,这将显示您所描述的行为,通过对原语的值进行比较,但是通过对对象的引用(参见严格的平等)。
#3
0
@Tim Down is right. indexOf
does strict comparison. I am giving a demonstration of this by overriding valueOf
function
@Tim下来是对的。indexOf并严格的比较。我通过重写函数的值来演示这一点
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
#1
8
It boils down to indexOf()
comparing against each array property in turn using the same algorithm as the ===
operator.
它可以归结为indexOf()与每个数组属性进行比较,使用与==运算符相同的算法。
The relevant section of the ECMAScript 5 spec is section 15.4.4.14, step 9, section b (highlighting mine):
ECMAScript 5规范的相关章节是第15.4.4.14节,第9步,b节(突出显示我的):
If kPresent is true, then
如果kPresent是真的,那么
i. Let elementK be the result of calling the [[Get]] internal method of O with the argument ToString(k).
i.让elementK作为调用带有参数ToString(k)的O的[[[[Get]]内部方法的结果。
ii. Let same be the result of applying the Strict Equality Comparison Algorithm to searchElement and elementK.
二世。让同样的结果是将严格的相等比较算法应用到searchElement和elementK中。
iii. If same is true, return k.
三世。如果相同,返回k。
References:
引用:
- indexOf()
- indexOf()
- Strict Equality Comparison Algorithm
- 严格平等比较算法
#2
2
I'm not sure if this is guaranteed across all ECMAScript implementations or not, but the Mozilla documentation states that it uses strict equality to make the comparison (===). As such this would exhibit the behaviour you describe, comparing by values on primitives, but by reference on objects (see strict equality).
我不确定这是否在所有ECMAScript实现中得到保证,但是Mozilla文档声明它使用严格的等式来进行比较(==)。因此,这将显示您所描述的行为,通过对原语的值进行比较,但是通过对对象的引用(参见严格的平等)。
#3
0
@Tim Down is right. indexOf
does strict comparison. I am giving a demonstration of this by overriding valueOf
function
@Tim下来是对的。indexOf并严格的比较。我通过重写函数的值来演示这一点
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