Левым операндом оператора = должно быть левостороннее выражение: переменная, элемент массива или свойство объекта. Правым операндом может быть любое значение любого типа. Значением оператора присваивания является значение правого операнда. Побочный эффект оператора = заключается в присваивании значения правого операнда переменной или свойству, указанному слева, так что при последующих обращениях к переменной или свойству будет получено это значение.
Чаще всего выражения присваивания используются как самостоятельные инструкции; тем не менее иногда можно увидеть, как выражение присваивания включается в более сложные выражения. Например, в одном выражении можно совместить операции присваивания и проверки значения:
(а = b) == 0
обычно бывает необходимо использовать круглые скобки, если выражение присваивания используется в составе более сложного выражения.
Оператор присваивания имеет ассоциативность справа налево, поэтому при наличии в выражении нескольких операторов присваивания они вычисляются справа налево. Благодаря этому можно написать код, присваивающий одно значение нескольким переменным, например:
i = j = к = 0; // Инициализировать 3 переменные значением 0
4.11.1. Присваивание с операцией
Помимо обычного оператора присваивания = в языке JavaScript поддерживается несколько других операторов, объединяющих присваивание с некоторой другой операцией. Например, оператор += выполняет сложение и присваивание. Следующее выражение:
total += sales_tax
эквивалентно выражению:
total = total + sales_tax
Как можно было ожидать, оператор += работает и с числами, и со строками. Для числовых операндов он выполняет сложение и присваивание, а для строковых -конкатенацию и присваивание.
Из подобных ему операторов можно назвать -=, *=, &= и др. Все операторы присваивания с операцией перечислены в табл. 4.2.
В большинстве случаев выражение:
а ор= b
где ор означает оператор, эквивалентно выражению:
а = a op b
В первой строке выражение а вычисляется только один раз. Во второй - дважды. Эти выражения отличаются, только если подвыражение а содержит операции, имеющие побочные эффекты, такие как вызов функции или оператор инкремента. Например, следующие два выражения присваивания неэквивалентны:
data[i++] *= 2;
data[i++] = data[i++] * 2;
4.12. Вычисление выражений
Подобно многим интерпретирующим языкам, JavaScript поддерживает возможность интерпретации строк с программным кодом на языке JavaScript, выполняя их, чтобы получить некоторое значение. В JavaScript эта операция выполняется с помощью глобальной функции eval():
eval("3+2") // => 5
Динамическое выполнение строк с программным кодом является мощной особенностью языка, которая практически никогда не требуется на практике. Если у вас появится желание использовать функцию eval(), задумайтесь - действительно ли это необходимо.
В подразделах ниже описываются основы использования функции eval() и затем рассказывается о двух ее ограниченных версиях, которые оказывают меньше влияния на оптимизатор.
eval() является функцией, но знакомство с ней включено в главу, описывающую операторы, потому что в действительности она должна была бы быть оператором. В самых ранних версиях языка eval() определялась как функция, но с тех пор проектировщики языка и разработчики интерпретаторов наложили на нее столько ограничений, что она стала больше похожа на оператор. Современные интерпретаторы JavaScript детально анализируют программный код и выполняют множество оптимизаций. Проблема функции eval() заключается в том, что программный код, который она выполняет, в целом не доступен для анализа. Вообще говоря, если функция вызывает eval(), интерпретатор не может оптимизировать эту функцию. Проблема с определением eval() как функции заключается в том, что ей можно присвоить другие имена:
var f = eval;
var g = f;