Сообщение от 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)();
Надеюсь, всё, более-менее, понятно объяснил. Если есть вопросы, сразу спрашивай, чтобы, пока свежо, полностью понять и разобраться.