Когда я должен использовать свое собственное пространство имен и когда я должен расширять нативные объекты js?
Я нахожусь в процессе рефакторинга моего кода. У меня проблемы с выбором того, как именно реализовать несколько функций утилит, которые у меня есть. В частности, если некоторые функции лучше использовать в моем личном пространстве имен или расширять js Objects напрямую.
Пример расширения нативных объектов JavaScript
(это правильный термин?).
String.prototype.prettyDate = function(){
return (this.substr(5,2) + '/' + this.substr(8) + '/' + this.substr(0,4));
}
var myString = "2010-12-27";
//logs 12/27/2010
console.log(myString.prettyDate);
Пример использования моего собственного пространства имен
var myNamespace = (function(){
var my = {};
my.prettyDate = function ( dateStr ){
return (dateStr.substr(5,2) + '/' + dateStr.substr(8) + '/' + dateStr.substr(0,4));
}
return my;
}());
var pretifiedDate = myNamespace.prettyDate('2010-12-27');
//logs 12/27/2010
console.log(pretifiedDate);
Вопросы для рассмотрения
- Когда утилита обоснованно вставляется в нативный объект JavaScript?
- Как я могу определить, когда утилита лучше находиться в моем собственном пространстве имен?
5 ответов
Почти никогда, из-за:
а / возможные конфликты с другими библиотеками
b / расширенные функции итерируются как свойства с помощью оператора in, что создает проблемы, если не отфильтровано hasOwnProperty (который обычно не используется)
Вы можете оправдать это небольшими работами с одним скриптом, но только если вы на 200% уверены, что никто и никогда не будет пытаться повторно использовать этот код где-либо. В таком случае используйте его только для функциональности, которая охватывает более одного модуля вашего кода. Расширение String с помощью trim() - нормально, расширение String с prettyDate() - сомнительно, расширение Object с displayAsPageHeader() - страшно.
Так почти всегда.
Посмотри это видео:
Джон Резиг считает, что расширение собственных объектов - это путь к катастрофе, особенно когда фреймворк или приложение могут превратиться во что-то, что делает гораздо больше, чем предполагалось изначально.
К сожалению, на этот вопрос нет "правильного" ответа. Это хорошая дискуссия, но я боюсь, что она здесь закроется. Следует ли вообще расширять нативные объекты - это субъективная дискуссия, и если вы согласитесь, что это условно, ответ на вопрос "когда?" это "зависит".
Если у вас есть контроль над его использованием и будет ли он сталкиваться с другим кодом, на самом деле нет причин, по которым вы не должны этого делать. Это может быть довольно удобно и может значительно уменьшить размер кода.
Реальная проблема с расширением собственных объектов возникает тогда, когда рядом с вашим расширением работает другой код, который может ожидать другого расширения с тем же именем свойства или который небрежно использует for(var i in obj)
без защиты от расширений до прототипа цепи.
Хорошо... я не эксперт в этом, но почти никогда! Вещи, которые вы делаете, безопаснее в вашем пространстве имен. И все работает нормально, если вы следуете шаблону модуля http://www.yuiblog.com/blog/2007/06/12/module-pattern/
Однако есть некоторые маленькие хитрости, которые позволяют нам избежать перезаписи пространства имен других. за пример:
var myNamespace = {}; //my namespace, unsafely written
//Better solution
if(typeof myNamespace === 'undefined'){
var myNamespace = {};
}
//Shorter solution
var myNamespace = myNamespace || {};
Это зависит от того, насколько вы контролируете, какой код запускается / загружается:
Если все находится под вашим контролем, то нет ничего плохого в расширении встроенных объектов, JavaScript предназначен для этого. Единственная проблема в том, что у вас могут возникнуть непредвиденные проблемы, когда две библиотеки что-то меняют. К счастью, ты не сделал бы это с собой, верно?
Если вы не знаете / не можете знать, пространство имен намного безопаснее, хотя и неуклюже и многословно. Это всегда безопаснее.
Лично я предпочитаю второй вариант, потому что мне не нравится слишком многословный код, а пространства имен выглядят забавно.