Подтвердить что ты не робот

Как Javascript indexOf() разрешает ссылки

Я немного смутил себя мысленным экспериментом, и теперь я ищу совет. Его ссылки на 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 соответственно.

4b9b3361

Ответ 1

Это сводится к indexOf() сравнению по сравнению с каждым свойством массива, в свою очередь, с использованием того же алгоритма, что и оператор ===.

Соответствующий раздел спецификации ECMAScript 5 - это раздел 15.4.4.14, этап 9, раздел b (выделение мин):

Если kPresent истинно, то

я. Пусть elementK является результатом вызова внутреннего метода [[Get]] O с аргументом ToString (k).

     

II. Пусть это будет результат применения алгоритма сравнения Strict Equality Comparison Algorithm для поискаElement и elementK.

     

III. Если это верно, верните k.

Литература:

Ответ 2

Я не уверен, что это гарантировано во всех реализациях ECMAScript или нет, но в документации Mozilla говорится, что он использует строгое равенство, чтобы сделать сравнение (===). Таким образом, это проявляет поведение, которое вы описываете, сравнивая значения по примитивам, но ссылаясь на объекты (см. строгое равенство).

Ответ 3

@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