Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 14.07.2012, 16:44
Интересующийся
Отправить личное сообщение для dump Посмотреть профиль Найти все сообщения от dump
 
Регистрация: 14.07.2011
Сообщений: 26

Почему оператор ++ генерирует искючение, а не NaN в случае со строкой?
Почему код:

alert('d'++);

генерирует ошибку, а не выводит значение NaN?
Ответить с цитированием
  #2 (permalink)  
Старый 14.07.2012, 16:47
Аватар для 9xakep
сегодня в 12:34|Комментир
Отправить личное сообщение для 9xakep Посмотреть профиль Найти все сообщения от 9xakep
 
Регистрация: 12.04.2011
Сообщений: 1,180

dump,
потому что не совмещение типов вроде.
Другие знаки приводят операнды к одному типу:
alert('a' + 1)
alert('a' * 1)
alert('a' - 1)
alert('a' / 1)
__________________
оляля, ололо
Ответить с цитированием
  #3 (permalink)  
Старый 14.07.2012, 18:25
Профессор
Отправить личное сообщение для oneguy Посмотреть профиль Найти все сообщения от oneguy
 
Регистрация: 31.05.2012
Сообщений: 396

Сообщение от 9xakep
dump,
потому что не совмещение типов вроде.
Другие знаки приводят операнды к одному типу:
Ответ неверный. Операнд оператора ++ должен быть такой, который может стоять в левой части присваивания, то есть либо переменной, либо свойством объекта. У вас там строка, поэтому генерируется SyntaxError.
Этот код работает:
var a='d';
alert(a++); //NaN
Ответить с цитированием
  #4 (permalink)  
Старый 15.07.2012, 17:57
Аватар для bes
bes bes вне форума
Профессор
Отправить личное сообщение для bes Посмотреть профиль Найти все сообщения от bes
 
Регистрация: 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.
Ответить с цитированием
  #5 (permalink)  
Старый 15.07.2012, 21:40
Профессор
Отправить личное сообщение для oneguy Посмотреть профиль Найти все сообщения от oneguy
 
Регистрация: 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, поэтому интерпретатор при этом сообщает о ранней ошибке.
Ответить с цитированием
  #6 (permalink)  
Старый 15.07.2012, 22:11
Аватар для bes
bes bes вне форума
Профессор
Отправить личное сообщение для bes Посмотреть профиль Найти все сообщения от bes
 
Регистрация: 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
)
Ответить с цитированием
  #7 (permalink)  
Старый 15.07.2012, 23:06
Профессор
Отправить личное сообщение для oneguy Посмотреть профиль Найти все сообщения от oneguy
 
Регистрация: 31.05.2012
Сообщений: 396

Сообщение от bes
Почитав про reference http://es5.javascript.ru/x8.html#x8.7 не пойму, что и когда является reference (это нечто предопределённое или нет)
Reference - это тип данных, который используется для вычисления выражений. Например, как объяснить вычисление выражения delete object.method ? Что нужно взять от object.method и передать оператору delete?
Цитата:
(исходя из приведённых пояснений, если бы строковый литерал был ссылкой, тогда ошибка возникла бы ещё на пункте
Цитата:
Type(lhs) равно Reference равно true
)
Не совсем понял. Объясните, пожалуйста, поконкретнее, что значит "если бы строковый литерал был ссылкой".
Ответить с цитированием
  #8 (permalink)  
Старый 15.07.2012, 23:28
Аватар для bes
bes bes вне форума
Профессор
Отправить личное сообщение для bes Посмотреть профиль Найти все сообщения от bes
 
Регистрация: 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 не совсем понятно об этом написано)
Ответить с цитированием
  #9 (permalink)  
Старый 16.07.2012, 02:09
Профессор
Отправить личное сообщение для oneguy Посмотреть профиль Найти все сообщения от oneguy
 
Регистрация: 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 не совсем понятно об этом написано)
Не понял вопрос. Объясните поподробнее, пожалуйста, что определить, как и при каких условиях.
Ответить с цитированием
  #10 (permalink)  
Старый 16.07.2012, 09:57
Аватар для bes
bes bes вне форума
Профессор
Отправить личное сообщение для bes Посмотреть профиль Найти все сообщения от bes
 
Регистрация: 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, собственно из того, что здесь приведено у меня пока не получается сделать такой вывод.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск