Показать сообщение отдельно
  #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.
Ответить с цитированием