Abril del 2006


Object Literal y los nombres de espacio en javascript

Cómo todo el mundo sabe, javscript puede ser un lenguaje muy feo y sólo algunos habían conseguido exprimir la quintaesencia de este lenguaje, como se hacía en dhtmlcentral.com, cuyas librerías han sido toda una ayuda para los que programamos en javascript desde hace años.
No obstante, eso fue una etapa y los tiempos cambian, y se han buscado nuevas formas que nos acerquen al tipo de lenguaje orientado a objeto propiamente dicho como es java o más actual, .net.
Siempre se ha pensado que era imposible crear clases en javascript, y es así,jaja, pero han buscado formas de imitarlo mediante la creación de objetos, lo que se ha venido a llamar en el mundo anglófono, namespaced javascript o object Literal.
Antes de entrar en materia, os haré un resumen de lo que estoy diciendo para que nos entendamos.

ANTES:
Antes todo eran funciones y entonces siempre podía pasar que si incluíamos 2 archivos de javascript distintos pudieran compartir nombres de funciones similares, y al más frecuentes, variables globales similares, y por lo tanto, ambos scripts dejaban de funcionar.
Como mencionaba, en dhtmlcentral.com y en otros sitios, propulsaron una forma propia de javascript de crear pseudo-classes, se hacía así:
function bola()
{
this.moverx=moverx;
this.movery=movery;
}
function moverx()
{
}
function movery()
{
}
nuevaBola=new bola();


O sea creábamos un objeto, que tenía asociado unos pseudo-métodos, pero el problema de que otro script tuviera una función con el mismo nombre seguía ahí.Había que fastidiarse.
AHORA:
Hoy día, con el surgimiento de Ajax se le está dando mucho bombo a otra forma de imitar las clases, y no es algo nuevo, pero lo cierto es que es cada vez más frecuente.
La "nueva forma", el javascript con nombre de espacio, no crea clases, crea objetos a los que se les añade propiedades, que van a hacer las veces de variables locales por su puesto públicas (aquí no hay distinciones del tipo privada o protegida) y métodos, métodos que no van a poder pisarse por otros scripts, aunque por supuesto nada de métodos con la propiedad override ni sealed ni nada que se le parezca. Es un truco, no una solución final.
Si has llegado hasta aquí, y no sabes de que estoy hablando, este ejemplo te haré comprender:
myscript=new Object();
myscript.current=1;
myscript.init=function(){
  // some code
}
myscript.validate=function(){
  // some code
}

Otro ejemplo con el código más resumido, no voy a decir más elegante, pero mejor para tener todo en un sólo bloque:
myscript={
  current:1,
  init:function(){
    // code
  },
  validate:function(){
    // code
 }
}
Por lo tanto, os animo aquello que hayáis tenido la suerte o la desgracia de llegar hasta aquí que para cuando tengáis tiempo en el trabajo de programar bien javascript y sea un proyecto algo complejo o reutilizable, cojáis las riendas de los nombres de espacio en javascript y empecéis a crear objetos.

Dolor de cabeza: redondeando en ASP

Aquellos que hayáis programado en cualquier lenguaje medianamente aceptable,
habrá podido apreciar que las funciones matemáticas math.floor y math.ceil o
math.ceiling nos proporcionan métodos para redondear hacia abajo o hacia
arriba, cosa que para algunos casos es vital.
Pues bien, ASP ni lo huele.
No obstante, siempre podemos crearnos unos métodos ingeniosos para conseguir casi los mismos
resultados.

He creado 2 funciones que podemos llamar según queramos redondear hacia arriba
o hacia abajo, llamadas roundDown y roundUp, y después una función con piloto
automático y que decidirá si usar uno u otro método dependiendo de su decimal:
autoRound.

La gran pregunta aquí es qué pasa si le paso 10,5, pues según ocurre por ejemplo en
.NET se redondea hacia abajo, pero si está por encima, p.e., 10,51 se redondea hacia
arriba.
En un principio me plantee que examinaría el 2 decimal y si éste era mayor de 0 redondearía
hacia arriba, pero que pasa si el número fuera 10,501. Con este método hubiera
redondeado hacia abajo, y shlaf!! gran error, gran horror.
Es por eso que en autoRound empleo un loop que me indicará si uno de los decimales
a partir del segundo decimal es mayor de 0 pues se redondeará hacia arriba.

Esta función también lo toma en cuenta:


Function roundDown(dblValue)
Dim myDec

myDec = InStr(1, CStr(dblValue), ",")
If myDec > 0 Then
    roundDown = CDbl(Left(CStr(dblValue), myDec))
Else
    roundDown = dblValue
End If

End Function

Function roundUp(dblValue)
Dim myDec

myDec = InStr(1, CStr(dblValue), ",")
If myDec > 0 Then
    roundUp = CDbl(Left(CStr(dblValue), myDec)) + 1
Else
    roundUp = dblValue
End If

End Function

function autoRound(dblValue)
Dim myDec,pos,ini,aux

ini=1
pos = InStr(1, CStr(dblValue), ",")
myDec=left(mid(cstr(dblValue),pos+ini),1)
aux=false

If myDec > 5 Then
        autoRound = roundUp(dblValue)
       
    Else
   
    if myDec = 5 then   
   
            do while Len(myDec)>0 and aux=false and ini<100
                ini=ini+1
                myDec=left(mid(cstr(dblValue),pos+ini),1)       
                if not isNumeric(myDec) then myDec=0       
                if myDec>0 then               
                     aux=true
                end if
               
            loop
       
            if aux=true then
       
                 autoRound = roundUp(dblValue)
       
            else
       
                autoRound = roundDown(dblValue)
               
            end if
       
    else
   
            autoRound = roundDown(dblValue)
   
    end if
   
end if


end function

Response.Write "<br>"
Response.Write "10,66: " & autoRound("10,66") & "<br>"'El output será 11.
Response.Write "10,1: " &autoRound("10,1") & "<br>"'El output será 10.
Response.Write "10,55: " &autoRound("10,55") & "<br>"'El output será 11.
Response.Write "10,5555: " &autoRound("10,5555") & "<br>"'El output será 11.
Response.Write "10,5: " &autoRound("10,5") & "<br>"'El output será 10.
Response.Write "10,51: " &autoRound("10,51") & "<br>"'El output será 10.
Response.Write "10,501: " &autoRound("10,501") & " Este estaría mal si no hiciéramos el loop<br>"'El output será 10.
Response.Write "10,5001: " &autoRound("10,5001") & " Este estaría mal si no hiciéramos el loop<br>"'El output será 10.
Response.Write "10,5000: " &autoRound("10,5000") & " Este estaría mal si no hiciéramos el loop<br>"'El output será 10.
Response.Write "10: " &autoRound("10") & "<br>"'El output será 10.
 

Dejadme salir!!!

Para los que procedáis de PHP como yo mismo, le habréis dado algunas vueltas antes de encontrar el equivalente a Exit en ASP.
Cómo que no funciona la famosa etiqueta? Cuál será la solución? Antes de que empecemos a sudar, la solución es simplemente:
Response.End

Utilizar chr en lugar de caracteres

Como regla general, recomiendo utilizar chr para las sustituciones de tipo replace para
los caracteres especiales, por ejemplo, si quiero sustituir unas comillas,
pensemos en el siguiente código:

dim strPrueba

strPrueba="texto ""de prueba"""

strPrueba=replace(strPrueba,"""","")

No queda claro porque hay un barullo de dobles comillas propio de un lenguaje
como asp.

En su lugar yo utilizaría algo más elegante:
strPrueba=replace(strPrueba,chr(34),"")

Podemos buscarle utilidades interesantes al método chr, el más útil diría yo que es
el carácter que indica retorno de carro.
Esto es útil cuando el texto ha sido insertado desde un textarea. Se trata del carácter 13, el 13 es tu número como
dicen en las pelis americanas.
Con el siguiente source podrás convertir esos caracteres a saltos de html.

textArticle= replace(strPrueba, chr(13),"<br>")

Otra utilidad muy interesante es sustituir barras inclinadas hacia un lado por otras hacia el otro lado.

Otro truco al respecto, podéis saber a qué corresponde cada caracter así:

for i=0 to numMax step 1

Response.Write (i & ":" & chr(i) & "<br>")

next