Контексты, this, объекты и функции

Это особенность функций и объектной модели JS - методов не существует.
Как минимум, ************ различает то, каким образом вызывается функция – как метод какого-либо объекта или нет:JS CallFunction JS CallFunctionName JS CallFunctionValue
Любая функция вызывается в контексте некоторого объекта, где this будет указывать на этот объект...
Сколько ни старался, но так и не смог найти (там, у них) такого определения, как "вызов функции в контексте объекта". Все, что попадается, выглядит совсем иначе:
The "current" object on which the function operates; the object specified here is "this" when the function executes....The object on which to call a method. If a method is found and called, obj is passed to it as this.
Т.е. или "функция вызывается на каком-то объекте", или "объект, на котором вызывается метод". Вообще, упрощенно, на js вызов метода выглядит (как мне представляется на сегодняшний день) вот так:
obj.method(argsList) => method.apply(obj, argsList);
Да и в ECMAScript Language Specification оно именно так и выглядит:
11.2.3 Function Calls:...8. Call the [[Call]] method on Result(3), providing Result(7) as the this value and providing the list Result(2) as the argument values.
, где Result(3) - это js-значение (Function object), а Result(7) - это тот самый объект (а может быть и null), на котором вызвана функция.
...но какой-либо жёсткой привязки к этому объекту нет.
Да куда уж жестче, если значение this уже не изменить? И определено оно будет еще до вызова.
JS_CallFunction calls a specified function, <i>fun</i>, on an object, <i>obj</i>. In terms of function execution, the object is treated as this....JS_CallFunctionValue executes a function referenced by a jsval, <i>fval</i>, on an object, <i>obj</i>. In terms of function execution, the object is treated as this....JS_CallFunctionName executes a function-valued property, <i>name</i>, belonging to a specified JS object, <i>obj</i>.
14 ответов

а что такое _this?
Просто переменная, где то выше инициализированная.
Как минимум, ************ различает то, каким образом вызывается функция – как метод какого-либо объекта или нет:
Детали реализации. Различий как между вызовами как "метод" или "просто функция" - нет, это всегда "как метод", всегда передаётся на ком вызвали. Три нативных функции это разный способ достать JS функцию - либо поиск функции по имени, либо уже готовый объект функции, либо обёрнутый в ссылку. В реализации на Haskell к примеру это будет одна функция, правда при компиляции тоже сделает тучу вариантов (скрыто от тебя). Хотя по моему уже была дискуссия, где выявилось что ECMA разделяет декларации функций 
function name() {...
и функции-closure как значения
var name = function() {...
Что то было связанно с видимостью функций, если вложить их в глубину на много уровней. На практике различий не встречал.
Сколько ни старался, но так и не смог найти (там, у них) такого определения, как "вызов функции в контексте объекта".
Ты привёл пример синтаксиса (как написать), я говорю о семантике (что означает). Передача функции объекта, на котором вызвали функцию == "вызвать функцию в контексте объекта". По крайней мере мы так среди своих в универе говорим, не формально 
Да куда уж жестче, если значение this уже не изменить? И определено оно будет еще до вызова.
Опять детали реализации. Не важно как интерпретатор получит ссылку на объект, будет ли искать его постоянно или положит на стек - для тебя, в синтаксисе (в тексте) всё одно. Да, когда встретим:
my_obj.method();//интерпретатор сделает подобное:/*js_object = lookup(local_context, 'my_obj');js_func = lookup(js_object, 'method');//+ аргументы подобным образомjs_result = js_callFunction(js_func, js_object, js_args);*/
Где объект функции держит свой local_context где она была определена, который отведён от боле верхнего до global (здесь global - объект из ECMA, в JS это window). Можно усложнить, можно упростить, зависит от языка и требований (thread-safe к примеру). К самому JS это отношения не имеет, функция всегда вызывается на каком то объекте, где global.func(); и func(); идентичны. Функция не имеет привязки к объекту на подобии
var a = some_object.method;a(); //ожидаем что вызвали some_object.method(), но вызывается some_object.method.apply(global, arguments)//а всё, потому что функция может принадлежать к множеству объектов, нет не являясь частью прототипа,//а реально быть присвоена к множеству объектов. В конце концов "определение метода" в JS ничего более//чем создание новой переменной this.method и присвоения ей значения-функции.//имея такую функцию на руках узнать к какому (каким) объектам она принадлежит не возможно


Передача функции объекта, на котором вызвали функцию == "вызвать функцию в контексте объекта". 
Опять то же самое. Я ведь о том и пишу, что нет никакой "передачи объекта функции". Если говорить о контексте, в котором вызывается функция, то это execution context (глобальный контекст, локальный контекст или еще бог знает какой), представляющий собой сложный набор данных. Ни о каком контексте объекта, на котором вызвана функция (метод), эта функция понятия не имеет. Она лишь будет иметь в своем распоряжении значение (то самое значение, указывающее на объект) для this keyword, которое будет определено еще до начала выполнения функции.
По крайней мере мы так среди своих в универе говорим, не формально smile
В универе – это одно, а здесь в результате мы видим то, что ни в ECMAScript Language, ни где-то поблизости днем с огнем не найти (я имею ввиду такой термин, как slot, например):
...возвращает функцию в slot'е refresh объекта _this.
Приходится ломать голову над трактовкой – то ли это что-то новенькое в ES, то ли это метафора, то ли речь идет об адресации к динамической памяти (к которой сам ES вообще никакого отношения не имеет).
...объект функции держит свой local_context где она была определена, который отведён от боле верхнего до global
Сам context она не держит. Как я уже писал, контекст – это многогранная информация, которой нет места в scope chain. Если представить это так, как определено в спецификации языка, то в [[Scope]] property функции должна быть цепочка, состоящая из activation objects окружения, в котором функция была создана (там же могут оказаться те, что были добавлены усилиями with или catch). И никакого "своего local_context, где она была определена".Взять хотя бы this value, ассоциирующееся с выполняемым контекстом. Этого значения нет и быть не может в [[Scope]] property функции.
здесь global - объект из ECMA, в JS это window
window === global:
ECMAScript Language Specification:10.1.5 Global Object... in the HTML document object model the window property of the global object is the global object itself.
Более того, global object может быть доступен благодаря this keyword в глобальном контексте. С помощью того же this объект global можно заполучить в любом другом контексте таким образом:
var global = function () { return this; }();
...функция всегда вызывается на каком то объекте, где global.func(); и func(); идентичны. 
Отнюдь нет. Во втором случае идентификатор func может оказаться методом любого объекта из scope chain активного контекста выполнения, и им может оказаться вовсе не global.
Функция не имеет привязки к объекту на подобии
Речь о привязке к объекту шла совсем в ином контексте (в другом смысле):
Любая функция вызывается в контексте некоторого объекта, где this будет указывать на этот объект, но какой-либо жёсткой привязки к этому объекту нет.
Т.е речь шла непосредственно о вызове на некотором объекте, и тут уж привязка достаточно жесткая.


AKS, может ну его к черту этого сферического коня в вакууме? Семантика, предложенная Sardar, вполне оправданна и помогает понять суть. К чему эти высокофилософские споры?


smartov, не мешай, я только попкорн принёс и уселся поудобней...   


AKS, может ну его к черту этого сферического коня в вакууме? Семантика, предложенная Sardar, вполне оправданна и помогает понять суть. К чему эти высокофилософские споры? 
Не надо, так не надо. Я не спорить хотел, а выяснить то, как ближе к "телу". Я ведь на 100% не уверен, что моя формулировка правильная. Мне самому нужно понять, как должно быть. Форум – это хорошая для меня возможность сделать это...Кстати, а откуда этот "сферический конь в вакууме"? Что это на самом деле? Персонаж из анекдота?


а откуда этот "сферический конь в вакууме"? 
imho, это из попытки физика выдать определение лошадинной силы... Откуда-то из "физики шутят" или еще более ранних...
window === global
ЕСли попридираться не по делу, то вот это утверждение несколько спорное  В жизни есть , к примеру WSH, в котором объекта window нет вообще, а javascript - есть... есть "встраиваемый" в приложения Javascript, в котором бывает все, включая черта в ступе...


Откуда-то из "физики шутят" или еще более ранних...
Если это тот самый анекдот, то тогда это мимо нот (т.е. не ко мне). Я лишь пытаюсь использовать имеющуюся терминологию, а не придумываю какую-то свою семантику.
ЕСли попридираться не по делу...
Не по делу – это любой может, а Вы по делу попробуйте. Смотрите за ходом:
global - объект из ECMA, в JS это window
, далее, в контексте "в JS это window":
window === global:
и подтверждение из ES:
...in the HTML document object model the window property of the global object is the global object itself.
, т.е. если уж есть window, то это и есть global.


AKS
Кстати, а откуда этот "сферический конь в вакууме"? Что это на самом деле? Персонаж из анекдота?
Да. Сначала из анекдота. Потом... Ну в общем нарицательным стало. Аналог "бессмысленная, в приложении к практике, тема"  


, т.е. если уж есть window, то это и есть global.
Ну да, в случае если он есть... А если нет - то что - это уже и не JavaScript вовсе? Или вам кажется, что ES придумывался исключительно для использования внутри броузеров и с обязательной поддержкой 
... HTML document object model ...
  ?


Если говорить о контексте, в котором вызывается функция, то это execution context (глобальный контекст, локальный контекст или еще бог знает какой), представляющий собой сложный набор данных.
Так, давай определимся с понятием контекста. Есть локальный контекст - это набор всех локальных переменных определённых в функции (var выражения). Есть  унаследованный контекст (у тебя scope chain) - это набор всех переменных, видимых на момент определения (создания нового instance) функции - по сути локальный контекст "родительской" функции (представим что самый внешний контекст это локальный контекст гипотетической функции run() {  здесь код самого верхнего уровня }.Контекст объекта - это набор всех его slot'ов (термин из Smaltalk, откуда прототипные объектное программирование взяло начало). В мире где "методы" и "переменные" объекта находятся в одном адресном пространстве - такие "поля" называются slot'ами. Я думаю ясно почему это удобней, вместо воображаемого разделения на "переменные" и "методы" объекта (некоторые воображают даже классы в JS).Контекст объекта == this внутри функции, позволяет обращаться к полям (slots) obъекта - задаётся программистом при вызове функции (да, именно программист говорит на каком объекте вызвать функцию, .func() - лишь удобный синтаксис). Объектов масса - значит и разных контекстов масса.Локальный контекст - создаётся каждый раз при вызове функции, при чём для каждого рекурсивного вызова (а также для каждого треда в multi-threaded движках) создаётся новы экземпляр контекста.Наследуемый контекст (ECMA: scope chain) - связан с конкретным instance функции. От одной функции можно породить массу instance, каждый будет связан со своим наследуемым контекстом, который существовал в момент когда интерпретатор создавал этот instance - другими словами каждая функция это closure (почти, это дело можно оптимизировать + ECMA по моему различает понятия функция и closure из-за немного разной видимости переменных).Ну и наконец - контекст == (map(name) => value) - обычно реализуемого хеш-таблицей. Теперь давай опираться от этих понятий и не путать вещи.
Приходится ломать голову над трактовкой – то ли это что-то новенькое в ES, то ли это метафора, то ли речь идет об адресации к динамической памяти (к которой сам ES вообще никакого отношения не имеет).
А теперь давай отбросим фарисейство и воспользуемся человеческой соображаловкой. Я не использую терминологию ECMA, т.к. перевожу термины на русский по смыслу.
Сам context она не держит. Как я уже писал, контекст – это многогранная информация, которой нет места в scope chain.
Говорим об одном и том же разными терминами (тупо переименуй абстрактное контекст на более конкретный scope chain).
Отнюдь нет. Во втором случае идентификатор func может оказаться методом любого объекта из scope chain активного контекста выполнения, и им может оказаться вовсе не global.
Используя global подразумевал переменную, содержащую именно объект global. Дописывать ", где переменная global содержит объект global" в не формальном общении для меня выглядит дико 
Т.е речь шла непосредственно о вызове на некотором объекте, и тут уж привязка достаточно жесткая.
Речь шла почему object.method даст функцию не связанную с object. Совершенно естественно, что интерпретатор на момент вызова функции найдёт объект и передаст его функции как this, но тебе в языке это принесёт такую же пользу, как знать, что Земля круглая. А ещё можно построить автомат, в котором object  (, где object содержит объект object, упомянутый в первом предложении   ) будет "закодирован" в набор состояний и тогда понятие this в интерпретаторе (в native run-time, не в семантике JS ;-) ) вообще исчезнет. Всё зависит от реализации.Мантра:Что бы было ясно: программиста интересует можно ли создать функцию, что будет жёстко привязана к конкретному объекту, где жёсткая привязка позволяет вызвать функцию без указания объекта, на ком вызываем и тем не менее ссылка this будет указывать на оригинальный объект.Ответ: нет, нельзя, т.к. функция свободна от каких либо ссылок на объекты, к которым она может принадлежать (являясь значением полей), поэтому указывать объект на ком вызываем необходимо.Но ведь в в N микросекунд, в которые интерпретатор выполняет функцию, он ведь "знает" объект на ком вызвали, значит в этот момент есть"жёсткая привязка"!Ответ: термин "жёсткая привязка" понят не правильно, реализация тут не при чём, обсуждаем специфику языка. В реализации само понятие объект может отсутствовать, а ссылок не явных (требуемых в разные моменты времени) может быть вообще не ограниченное количество.Как сделать дискуссию конструктивной?Обсуждать смысл аспектов языка, а не привязываться к терминам. Любой человек всегда способен найти корреляцию между собственной терминологией и терминами используемыми собеседником - это одно из главных отличий человеческого мозга от компьютера - работать со смыслом, а не с символьными вычислениями.Перестать задумываться о реализации JS движка, ведь в разных языках и окружениях по разному. Используя общий термин контекст, я к примеру не имею в виду JSContext из ************. Если конвертнуть интерпретатор в машину Тьюринга, то детали из ************ вообще потеряют смысл - заметим, что семантика JS при этом не изменится P.S. извиняюсь, за жёсткий ответ, просто считаю что спор уходит в тупик, когда скатывается до различий в терминологии.


Ну да, в случае если он есть... А если нет - то что - это уже и не JavaScript вовсе? Или вам кажется, что ES придумывался исключительно для использования внутри броузеров и с обязательной поддержкой 
Я ведь написал, что window === global. Что не понятно? И разве я писал что-то об отсутствии window? Вроде бы указал на автора формулы "global - объект из ECMA, в JS это window", так почему ко мне вопросы?
Есть локальный контекст - это набор всех локальных переменных определённых в функции (var выражения). 
Это не только "var выражения". Это еще и arguments object, и формальные параметры, и объявленные функции, и т.д., и т.п. 
Есть  унаследованный контекст (у тебя scope chain)
Это не у меня, это в ECMAScript Language Specification
...это набор всех переменных, видимых на момент определения (создания нового instance) функции - по сути локальный контекст "родительской" функции...
Опираясь на ваши же рассуждения, что локальный контекст – это набор локальных переменных, можно сказать, что унаследованный контекст не является лишь локальным контекстом "родительской" функции.
представим что самый внешний контекст это локальный контекст гипотетической функции run()
Зачем представлять по-своему то, что уже давно представлено? Чтобы подогнать под свою философию?
...термин из Smaltalk, откуда прототипные объектное программирование взяло начало
Не аргумент.
Я думаю ясно почему это удобней, вместо воображаемого разделения на "переменные" и "методы" объекта
Я как-раз так не думаю.
...некоторые воображают даже классы в JS...
Это еще при чем? 
ECMA: scope chain
Мне не ясно – для чего подобные оговорки? Мы в каком разделе беседуем?
От одной функции можно породить массу instance...
???
...другими словами каждая функция это closure
???
Теперь давай опираться от этих понятий и не путать вещи.
О каких именно понятиях речь? Пока передо мной лишь бессвязная каша – локальные/наследуемые/наборы слотов/this внутри функции/хеш-таблицы. 
А теперь давай отбросим фарисейство и воспользуемся человеческой соображаловкой.
В очередной раз не понимаю, на этот раз – причем тут фарисейство? Вы или выбирайте выражения, или не используйте тех, смысл которых Вам не ясен.
Я не использую терминологию ECMA, т.к. перевожу термины на русский по смыслу.
А я напротив предлагаю воспользоваться существующими определениями, не пытаясь перевести их на любой другой язык. Подобные попытки всегда неудачны.
...тупо переименуй абстрактное контекст на более конкретный scope chain
Очередное определение контекста? Так что же это, в конце концов? И как это последнее, с вашим слов тупо переименованное, увязать с вызовом функции в контексте объекта?
Используя global подразумевал переменную, содержащую именно объект global. Дописывать ", где переменная global содержит объект global" в не формальном общении для меня выглядит дико smile
Не все могут, также как smartov, понимать Вас с полуслова. Лично у меня не настолько развитая интуиция. Так что пишите сразу, как есть, чтобы потом не оправдываться.
но тебе в языке это принесёт такую же пользу, как знать, что Земля круглая. 
Любые детали полезны, также как и знание того, что Земля круглая. 
Мантра:
Да уж...
программиста интересует можно ли создать функцию
Да не это его интересовало, господи!
Как сделать дискуссию конструктивной?
Ответ простой - нужно учиться искусству общения.
Обсуждать смысл аспектов языка, а не привязываться к терминам.
Обсуждать, используя свою доморощенную терминологию? Насколько продуктивным может быть такое обсуждение?
Любой человек всегда способен найти корреляцию между собственной терминологией и терминами используемыми собеседником...
Даже если собеседник ошибается и не хочет признавать своих ошибок? В чем смысл обсуждения, если заблуждающийся упирается руками и ногами?
Перестать задумываться о реализации JS движка, ведь в разных языках и окружениях по разному.
Причем тут разные языки и окружения? Есть ECMAScript Language Specification, есть реализации, претендующие на соответствие спецификации – о них и речь. Все остальное, а именно чьи-либо пространные рассуждения, к примеру о машине Тьюринга, не представляет для конструктивной дискуссии ни малейшего интереса.
я к примеру не имею в виду JSContext из ************.
************ был упомянут, как незначительная частность, или как следствие, если угодно.
извиняюсь, за жёсткий ответ, просто считаю что спор уходит в тупик, когда скатывается до различий в терминологии. 
Не стоит извинений. Эмоции - они от недостатка аргументов.


Вроде бы указал на автора формулы "global - объект из ECMA, в JS это window", так почему ко мне вопросы?
Ну, чтобы придать конкретности - вот та "реальность", для которой мне приходится чего-то писать
Writeln("global " + typeof(global));Writeln("window " + typeof(window));Writeln("WriteLn " + typeof(WriteLn));Writeln("this " + typeof(this));
результат
global undefinedwindow undefinedWriteLn unknownthis object
Что такое у меня this я так и не разобрался, документацию читать лень, да и потребности пока не вижу... ;-) Что такое global или window в моей "реальности" - вообще неопределено... Тем не менее это самый настоящий JavaScript. Впрочем формула window===global в ней, хоть и бессмысленна, но спарведлива 


можно сказать, что унаследованный контекст не является лишь локальным контекстом "родительской" функции.
Это почему же? Вчитайся в мой текст получше. Термин "лишь" - не ограничивает пользователей контекста только функцией, к которой контекст принадлежит, если что...
Зачем представлять по-своему то, что уже давно представлено? Чтобы подогнать под свою философию?
Странный выпад... Да, не опираюсь на стандарт ECMA дословно, смысл то идентичный. Мало того, в реализации действительно удобно представить самый внешний контекст как просто локальный контекст гипотетической run(). Может приведёшь, что ECMA говорит по этому поводу и где я был не прав?
Я как-раз так не думаю.
Ну это аргумент обиженного малыша, если честно   В чём различия между "простыми" переменными (содержит число к примеру) и "методами" (переменная содержит функцию)?  Только по существу, т.к. на концептуальном уровне для человека пришедшего с ООП это действительно удобно. Увы понятие "концептуальный уровень" - есть инструмент, для лучшего восприятия семантики. Например узнав что такое классы и instaces в Haskell у обычного ООП программиста "расплавятся мозги", проверенно на себе   , но поняв, чувствуешь себя как заново родился 
Мы в каком разделе беседуем?
Не формальное обсуждение JS. Суть этого топа, по моему было решить - есть ли какая-либо жёсткая привязка функции к объекту, такая, что имея на руках только функцию, можно достать объект, к которому эта функция принадлежит - правда скатываемся до выяснения, чья же терминология лучше и как это кощунственно переводить термины ECMA по смыслу     Попутно нырнули в дреби ************, узнали что таки this всегда при вызове функции используется, а три C'шных функции нужны для разного доступа к функции. Ну ещё узнали, что при общении нужно точно указывать, когда говорим о ссылке, а когда о конкретном значении (соглашусь, полезное качество  ).
Даже если собеседник ошибается и не хочет признавать своих ошибок? В чем смысл обсуждения, если заблуждающийся упирается руками и ногами?
Где я ошибаюсь? До сих пор наш диалог напоминает:
S> эта стенка белаяA> нет!!! эта стенка цвета #FFFFFF, согласно спецификации xxx и вообще ... и ...
Предлагаю взять мои утверждения и опровергнуть. Нет, не доказать, что я не copy-paste термины из спецификации ECMA, а то что изменил смысл терминов. Или хотя бы заблуждаюсь в вопросе ссылок.
Пока передо мной лишь бессвязная каша
Ответ простой - нужно учиться искусству общения.
По моему этот топ не приносит больше удовольствие, ни мне, ни тебе. Если снова захочется выкрикнуть подобное, есть PM.Добавлено через 2 минуты и 38 секундksnk, global (объект, а не переменная с именем "global" если что   ), действительно существует в ECMAScript окружении. Оригинальный "браузерный" JS в этом плане отличается, там используется DOM 0 window для этих целей (DOM 0 - общепризнанный термин "унаследованных" window, document и т.д. если что    )


Что такое у меня this...
Global Object
Вчитайся в мой текст получше.
Вчитываюсь:
Есть локальный контекст - это набор всех локальных переменных определённых в функции (var выражения).
Ага, вары – локальный контекст. Дальше:
Есть  унаследованный контекст ... - это набор всех переменных, видимых на момент определения ... функции - по сути локальный контекст "родительской" функции
Унаследованный контекст – локальный контекст "родительской" функции. А что такое локальный контекст "родительской" функции? Согласно Вам - это вары "родительской" функции. Вот я и пишу, что не только лишь.
Странный выпад... 
Ничего странного, и уже тем более не выпад. Я пытаюсь понять, зачем нужно уходить в "лес огородами".
Может приведёшь, что ECMA говорит по этому поводу и где я был не прав?
Я написал лишь то, что написал, и ни слова о правых и неправых.Почему не тянет на гипотетической run()? Хотя бы потому, что есть существенные отличия – отсутствует arguments object и формальные параметры. 
...для человека пришедшего с ООП это действительно удобно. 
Этот человек начнет для своего удобства искать классы и т.д. Что прикажете делать? Найти и показать их ему? Речь не об удобстве – речь о конкретных терминах.
...скатываемся до выяснения, чья же терминология лучше...
Я не скатываюсь. Я не собирался выяснять, чья лучше, а чья хуже. Посмотрите, с чего я начал: "А вот там вроде что-то такое есть", "А вот этого я никак найти не могу", "А вот в доках все как-то по-другому".И мне не нужна моя терминология. Я пытаюсь узнать то, как должно быть. Читали, что я ответил smartov?
Где я ошибаюсь?
Да хотя бы с closures. То Вы пишите, что "ECMA разделяет декларации функций и функции-closure как значения":
function name() {...var name = function() {...
, то вдруг "каждая функция это closure". 
Или хотя бы заблуждаюсь в вопросе ссылок.
Каких еще ссылок?
По моему этот топ не приносит больше удовольствие, ни мне, ни тебе. 
А что так? Какие есть еще соображения по теме? Я же написал, что я не уверен на 100%, и чтобы понять, нужно обсуждение. Вот, к примеру, у тех, кто пишет Mozilla’вские доки (this Operator) представление почти такое же, как у Вас:
The this keyword refers to the <span>context object</span> (a.k.a. current object). In general, in a method, this refers to the calling object.