01.11.2009, 01:21
|
...
|
|
Регистрация: 09.03.2008
Сообщений: 216
|
|
Secrets of the Javascript Ninja
Читали последнюю книжку от Ресига? Только открыл и уже:
To start, it's important to realize what that the function context represents: The object within which the function is being executed. For example, defining a function within an object structure will ensure that its context always refers to that object - unless otherwise overwritten... However, what about a function that isn't explicitly declared as a property of an object? Then the function's context refers to the global object.
Ну, то что наш ниндзя прибил точный и важнейший термин "контекст" его народным определением ещё можно понять и даже простить, если бы речь шла о вызове функции "в контексте чего-либо". Но он пишет об определении/объявлении функции в связи с чем "context always refers to that object", не о вызове. Типичная избитая ошибка javascript-ньюбов. Ещё 3 страницы осилил - на каждой по системной ошибке.
Резюме - начинающим читать по диагонали (хуже не будет), хорошо знающим - читать по диагонали (чтобы составить мнение о книге и авторе), уже не начинающим, но пока плавающим - лучше не читать. ;-)
|
|
01.11.2009, 01:58
|
Профессор
|
|
Регистрация: 25.02.2008
Сообщений: 707
|
|
Ниндзюцу, блин
Кстати, 80% пишущих на JS, под термином "контекст" (или даже полно - контекст исполнения) понимают this-value (Ниндзя в данном случае тоже использует слово "context", но подразумевает this-value).
Да, вот так продвигается неграмотность. Zeroglif, надо выступать в том месте и в то время, где эти вопросы решаются. Польза будет, я думаю.
Интересно, Резиг же, вероятно, советовался со многими перед выпуском книги. Он же, вроде, в Мозилле работает (нет?) - ну, посоветовался бы с B.Eich-ом.
Сообщение от Википедия
|
Джон Резиг (англ. John Resig) — JavaScript евангелист в Mozilla Corporation.
|
А кто ему этот титул присвоил? Или он самозванно? Или это Википедия так балуется?
|
|
01.11.2009, 02:29
|
...
|
|
Регистрация: 09.03.2008
Сообщений: 216
|
|
Dmitry A. Soshnikov,
Ресиг давно мозильный javascript евангелист, получает деньги за это... так что... Ты почитай, как евангелист пиарит в книжке конструкцию with(), несколько страниц аж. Я уже до прототипов дошёл, там вообще труба, какая-то очередность присвоения свойств (сначала из prototype, потом из конструктора, поэтому затираются)... там же про то, что свойства объекта статичны!!!, а свойства прототипа live!!! и они bind к экземпляру даже!!! после его создания. Типа своя трактовка непонятного чуда.
В общем, вторая его аццкая книга и снова всё внесистемно, по вершкам, нагугленные куски, самопал... первая даже лучше... а ведь годы уже прошли.
Цитата:
|
Кстати, 80% пишущих на JS
|
Угу. "Вызов в контексте" нормальные люди используют, подразумевая 'this'. Вызов! Он говорит не про вызов, а про определение функции, это чушь.
|
|
01.11.2009, 02:32
|
...
|
|
Регистрация: 09.03.2008
Сообщений: 216
|
|
Ему всего-то надо понять reference type, просто разобрать почему:
var obj = { m: function () { return this; } };
alert( obj.m() ); //-> object
alert( (obj.m)() ); //-> object
alert( (obj.m = obj.m)() ); //-> global
|
|
01.11.2009, 03:27
|
|
|
Регистрация: 10.07.2008
Сообщений: 3,873
|
|
Так что то я начал сомневаться. В таком варианте: вызов функции func в контексте объекта context — правильная терминология и именование аргумента функции?
function bind(func, context) {
return function(arg) {
func.call(context, arg);
};
}
Всегда смущало, что вместо context многие пишут scope — это же не правильно? Или вообще может лучше thisObj называть
Последний раз редактировалось Octane, 01.11.2009 в 03:34.
|
|
01.11.2009, 03:28
|
|
Рассеянный профессор
|
|
Регистрация: 06.04.2009
Сообщений: 2,379
|
|
Сообщение от Zeroglif
|
просто разобрать почему
|
а почему?
Я сталкивался с подобным в немного другом виде:
alert( (obj.m || obj.n)() ); //-> global
объяснил себе так: раз "obj.m || obj.n" в скобках, то они будут вычисляться и на выходе из скобок будет просто "m" или просто "n", т. е. это тоже самое что:
var x = obj.m || obj.n;
x(); //-> global
Правильно я понял?
Последний раз редактировалось Riim, 01.11.2009 в 03:30.
|
|
01.11.2009, 03:37
|
|
Рассеянный профессор
|
|
Регистрация: 06.04.2009
Сообщений: 2,379
|
|
Сообщение от Octane
|
что вместо context многие пишут scope
|
т. е. получается:
Цитата:
|
вызов функции func в scope объекта context
|
разве у объектов есть scope? Он же у функций.
|
|
01.11.2009, 12:21
|
...
|
|
Регистрация: 09.03.2008
Сообщений: 216
|
|
Сообщение от Octane
|
Всегда смущало, что вместо context многие пишут scope — это же не правильно? Или вообще может лучше thisObj называть
|
'thisObj' было бы идеально, тогда не будут перекрещиваться термины, обозначающие разные вещи:
- "вызов функции в контексте объекта";
- " контекст исполнения функции";
Но, в принципе говорить о вызове в контексте (именно о вызове) - это нормально, если вы посмотрите на родные доки JavaScript (начиная с 1.3), то в отношении 'apply' и 'call' эта терминология применяется:
Цитата:
|
Allows you to apply a method of another object in the context of a different object (the calling object).
|
что в переводе на формальный язык ES расшифровывается с точки зрения вызова прямо там же:
Цитата:
|
assign a different this object
|
Отсюда, говоря о "вызове в контексте объекта" мы однозначно говорим об определении 'this'...
|
|
01.11.2009, 12:52
|
...
|
|
Регистрация: 09.03.2008
Сообщений: 216
|
|
Сообщение от Riim
|
Правильно я понял?
|
Не совсем, но близко. Согласно Дж.Ресигу "определение функции в качестве метода объекта гарантирует, что вызов всегда будет в контексте этого объекта". Это само собой глупость, так как 'this' определяется 'caller'-ом, попросту говоря тем, как записана форма вызова, а не тем как и где определена функция. Обычную объявленную функцию уже с ходу можно вызывать по-разному, меняя 'this':
function f() {
alert( this );
}
f();
f.prototype.constructor();
Не говоря уже о том, что её можно передавать, присваивать и т.д.
При вызове интерпретатор определяет, что стоит слева от "оператора вызова", от скобок. Вычисляется выражение и определяется тип вычисленного промежуточного результата... а это одно из двух - Reference type или не Reference type. Если там (слева) стоит идентификатор (foo) или аксессор (foo.x или foo['x']), то мы имеем дело с Reference type, а значит определённый объект, "владелец" метода в момент вызова, станет значением 'this' (activation object не в счёт). Если там любое другое выражение, например:
(foo.x || foo.y)();
(foo.x, foo.y)();
(function () {})();
то это не Reference type, значением 'this' станет null->global.
|
|
01.11.2009, 13:41
|
Профессор
|
|
Регистрация: 25.02.2008
Сообщений: 707
|
|
Сообщение от Zeroglif
|
Ты почитай, как евангелист пиарит
|
Ага, полистаю.
Сообщение от Zeroglif
|
alert( (obj.m)() ); //-> object
alert( (obj.m = obj.m)() ); //-> global
|
Да, я подробней покажу, всем остальным, кому интересно:
Сообщение от 11.1.6 The Grouping Operator
|
NOTE
This algorithm does not apply GetValue to Result(1). The principal motivation for this is so that
operators such as delete and typeof may be applied to parenthesised expressions.
|
Поэтому, в первом случае после оператора группировки, у нас всё ещё Reference Type, а во втором случае, оператор присваивания (как и другие - "ИЛИ", или "запятая"), вызовет для AssignmentExpression GetValue, который, вызвав в свою очередь [[Get]], вернёт уже значение свойства, т.е. функцию, и будет уже не тип Reference. Для выражения вызова, это означает использовать Global в качестве this-value.
Сообщение от 11.13.1 Simple Assignment ( = )
|
2. Evaluate AssignmentExpression.
3. Call GetValue(Result(2)).
|
Сообщение от Octane
|
Всегда смущало, что вместо context многие пишут scope — это же не правильно?
|
С точки зрения Scope и [[Scope]] в ES (и основной точки зрения - понимания этих сущностей) - конечно, это неправильно. Этим, кстати, грешит фреймворк ExtJS, который везде для handler-ов событий указывает вторым параметром - scope: this, имея в виду thisValue.
Последний раз редактировалось Dmitry A. Soshnikov, 02.11.2009 в 12:07.
|
|
|
|