14.07.2012, 16:44
|
Интересующийся
|
|
Регистрация: 14.07.2011
Сообщений: 26
|
|
Почему оператор ++ генерирует искючение, а не NaN в случае со строкой?
Почему код:
alert('d'++);
генерирует ошибку, а не выводит значение NaN?
|
|
14.07.2012, 16:47
|
|
сегодня в 12:34|Комментир
|
|
Регистрация: 12.04.2011
Сообщений: 1,180
|
|
dump,
потому что не совмещение типов вроде.
Другие знаки приводят операнды к одному типу:
alert('a' + 1)
alert('a' * 1)
alert('a' - 1)
alert('a' / 1)
__________________
оляля, ололо
|
|
14.07.2012, 18:25
|
Профессор
|
|
Регистрация: 31.05.2012
Сообщений: 396
|
|
Сообщение от 9xakep
|
dump,
потому что не совмещение типов вроде.
Другие знаки приводят операнды к одному типу:
|
Ответ неверный. Операнд оператора ++ должен быть такой, который может стоять в левой части присваивания, то есть либо переменной, либо свойством объекта. У вас там строка, поэтому генерируется SyntaxError.
Этот код работает:
var a='d';
alert(a++); //NaN
|
|
15.07.2012, 17:57
|
|
Профессор
|
|
Регистрация: 22.03.2012
Сообщений: 3,744
|
|
Сообщение от oneguy
|
Ответ неверный. Операнд оператора ++ должен быть такой, который может стоять в левой части присваивания, то есть либо переменной, либо свойством объекта. У вас там строка, поэтому генерируется SyntaxError.
|
Можно пояснить, как получить такой вывод из спецификации
http://es5.javascript.ru/x11.html#x11.3.1
Цитата:
|
11.3.1 Постфиксный оператор инкремента # Ⓣ Ⓡ Ⓖ
Для вычисления PostfixExpression : LeftHandSideExpression [no LineTerminator here] ++ выполняются следующие шаги:
Пусть lhs будет результатом вычисления LeftHandSideExpression Левостороннее выражение.
Сгенерировать исключение SyntaxError, если все следующие условия являются истинными:
Type(lhs) равно Reference равно true
IsStrictReference(lhs) равно true
Type(GetBase(lhs)) равно Environment Record
GetReferencedName(lhs) равно либо "eval", либо "arguments"
Пусть oldValue Старое значение будет ToNumber(GetValue(lhs)).
Пусть newValue Новое значение будет результатом прибавления значения 1 к значению oldValue, с применением таких же правил, что и для оператора + (см. пункт. 11.6.3).
Вызвать PutValue(lhs, newValue).
Вернуть oldValue.
|
|
|
15.07.2012, 21:40
|
Профессор
|
|
Регистрация: 31.05.2012
Сообщений: 396
|
|
Сообщение от bes
|
Можно пояснить, как получить такой вывод из спецификации
|
При вычислении LeftHandSideExpression [no LineTerminator here] ++ одним из шагом вычисляется PutValue(lhs, newValue). Операция PutValue кидает ReferenceError, если тип первого операнда не Reference.
Дальше читаем: http://es5.javascript.ru/x16.html#x16
Цитата:
|
Реализация должна рассматривать все случаи следующих ошибок как раннюю ошибку:
...
Попытки вызвать PutValue для значения, по которому можно заранее определить, что оно не является Reference (например, при выполнении инструкции присваивания 3=4).
|
В данном случае в выражении 'd'++ PutValue должен вызываться для значения выражения 'd', а строковый литерал никогда не возвращает Reference, поэтому интерпретатор при этом сообщает о ранней ошибке.
|
|
15.07.2012, 22:11
|
|
Профессор
|
|
Регистрация: 22.03.2012
Сообщений: 3,744
|
|
Спасибо за пояснение, то есть ошибка возникает не из этих пунктов
Цитата:
|
Сгенерировать исключение SyntaxError, если все следующие условия являются истинными:
Type(lhs) равно Reference равно true
IsStrictReference(lhs) равно true
Type(GetBase(lhs)) равно Environment Record
GetReferencedName(lhs) равно либо "eval", либо "arguments"
|
а как результат предпоследнего шага
Цитата:
|
Вызвать PutValue(lhs, newValue).
|
Сообщение от oneguy
|
а строковый литерал никогда не возвращает Reference
|
Почитав про reference http://es5.javascript.ru/x8.html#x8.7 не пойму, что и когда является reference (это нечто предопределённое или нет)
(исходя из приведённых пояснений, если бы строковый литерал был ссылкой, тогда ошибка возникла бы ещё на пункте
Цитата:
|
Type(lhs) равно Reference равно true
|
)
|
|
15.07.2012, 23:06
|
Профессор
|
|
Регистрация: 31.05.2012
Сообщений: 396
|
|
Reference - это тип данных, который используется для вычисления выражений. Например, как объяснить вычисление выражения delete object.method ? Что нужно взять от object.method и передать оператору delete?
Цитата:
|
(исходя из приведённых пояснений, если бы строковый литерал был ссылкой, тогда ошибка возникла бы ещё на пункте
Цитата:
Type(lhs) равно Reference равно true
)
|
Не совсем понял. Объясните, пожалуйста, поконкретнее, что значит "если бы строковый литерал был ссылкой".
|
|
15.07.2012, 23:28
|
|
Профессор
|
|
Регистрация: 22.03.2012
Сообщений: 3,744
|
|
Сообщение от oneguy
|
Не совсем понял. Объясните, пожалуйста, поконкретнее, что значит "если бы строковый литерал был ссылкой".
|
Цитата:
|
Сгенерировать исключение SyntaxError, если все следующие условия являются истинными:
Type(lhs) равно Reference равно true
|
если тип операнда слева - ссылочный, генерировать исключение (так как литерал не ссылочного типа, поэтому не генерировать)
Сообщение от oneguy
|
Reference - это тип данных, который используется для вычисления выражений. Например, как объяснить вычисление выражения delete object.method ? Что нужно взять от object.method и передать оператору delete?
|
передаётся ссылка на метод, как я понимаю
хотелось бы понять, как по спецификации определить, что ссылочного типа, что нет (где-то это должно быть в спецификации обозначено, а в http://es5.javascript.ru/x8.html#x8.7 не совсем понятно об этом написано)
|
|
16.07.2012, 02:09
|
Профессор
|
|
Регистрация: 31.05.2012
Сообщений: 396
|
|
Сообщение от bes
|
если тип операнда слева - ссылочный, генерировать исключение
|
Не так. В спецификации написано, что генерировать исключение, если выполняются все 4 условия одновременно:
Type(lhs) равно Reference равно true
IsStrictReference(lhs) равно true
Type(GetBase(lhs)) равно Environment Record
GetReferencedName(lhs) равно либо "eval", либо "arguments"
Цитата:
|
хотелось бы понять, как по спецификации определить, что ссылочного типа, что нет (где-то это должно быть в спецификации обозначено, а в http://es5.javascript.ru/x8.html#x8.7 не совсем понятно об этом написано)
|
Не понял вопрос. Объясните поподробнее, пожалуйста, что определить, как и при каких условиях.
|
|
16.07.2012, 09:57
|
|
Профессор
|
|
Регистрация: 22.03.2012
Сообщений: 3,744
|
|
Сообщение от oneguy
|
Не так. В спецификации написано, что генерировать исключение, если выполняются все 4 условия одновременно:
|
Да, здесь я блажанул
Сообщение от oneguy
|
Не понял вопрос. Объясните поподробнее, пожалуйста, что определить, как и при каких условиях.
|
Вопрос в том как определять, какие типы можно отнести к типу Reference, а какие нет.
Алгоритм выполняется последовательно, поэтому пытаемся разобрать фразу Type(lhs) равно Reference равно true:
Type(lhs)
Цитата:
|
В тексте данной спецификации выражение "Type(x)" используется в качестве сокращения для фразы "тип, к которому относится x", где "тип" означает языковой тип и тип спецификации, описываемые в данной главе.
|
то есть определяется тип левостороннего выражения
далее этот тип сравнивается с типом Reference
собственно о Reference http://es5.javascript.ru/x8.html#x8.7
Цитата:
|
8.7 Тип спецификации Reference # Ⓣ
Тип Reference Cсылка используется, чтобы объяснить поведение операторов delete и typeof и операторов присваивания. Например, можно сказать, что "левосторонний операнд присваивания создаёт ссылку". Поведение операторов присваивания можно также объяснить и анализом синтаксической формы левостороннего оператора. Но здесь есть одна сложность: вызовы функции могут возвращать ссылки. Правда, эта возможность применима только к объектам среды: возврат ссылки не предусмотрен ни для функций ECMAScript, определяемых данной спецификацией, ни для функций, определяемых пользователем. (Еще один довод против синтаксического анализа заключается в том, что это было бы долго и неудобно, и затрагивало бы многие части спецификации.)
Reference является предвычисленной resolved привязкой имени. Ссылка состоит из трех компонентов: значения базы base value, имени по ссылке referenced name, и флага строгой ссылки strict reference с булевым значением. Значение базы – это undefined, Object, Boolean, String, Number, или запись окружения (10.2.1). Если значение базы – undefined, это означает, что значение по ссылке не удалось вычислить. Имя по ссылке – это строка.
Для доступа к компонентам ссылок в данной спецификации используются следующие абстрактные операции:
GetBase(V) Получить базу(V). Возвращает компонент со значением базы ссылки V.
GetReferencedName(V) Получить имя по ссылке(V). Возвращает компонент имени по ссылке для ссылки V.
IsStrictReference(V) Является строгой ссылкой(V). Возвращает компонент строгой ссылки для ссылки V.
HasPrimitiveBase(V) Имеет примитивную базу(V). Возвращает true, если значение базы – Boolean, String или Number.
IsPropertyReference(V) Является ссылкой на свойство(V). Возвращает true, если либо значение базы является объектом, либо HasPrimitiveBase(V) – true; в противном случае возвращает false.
IsUnresolvableReference(V) Является неразрешимой ссылкой(V). Возвращает true, если значение базы – undefined, в противном случае возвращает false.
/////Далее описывается алгоритм работы getValue и putValue.
|
На какой основе понять, что полученный тип Type(lhs) равен или не равен типу Reference, собственно из того, что здесь приведено у меня пока не получается сделать такой вывод.
|
|
|
|