 
			
				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.
				
				
			
		
		
	
		
		
	
	
	 | 
 
 
	 
		 | 
 
 
 
 
 
 
 
	 | 
 
 
 |