Цитата:
|
Zeroglif, Dmitry A. Soshnikov, спасибо за объяснение.
Получается, что аксессор - это, в понимании интерпретатора, свойство с привязкой к своему контексту и если есть что-то, что заставляет прочитать это свойство (вызвать GetValue), то привязка к контексту теряется и это уже не аксессор? |
Цитата:
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)(); Надеюсь, всё, более-менее, понятно объяснил. Если есть вопросы, сразу спрашивай, чтобы, пока свежо, полностью понять и разобраться. |
Цитата:
Цитата:
|
Цитата:
Если obj.m, то это MemberExpression.Identifier. Соответственно, для m. Ещё, акксессор (чтобы не путать терминологию) - это выражение доступа к свойству - точка или квадратные скобки, но не сами свойства. Цитата:
Ситуация, когда базовым объектом будет является объект активации, может быть, например, при вызове вложенной функции внутри родительской функции: function foo() { function bar() { return this; } alert(bar()); // равносильно AO.bar() => null.bar(); => Global.bar(); } Декларации функций, переменные и формальные параметры - являются свойствами объекта активации. |
Цитата:
Цитата:
Цитата:
|
Цитата:
Цитата:
В alert-e всё ещё Reference Type, и только потом будет получено значение. Цитата:
Цитата:
А MemberExpression . Identifier, вычисляется по своему алгоритму, где будет отрезолвен MemberExpression (на этапе PrimaryExpression : Identifier), получено его значение, получено значение Identifier, которое эквивалентно <identifier-string>, и возвращено новое значение типа Reference c базой ToObject(значение MemberExpression) и именем свойства ToString(значение Identifier). Спасибо, что поправил ;) Это важные замечания. |
Цитата:
|
Riim,
1) Аксессор (доступ к свойству): выражение.выражение выражение[выражение] 2) Идентификатор: foo Только в этих двух случаях (про скобки и функции хоста опускаю) результатом вычисления выражения будет значение Reference Type. Для аксессора к тому же вообще не важно, что там стоит слева или справа от точки - литерал, идентификатор или сложное выражение, всё равно левая часть станет объектом, правая часть станет строкой. |
Цитата:
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). Цитата:
|
Часовой пояс GMT +3, время: 23:23. |