Cita:
Iniciado por h2swider No es posibles extender nativos en JS. :)
Sí y no. Depende. Primera aclaración: los objetos que supuestamente no se pueden extender son los objetos host (document, window, frames. etc). Los objetos nativos (Date, Math, etc) pueden extenderse modificando su prototipo (prototype) sin problemas si uno sabe lo que hace.
Los objetos host pueden extenderse de varias maneras, algunas más correctas que otras. Algunos navegadores permiten modificar su prototipo, para otros ni siquiera tienen prototipo (y ambas posturas son correctas de acuerdo al estandar, ya que no es necesario que respondan a las características de los objetos tradicionales javascript).
Una manera un tanto incorrecta de extender objetos host sería esta:
Código PHP:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Untitled Document</title>
<script type="text/javascript">
var ej=(
function(){
var mp={
addEvent: function(type, fn ) {
if ( this.addEventListener ) {
this.addEventListener( type, fn, false );
} else if(this.attachEvent){
var _this=this;
var f= function(){fn.call(_this,window.event);}
this.attachEvent( 'on'+type, f);
}else{
throw new Error('Estás navegando en una balsa agujereada: es hora de cambiar de navegador!');
}
return this;
},
customFocus:function(){
this.style.background='pink';
return this;
},
customBlur:function(){
this.style.background='white';
return this;
},
extendido:1
};
return {
extend:function(el,obj){
if(el.extendido && el!=mp)return el;
for(var i in obj)
el[i]=obj[i];
return el;
},
get:function(id){
if(!document.getElementById(id))return false;
return ej.extend(document.getElementById(id),mp);
},
geto:function(obj){
return ej.extend(obj,mp);
}
};
}
)();
var $=ej.get,_$=ej.geto;
_$(window).addEvent('load',function(){$('pp').addEvent('focus',function(){this.customFocus();}).addEvent('blur',function(){this.customBlur();});});
</script>
</head>
<body>
<form action="" method="get">
<input id="pp" name="" type="text" />
</form>
</body>
</html>
Es un tanto incorrecta porque agrega métodos y propiedades a objetos host aprovechando que se comportan como un objeto javascript Object, pero el problema es que aunque ahora funciona en todos los navegadores, esto puede cambiar en el futuro y además puede ocasionar cconflictos y problemas de rendimiento si no se sabe muy bien lo que se hace. No obstante esto, Frameworks conocidos utilizan esta técnica.
Una mejor aproximación es usar un wrapper: envolver el objeto host en otro. Ese objeto envoltorio es el que tiene las propiedades y métodos que extienden de manera indirecta las propiedades del objeto host. Pero la ventaja es que nunca se agrega nada al objeto host: el que hace todo el trabajo es el wrapper:
Código PHP:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Untitled Document</title>
<script type="text/javascript">
var ej=(
function(){
var extendidos={};
var mp={
addEvent: function(type, fn ) {
var _this=this;
if ( this[0].addEventListener ) {
var f= function(){fn.call(_this);};
this[0].addEventListener( type, f, false );
} else if(this[0].attachEvent){
var f= function(){fn.call(_this,window.event);};
this[0].attachEvent( 'on'+type, f);
}else{
throw new Error('Estás navegando en una balsa agujereada: es hora de cambiar de navegador!');
}
return this;
},
customFocus:function(){
this[0].style.background='pink';
return this;
},
customBlur:function(){
this[0].style.background='white';
return this;
}
};
return {
extend:function(el,obj){
if(el[0]!==document && el!==mp){
el[0].id=el[0].id || '____'+(+new Date())+Math.random();
}
if( el!==mp && extendidos.hasOwnProperty(el[0].id || 'document'))
return extendidos[(el[0].id || 'document')];
for(var i in obj)
el[i]=obj[i];
if(el!==mp)
extendidos[(el[0].id || 'document')]=el;
return el;
},
get:function(id){
if(!document.getElementById(id))
return false;
var el=[];
el[0]=document.getElementById(id);
return ej.extend(el,mp);
},
geto:function(obj){
var el=[];
el[0]=obj;
return ej.extend(el,mp);
}
};
}
)();
var $=ej.get,_$=ej.geto;
_$(window).addEvent('load',function(){$('pp').addEvent('focus',function(){this.customFocus();}).addEvent('blur',function(){this.customBlur();});});
</script>
</head>
<body>
<form action="" method="get">
<input id="pp" name="" type="text" />
</form>
</body>
</html>
Son sólo ejemplos. Hay que agregar varias optimizaciones para poder usarlos en un ambiente real.