Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #11 (permalink)  
Старый 01.11.2009, 15:13
Профессор
Отправить личное сообщение для Dmitry A. Soshnikov Посмотреть профиль Найти все сообщения от Dmitry A. Soshnikov
 
Регистрация: 25.02.2008
Сообщений: 707

Сообщение от Riim
разве у объектов есть scope? Он же у функций.
Scope - у контекстов, [[Scope]] - у функций.
__________________
Тонкости ECMAScript
Ответить с цитированием
  #12 (permalink)  
Старый 06.11.2009, 05:49
Аватар для Riim
Рассеянный профессор
Отправить личное сообщение для Riim Посмотреть профиль Найти все сообщения от Riim
 
Регистрация: 06.04.2009
Сообщений: 2,379

Zeroglif, Dmitry A. Soshnikov, спасибо за объяснение.
Получается, что аксессор - это, в понимании интерпретатора, свойство с привязкой к своему контексту и если есть что-то, что заставляет прочитать это свойство (вызвать GetValue), то привязка к контексту теряется и это уже не аксессор?
Ответить с цитированием
  #13 (permalink)  
Старый 06.11.2009, 11:38
Профессор
Отправить личное сообщение для Dmitry A. Soshnikov Посмотреть профиль Найти все сообщения от Dmitry A. Soshnikov
 
Регистрация: 25.02.2008
Сообщений: 707

Сообщение от Riim
свойство с привязкой к своему контексту
Не совсем. Псевдокодом, значение типа Reference Type можно представить в виде обычного объекта с двумя свойствами - база (base) (т.е. объект, которому принадлежит свойство) и имя свойства (property name) внутри базы:

var valueOfReferenceType = {
  base: <базовый объект>,
  propertyName: <имя свойства>
};


Далее, если мы имеем в коде обращение к переменной, в силу вступает алгоритм (и механизм) разрешения имени идентификатора (этой переменной):

var foo = 10;
alert(foo);


На выходе алгоритма разрешения имени - всегда значение типа Reference Type. Т.е. для нашей переменной foo, результатом разрешения имени будет:

var fooReference = {
  base: Global, // т.к. foo - в глобальном объекте
  propertyName: "foo"
};


Главным моментом разрешения имени является именно тот факт, что возвращается объект типа Reference Type, т.е. без получения значения этой переменной. Иными словами, если мы пишем код:

foo;


Мы получаем "на выходе" - fooRef.

И только затем (в примере выше), когда вызывается alert, уже вызывается метод GetValue для fooRef.

GetValue вернёт уже значение другого типа (в данном случае Number - 10), но не значение ReferenceType.

Псевдокод алгоритма GetValue:

function GetValue(fooReference) {
  var base = GetBase(fooReference); // Global
  return base.[[Get]](GetPropertyName(fooReference)); // 10
}


Так вот, главный момент, касающийся вызова функции - выражение вызова ожидает слева (от скобок вызова) значение типа Reference Type. Если это так, то в качестве this-value будет база этого значения:

// в первых скобках - значение типа
// Reference Type, т.к. сработал алгоритм
// разрешения имён идентификаторов,
// базой является obj, именно он будет передан
// в качестве this-value
(obj.m)();


Если же слева стоит значение не Reference Type (т.е. любого другого типа), то в качестве this-value будет null. Исключение составляет лишь объект активации: в том случае, когда он является базой, также подставляется null.

Повторю, что оператор присваивания вызывает GetValue, и, соответственно, на выходе мы получаем значение типа Object, а не Reference Type:

// this-value будет null
(obj.m = obj.m)();


Надеюсь, всё, более-менее, понятно объяснил. Если есть вопросы, сразу спрашивай, чтобы, пока свежо, полностью понять и разобраться.
__________________
Тонкости ECMAScript

Последний раз редактировалось Dmitry A. Soshnikov, 06.11.2009 в 11:41.
Ответить с цитированием
  #14 (permalink)  
Старый 06.11.2009, 12:48
Аватар для Riim
Рассеянный профессор
Отправить личное сообщение для Riim Посмотреть профиль Найти все сообщения от Riim
 
Регистрация: 06.04.2009
Сообщений: 2,379

Сообщение от Dmitry A. Soshnikov
в силу вступает алгоритм (и механизм) разрешения имени идентификатора
Как это для аксессора формулируется? "Алгоритм разрешения имени идентификатора который в аксессоре", или "Алгоритм разрешения аксессора", или еще как-то?

Сообщение от Dmitry A. Soshnikov
объект активации
А кто это?
Ответить с цитированием
  #15 (permalink)  
Старый 06.11.2009, 13:13
Профессор
Отправить личное сообщение для Dmitry A. Soshnikov Посмотреть профиль Найти все сообщения от Dmitry A. Soshnikov
 
Регистрация: 25.02.2008
Сообщений: 707

Сообщение от Riim
Как это для аксессора формулируется? "Алгоритм разрешения имени идентификатора который в аксессоре", или "Алгоритм разрешения аксессора", или еще как-то?
Если стоит просто obj, то - это MemberExpression -> PrimaryExpression -> Identifier. Соответственно, разрешение имени получается для obj.

Если obj.m, то это MemberExpression.Identifier. Соответственно, для m.

Ещё, акксессор (чтобы не путать терминологию) - это выражение доступа к свойству - точка или квадратные скобки, но не сами свойства.

Сообщение от Riim
А кто это?
Объект активации.

Ситуация, когда базовым объектом будет является объект активации, может быть, например, при вызове вложенной функции внутри родительской функции:

function foo() {
  function bar() { return this; }
  alert(bar()); // равносильно AO.bar() => null.bar(); => Global.bar();
}


Декларации функций, переменные и формальные параметры - являются свойствами объекта активации.
__________________
Тонкости ECMAScript
Ответить с цитированием
  #16 (permalink)  
Старый 06.11.2009, 16:28
...
Отправить личное сообщение для Zeroglif Посмотреть профиль Найти все сообщения от Zeroglif
 
Регистрация: 09.03.2008
Сообщений: 216

Сообщение от Dmitry A. Soshnikov
Мы получаем "на выходе" - fooRef.
На выходе будет значение переменной, т.к. это экспрешн стэйтмент. Ты если про алерт пишешь, то вытаскивать выражение из вызова алерта нельзя, иначе получим значение.

Сообщение от Dmitry A. Soshnikov
выражение вызова ожидает слева (от скобок вызова) значение типа Reference Type
Точнее ожидает объект, ещё точнее ожидает callable объект, иначе ошибка. Какое именно выражение стоит слева и будет ли оно вычислено в значение Reference Type это как бы важно только с точки зрения 'this'.

Сообщение от Dmitry A. Soshnikov
Если obj.m, то это MemberExpression.Identifier. Соответственно, для m
Неа, резолвится левая часть и то, если там идентификатор только.
Ответить с цитированием
  #17 (permalink)  
Старый 06.11.2009, 17:18
Профессор
Отправить личное сообщение для Dmitry A. Soshnikov Посмотреть профиль Найти все сообщения от Dmitry A. Soshnikov
 
Регистрация: 25.02.2008
Сообщений: 707

Сообщение от Zeroglif
На выходе будет значение переменной, т.к. это экспрешн стэйтмент. Ты если про алерт пишешь, то вытаскивать выражение из вызова алерта нельзя, иначе получим значение.
Ай, не доглядел, действительно:

Сообщение от ECMA-262-3 12.4. Expression Statement
1. Evaluate Expression.
2. Call GetValue(Result(1)).
Но, я хотел показать основную идею - промежуточного значения типа Reference; пример ошибочный был, да.

В alert-e всё ещё Reference Type, и только потом будет получено значение.

Сообщение от Zeroglif
Точнее ожидает объект, ещё точнее ожидает callable объект, иначе ошибка. Какое именно выражение стоит слева и будет ли оно вычислено в значение Reference Type это как бы важно только с точки зрения 'this'.
Ну да, если более точно, то так, конечно.

Сообщение от Zeroglif
Неа, резолвится левая часть и то, если там идентификатор только.
Да, и вправду, тоже ошибся. Только PrimaryExpression : Identifier резолвится.

А MemberExpression . Identifier, вычисляется по своему алгоритму, где будет отрезолвен MemberExpression (на этапе PrimaryExpression : Identifier), получено его значение, получено значение Identifier, которое эквивалентно <identifier-string>, и возвращено новое значение типа Reference c базой ToObject(значение MemberExpression) и именем свойства ToString(значение Identifier).

Спасибо, что поправил Это важные замечания.
__________________
Тонкости ECMAScript

Последний раз редактировалось Dmitry A. Soshnikov, 06.11.2009 в 20:14.
Ответить с цитированием
  #18 (permalink)  
Старый 07.11.2009, 03:27
Аватар для Riim
Рассеянный профессор
Отправить личное сообщение для Riim Посмотреть профиль Найти все сообщения от Riim
 
Регистрация: 06.04.2009
Сообщений: 2,379

Сообщение от Dmitry A. Soshnikov
А MemberExpression . Identifier, вычисляется по своему алгоритму, где будет отрезолвен MemberExpression (на этапе PrimaryExpression : Identifier), получено его значение, получено значение Identifier, которое эквивалентно <identifier-string>, и возвращено новое значение типа Reference c базой ToObject(значение MemberExpression) и именем свойства ToString(значение Identifier).
т. е. сначала создается ReferenceType для obj, а потом второй ReferenceType для m из obj.m , при этом для создания второго ReferenceType нужно вызвать GetValue у первого?
Ответить с цитированием
  #19 (permalink)  
Старый 07.11.2009, 11:46
...
Отправить личное сообщение для Zeroglif Посмотреть профиль Найти все сообщения от Zeroglif
 
Регистрация: 09.03.2008
Сообщений: 216

Riim,

1) Аксессор (доступ к свойству):

выражение.выражение
выражение[выражение]

2) Идентификатор:

foo

Только в этих двух случаях (про скобки и функции хоста опускаю) результатом вычисления выражения будет значение Reference Type. Для аксессора к тому же вообще не важно, что там стоит слева или справа от точки - литерал, идентификатор или сложное выражение, всё равно левая часть станет объектом, правая часть станет строкой.
Ответить с цитированием
  #20 (permalink)  
Старый 07.11.2009, 12:42
Профессор
Отправить личное сообщение для Dmitry A. Soshnikov Посмотреть профиль Найти все сообщения от Dmitry A. Soshnikov
 
Регистрация: 25.02.2008
Сообщений: 707

Сообщение от Riim
т. е. сначала создается ReferenceType для obj, а потом второй ReferenceType для m из obj.m , при этом для создания второго ReferenceType нужно вызвать GetValue у первого?
Давай посмотрим алгоритм:

MemberExpression . Identifier

// получаем значение Reference Type для MemberExpression
1. Evaluate MemberExpression.

// получаем значение Result(1)
2. Call GetValue(Result(1)).

// вычисляем выражение для Expression,
// в нашем случае - для Identifier
// это может быть просто строка,
// идентификатор, который преобразуется
// в строку или выражение
3. Evaluate Expression.

// получаем значение, если у нас просто
// строка - она и вернётся из GetValue
4. Call GetValue(Result(3)).

// преобразование к объекту значения MemberExpression
5. Call ToObject(Result(2)).

// преобразование к строке значения Identifier
// в нашем случае ничего не меняется
6. Call ToString(Result(4)).

// возвращаем новое значение типа Reference
// c базой MemberExpression и именем свойства Identifier
// с учётом предыдущих преобразований
7. Return a value of type Reference whose base object is Result(5) and whose property name is
Result(6).


Сообщение от Zeroglif
(про скобки и функции хоста опускаю)
А что там за случаи?
__________________
Тонкости ECMAScript

Последний раз редактировалось Dmitry A. Soshnikov, 07.11.2009 в 12:45.
Ответить с цитированием
Ответ


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

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


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Помогите с javascript andruhin Общие вопросы Javascript 12 04.05.2012 10:05
Собрался силами, собираюсь освоить Javascript walker Общие вопросы Javascript 14 20.03.2012 16:17
JavaScript на Яндекс.Фотки - почему тормозит браузеры? ZavFirefox Javascript под браузер 23 27.09.2009 19:24
Программист на JavaScript (удалённо) Vadym Работа 1 28.01.2009 13:57
Нужен Старший разработчик JavaScript Yandex Работа 17 19.08.2008 16:43