Статьи

JavaScript Викторина № 5

Если вы еще не ознакомились с викторинами JavaScript 1, 2 , 3 и 4 , найдите время, чтобы посмотреть на них. Каждый строит на другом, и они становятся все сложнее. Посмотрите, действительно ли вы знаете свой порядок операций JavaScript.

var object1 = {
    valueOf: function () {
return 10;
    },
    toString: function () {
return "object1";
    }
};

var object2 = {
    valueOf: function () {
return 20;
    },
    toString: function () {
return "object2";
    }
};

var object3 = {
    valueOf: function () {
return 30;
    },
    toString: function () {
return "object3";
    }
};

var result = (object2, object1, object3) + object1 +-- object1; 
alert(result);

Вопрос : что выводит предупреждение и почему?

* Напишите свой ответ на листе бумаги, а затем прочитайте ответ. *

Ответ :

Вывод предупреждения 49 . Давайте проанализируем этот тест. В следующем выражении:

(object2, object1, object3)

Чтобы узнать результат этого выражения, мы должны знать, как выражения работают с оператором запятой. Если у нас есть выражение, которое содержит много операторов запятой, то это выражение будет оцениваться до последнего упомянутого значения. Это значит, что  (object2, object1, object3)будет оцениваться до object3. Тогда у нас будет следующее сокращенное выражение:

object3 + object1 +-- object1

В этом выражении у нас есть два основных оператора:
1. + оператор.
2. — префиксный оператор.

Порядок выполнения будет следующим:
1. — префиксный оператор.
2. + оператор.

Чтобы получить полный список приоритетов операторов, проверьте https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/Operator_Precedence .

Порядок выполнения означает, что оценка выражения начнется с:

-- object1

Будет применен оператор префикса, object1который вызовет valueOfметод object1. Это означает, что результат будет 10 — 1 = 9.

Затем выполнение оценки продолжается, добавляя object3 + object1к предыдущему результату следующее:

object3 + object1 + 9

Теперь мы подошли к самой простой части викторины, valueOfметоды object1и object3вызваны, что означает, что конечный результат будет 30 + 10 + 9 = 49.

Исходное правило сложения в соответствии со спецификацией Ecma-262 для справки выглядит следующим образом:
«Оператор сложения выполняет либо конкатенацию строк, либо числовое сложение.

Производство AdditiveExpression: AdditiveExpression + MultiplicativeExpression оценивается следующим образом:
1. Пусть lref будет результатом оценки AdditiveExpression.
2. Пусть lval будет GetValue (lref).
3. Пусть rref будет результатом вычисления MultiplicativeExpression.
4. Пусть rval будет GetValue (rref).
5. Пусть lprim будет ToPrimitive (lval).
6. Пусть rprim будет ToPrimitive (rval).
7. Если Тип (lprim) равен String или Тип (rprim) равен String, то
a. Вернуть строку, которая является результатом конкатенации ToString (lprim), за которой следует ToString (rprim)
8. Вернуть результат применения операции сложения к ToNumber (lprim) и ToNumber (rprim). »