Прототипирование родных типов JavaScript, не рекомендуется?
Неплохая идея прототипа дополнительных возможностей в родных типах JavaScript, таких как Array, String, Number и т.д.
Я думаю, было бы здорово иметь такие функции, как myArr.pop() и т.д., но что, если когда-нибудь это станет частью ECMAScript x - и отличается от моей реализации, значит, это потенциально может сломать все программное обеспечение?
Ответы
Ответ 1
Прототип - это библиотека, которая широко распространяет собственные типы Javascript и классы DOM, и показывает очень хорошо хорошие, плохие и уродливые расширения родных типов Javascript.
The Good: вы получаете естественный код Javascript.
Плохо: вы забываете, что на самом деле используете Prototype - нерешительную путаницу при переключении на проект, который не использует Prototype. (Почему я не могу... о, верно, это была возможность прототипа.)
Ужасно: если существует конфликт для определений методов (два метода, которые различаются в контрактах или подписях) из-за противоречивых библиотек, браузера или спецификации, вам может потребоваться изменить код клиента для обеспечения совместимости. Это делает еще одно соображение совместимости в мире, уже преследуемом ими.
В целях совместимости и сохранения моих собственных ясности я лично воздерживаюсь от расширения родных или DOM-типов JavaScript и предпочитаю менее навязчивые библиотеки Prototype.
Однако, если вы чувствуете себя непринужденно с этими недостатками, не позволяйте мне останавливать вас.
Ответ 2
Если вы пытаетесь реплицировать метод, определенный для некоторых браузеров, но не другие, попытайтесь получить определение, соответствующее исходной реализации.
if(![].indexOf){
Array.prototype.indexOf= function indexOf(what, i){
i= i || 0;
var L= this.length;
while(i< L){
if(this[i]=== what) return i;
++i;
}
return -1;
}
}
if(![].map){
Array.prototype.map= function map(fun, scope){
var L= this.length, A= Array(this.length), i= 0, val;
if(typeof fun== 'function'){
while(i< L){
if(i in this){
A[i]= fun.call(scope, this[i], i, this);
}
++i;
}
return A;
}
else throw 'missing function argument';
}
}
if(!''.trim){
String.prototype.trim= function trim(){
return this.replace(/^\s+|\s+$/g,'');
}
}
При необходимости будет использоваться собственный метод.
Если вы катите свои собственные методы, попробуйте дать им имя, которое вряд ли будет упреждаемым
Мне нравится иметь случайный случай и метод naturalSort для массивов,
но я даю им немного отличные имена.
Array.prototype.a1Sort= function(){
var a, b, a1, b1, rx= /(\d+)|(\D+)/g, rd= /\d+/;
return this.sort(function(as, bs){
a= String(as).toLowerCase().match(rx);
b= String(bs).toLowerCase().match(rx);
while(a.length && b.length){
a1= a.shift();
b1= b.shift();
if(rd.test(a1) || rd.test(b1)){
if(!rd.test(a1)) return 1;
if(!rd.test(b1)) return -1;
if(a1!= b1) return a1 - b1;
}
else if(a1!= b1) return a1> b1? 1: -1;
}
return a.length - b.length;
});
}
Array.prototype.disorder= function(force){
var i, temp, L= this.length, A= force? this: this.concat();
while(--L){
i= Math.floor(Math.random()*L);
temp= A[i];
A[i]= A[L];
A[L]= temp;
}
return A;
}
Если вы добавите прототипы, убедитесь, что вы задокументируете его и ссылаетесь на документ в каждом script, который их использует,
если кто-нибудь будет работать с вашим кодом, включая вас.