 
			
				21.10.2014, 19:14
			
			
			
		  
	 | 
 
	
		
		
		
			
			| 
			
				
				
				 Кандидат Javascript-наук 
				
				
				
				
	
 
 
			 | 
			  | 
			
				
				
					Регистрация: 14.10.2014 
					
					
					
						Сообщений: 117
					 
					
					
			
		
 
		 
		
			 | 
		 
		 
		
	 | 
 
	| 
	
	
		
		
			
			 
				Безопасный Monkey Patching
			 
			
		
		
		
		Сейчас в JS считается дурным тоном расширение прототипов, особенно нативных объектов. ИМХО, это связано с одной стороны, тем, что в JS приходит много народу из статических языков, которые просто не понимают профита, с другой — вопросами оптимизации. Где то читал, что Во времена расцвета Prototype.js это наоборот считалось Best Practice. Да и в руби, например, вроде от него нос не воротят. Ну ладно, времена меняются. 
Я тут подумал, а почему бы не сделать вот так
 
show=function(x){console.log(x); return x}
Object.prototype.call=function(f){return f(this.valueOf())}
// Примеры использования
"foo".call(show)
"foo bar baz".split(" ").call(show)
;({one: 1, two: 2}).call(show)
;({one: 1, two: 2}).call(function(o){for(var i in o){show(o[i])}})
//  foo
//  [ 'foo', 'bar', 'baz' ]
//  { one: 1, two: 2 }
//  1
//  2
Так мы получаем почти то же самое, правда с ущербным синтаксисом через  жопу вызова, типа колбеков, но избавляемся от претензий статик-клоунов по-поводу неожиданных эффектов, т.к. главный объект расширен единственным методом. А уже на основе этого можно делать любые обертки. call можно сделать enumerable=false, если чо.  
		
	
		
		
		
		
		
		
	
		
			
			
	
			
			
			
			
			
				 
			
			
			
			
			
			
				
			
			
			
		 
		
	
	
	 | 
 
 
	 
		 | 
 
 
	
	
	
		
	
		
		
		
			
			 
			
				21.10.2014, 20:19
			
			
			
		  
	 | 
 
	
		
		
		
			
			
			
				
				
				
				
				
				
				
	
 
 
 
			 | 
			  | 
			
				
				
					Регистрация: 10.07.2008 
					
					
					
						Сообщений: 3,873
					 
					
					
			
		
 
		 
		
			 | 
		 
		 
		
	 | 
 
	
	
	
		
		
		
		
		А смысл твоего метода call, если того же результата можно добиться написав по-человечески: 
function show(x) {
    console.log(x);
    return x;
}
show("foo");
show("foo bar baz".split(" "));
show({
    one: 1,
    two: 2
});
(function (o) {
    for (var i in o) {
        show(o[i])
    }
})({
    one: 1,
    two: 2
});
//  foo
//  [ 'foo', 'bar', 'baz' ]
//  { one: 1, two: 2 }
//  1
//  2
?  
		
	
		
		
		
		
		
		
	
		
		
	
	
	 | 
 
 
	 
		 | 
 
 
	
	
	
		
	
		
		
		
			
			 
			
				21.10.2014, 20:30
			
			
			
		  
	 | 
 
	
		
		
		
			
			| 
			
				
				
				 Кандидат Javascript-наук 
				
				
				
				
	
 
 
			 | 
			  | 
			
				
				
					Регистрация: 14.10.2014 
					
					
					
						Сообщений: 117
					 
					
					
			
		
 
		 
		
			 | 
		 
		 
		
	 | 
 
	| 
	
	
		
		
		
		
		 Octane, 
 Смысл в том, что когда у тебя получается вот такая вот хрень а1(... a2(...a3(....a4(....)))) гораздо легче это писать в объектном стиле a1.a2.a3.a4. Дело даже не в записи как таковой, а в том, что ты запариваешься куда какие параметры передавать. В данном случае, явная передача объекта проще. 
		
	
		
		
		
		
		
		
	
		
		
	
	
	 | 
 
 
	 
		 | 
 
 
	
	
	
		
	
		
		
		
			
			 
			
				22.10.2014, 15:20
			
			
			
		  
	 | 
 
	
		
		
		
			  | 
			
			
				
				
				 Быдлокодер;) 
				
				
				
				
	
 
 
 
			 | 
			  | 
			
				
				
					Регистрация: 19.11.2010 
					
					
					
						Сообщений: 4,338
					 
					
					
			
		
 
		 
		
			 | 
		 
		 
		
	 | 
 
	
	
	
		
		
		
		
		Не расширяй  никогда Object.prototype, а остальные прототипы можно, но аккуратно.
 
Пример из личного опыта:
 
Object.prototype.get = function () { ... };
Потом где то в коде была функция:
 
function foo(params) {
    params = params || {};
    params.get = params.get || '*'; // И тут всё ломается
}
 
		
	
		
		
		
		
		
			
		
		
		
		
	
		
		
	
	
	 | 
 
 
	 
		 | 
 
 
	
	
	
		
	
		
		
		
			
			 
			
				22.10.2014, 15:39
			
			
			
		  
	 | 
 
	
		
		
		
			
			| 
			
				
				
				 Кандидат Javascript-наук 
				
				
				
				
	
 
 
			 | 
			  | 
			
				
				
					Регистрация: 14.10.2014 
					
					
					
						Сообщений: 117
					 
					
					
			
		
 
		 
		
			 | 
		 
		 
		
	 | 
 
	
	
	
		
		
		
		
		
	
 
	| 
		
			Сообщение от kobezzza
			
		
	 | 
 
	| 
		И тут всё ломается
	 | 
 
	
 
 А что у тебя сломалось, я не понял?  
		
	
		
		
		
		
		
		
	
		
		
	
	
	 | 
 
 
	 
		 | 
 
 
	
	
	
		
	
		
		
		
			
			 
			
				22.10.2014, 18:21
			
			
			
		  
	 | 
 
	
		
		
		
			  | 
			
			
				
				
				 Быдлокодер;) 
				
				
				
				
	
 
 
 
			 | 
			  | 
			
				
				
					Регистрация: 19.11.2010 
					
					
					
						Сообщений: 4,338
					 
					
					
			
		
 
		 
		
			 | 
		 
		 
		
	 | 
 
	
	
	
		
		
		
		
		
	
 
	
		
			Сообщение от terminator-101
			 
		
	 | 
 
	| 
		А что у тебя сломалось, я не понял?
	 | 
 
	
 
 У меня есть функция, которая принимает объект-параметр, в объекте есть свойство, которое в случае, если не задано устанавливается в значение по умолчанию, но этого не происходит, т.к. в прототипе Object есть свойство с таким же именем
 
params.get = params.get || '*';
 
Т.е. вместо значения по умолчанию мы получаем ссылку на значение из прототипа и всё ломается.  
		
	
		
		
		
		
		
			
		
		
		
		
	
		
		
	
	
	 | 
 
 
	 
		 | 
 
 
	
	
	
		
	
		
		
		
			
			 
			
				22.10.2014, 19:01
			
			
			
		  
	 | 
 
	
		
		
		
			  | 
			
			
				
				
				 Профессор 
				
				
				
				
	
 
 
 
			 | 
			  | 
			
				
				
					Регистрация: 11.09.2010 
					
					
					
						Сообщений: 8,804
					 
					
					
			
		
 
		 
		
			 | 
		 
		 
		
	 | 
 
	
	
	
		
		
		
		
		
	
 
	| 
		
			Сообщение от kobezzza
			
		
	 | 
 
	| 
		Не расширяй никогда Object.prototype
	 | 
 
	
 
 Да что там, бывает что встроенные свойства малину портят. 
Благо, есть Object.create(null), но все равно бесит.  
		
	
		
		
		
		
		
			
				__________________ 
				В личку только с интересными предложениями   
			 
		
		
		
		
	
		
		
	
	
	 | 
 
 
	 
		 | 
 
 
	
	
	
		
	
		
		
		
			
			 
			
				22.10.2014, 19:16
			
			
			
		  
	 | 
 
	
		
		
		
			
			| 
			
				
				
				 Кандидат Javascript-наук 
				
				
				
				
	
 
 
			 | 
			  | 
			
				
				
					Регистрация: 14.10.2014 
					
					
					
						Сообщений: 117
					 
					
					
			
		
 
		 
		
			 | 
		 
		 
		
	 | 
 
	
	
	
		
		
		
		
		kobezzza, 
 Ну, если ты сам расширял, ты должен был, наверное помнить,об этом. Это называется не "ломается", а "ошибся". И это может произойти не только с расширением Object, но и вообще с чем угодно. Это стандартная хрень
 
proto={get_: function(){}}
O=function(){}
O.prototype=proto
o1=Object.create(proto)
o2=new O
function foo(params){
   params=params||{}
   params.get_=params.get_||"*"
}
foo(o1)
foo(o2)
alert([o1.get_, o2.get_]) //
То есть, это произошло бы и в случае расширения String, Regexp и пр, равно как и в случае созданного ненативного объекта. Тут дело не в бобине, какбы.  
		
	
		
		
		
		
		
		
	
		
		
	
	
	 | 
 
 
	 
		 | 
 
 
	
	
	
		
	
		
		
		
			
			 
			
				22.10.2014, 19:21
			
			
			
		  
	 | 
 
	
		
		
		
			  | 
			
			
				
				
				 Быдлокодер;) 
				
				
				
				
	
 
 
 
			 | 
			  | 
			
				
				
					Регистрация: 19.11.2010 
					
					
					
						Сообщений: 4,338
					 
					
					
			
		
 
		 
		
			 | 
		 
		 
		
	 | 
 
	
	
	
		
		
		
		
		terminator-101, в данном случая я "забыл", но такую багу очень легко поймать путём подключения сторонней библиотеки.
 
	
 
	| 
		
			 Цитата: 
		
	 | 
 
	| 
		Ну, если ты сам расширял, ты должен был, наверное помнить,об этом.
	 | 
 
	
 
 Я работаю одновременно над кучей проектов, сумарная кодовая база несколько сотен тысяч строк кода и разумеется помнить обо всём я не могу, поэтому пишу "очевидный" код, а не танцую с бубнами.
 
	
 
	| 
		
			 Цитата: 
		
	 | 
 
	| 
		И это может произойти не только с расширением Object, но и вообще с чем угодно.
	 | 
 
	
 
 Может, но с Object.prototype шанс словить такую багу близится к 100%, если только не городить свои неймспейсы, но это будет бред.  
		
	
		
		
		
		
		
			
		
		
		
		
		
						  
				
				Последний раз редактировалось kobezzza, 22.10.2014 в 19:24.
				
				
			
		
		
	
		
		
	
	
	 | 
 
 
	 
		 | 
 
 
 
 |  
  |