Безопасный 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, время: 07:40. |