Безопасный 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, если того же результата можно добиться написав по-человечески:
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
? |
Octane,
Смысл в том, что когда у тебя получается вот такая вот хрень а1(... a2(...a3(....a4(....)))) гораздо легче это писать в объектном стиле a1.a2.a3.a4. Дело даже не в записи как таковой, а в том, что ты запариваешься куда какие параметры передавать. В данном случае, явная передача объекта проще. |
Не расширяй никогда Object.prototype, а остальные прототипы можно, но аккуратно.
Пример из личного опыта:
Object.prototype.get = function () { ... };
Потом где то в коде была функция:
function foo(params) {
params = params || {};
params.get = params.get || '*'; // И тут всё ломается
}
|
Цитата:
|
Цитата:
params.get = params.get || '*'; Т.е. вместо значения по умолчанию мы получаем ссылку на значение из прототипа и всё ломается. |
Цитата:
Благо, есть Object.create(null), но все равно бесит. |
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 и пр, равно как и в случае созданного ненативного объекта. Тут дело не в бобине, какбы. |
terminator-101, в данном случая я "забыл", но такую багу очень легко поймать путём подключения сторонней библиотеки.
Цитата:
Цитата:
|
| Часовой пояс GMT +3, время: 04:34. |