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

Почему Javascript "in" оператор последовательно медленнее, чем строгий элемент сравнения с undefined?

См. http://jsperf.com/in-vs-member-object-access

По существу, почему проверка if ('bar' in foo) {} значительно медленнее, чем if (foo.bar !== undefined) {}?

4b9b3361

Ответ 1

foo.bar !== undefined проверяет только те 2 значения, чтобы увидеть, соответствуют ли они.

В то время как 'bar' in foo должен будет использовать какой-либо механизм для прокрутки свойств foo, чтобы увидеть, есть ли в нем bar.

Вот интересный Чтение из Ecma- script

Оператор in

Произведение RelationalExpression: RelationalExpression в ShiftExpression оценивается следующим образом:
1. Оцените реляционное выражение.
2. Вызовите GetValue (Результат (1)).
3. Оцените выражение Shift.
4. Вызовите GetValue (Результат (3)).
5. Если Result (4) не является объектом, вызовите исключение TypeError.
6. Вызов ToString (Результат (2)).
7. Вызвать метод [[HasProperty]] результата (4) с параметром Результат (6).
8. Результат возврата (7).

Оператор Strict Does-not-equal (! ==)

Производство EqualityExpression: EqualityExpression! == RelationalExpression оценивается следующим образом:
1. Оцените выражение равенства.
2. Вызовите GetValue (Результат (1)).
3. Оценка RelationalExpression.
4. Вызовите GetValue (Результат (3)).
5. Выполните сравнение Результат (4) === Результат (2). (См. Ниже).
6. Если Result (5) истинно, верните false. В противном случае верните true.

Ответ 2

Ты прав. Для "bar" in foo нет смысла быть медленнее, чем foo.bar.

Единственная причина in не так быстро, так это то, что он не получал столько внимания от инженеров JIT, сколько гораздо более общий синтаксис foo.bar.

Особенно в случае вашего теста jsperf, где свойство существует как прямое свойство непосредственно в foo (а не прототипе), понятно, что 'bar' in foo не должно быть медленнее, чем foo.bar !== undefined, Во всяком случае, это должно быть быстрее. Основное различие между ними состоит в том, что на in можно ответить, даже не проверяя значение свойства!

В случае foo.bar я ожидаю, что как двигатель V8, так и движок SpiderMonkey обнаружат, что код не делает ничего полезного (то есть он не имеет наблюдаемых эффектов) и полностью оптимизирует его. Тест не измеряет никакой реальной работы.

По-видимому, двигатели еще недостаточно умны, чтобы оптимизировать "bar" in foo, но это всего лишь вопрос времени. И приоритеты.