Es un buen momento para JavaScript. No solo se está convirtiendo en un lenguaje mucho más respetado, sino que también está creciendo a pasos agigantados, tanto en popularidad como en características. A medida que más navegadores comienzan a implementar las características del estándar de la quinta edición de ECMAScript, JavaScript se convierte en una plataforma aún más poderosa para su desarrollo. En este tutorial, hablaremos sobre los nuevos métodos que están disponibles para usted..
ECMAScript es el nombre oficial de lo que todos llamamos JavaScript. Eso no significa que estemos equivocados; es solo que el nombre "JavaScript" es una marca registrada de Oracle; por lo tanto, Ecma International (originalmente la Asociación Europea de Fabricantes de Computadoras, por lo tanto, ECMA) usa el término "ECMAScript" para referirse al estándar de JavaScript. La última versión de este estándar es la 5ª edición y fue aprobada hace poco más de un año (el 3 de diciembre de 2009). Abarca una amplia gama de grandes adiciones, y varias de ellas están empezando a aparecer en los navegadores. Las implementaciones de ECMAScript 5 se llama JavaScript 1.8.5..
En este tutorial, veremos las funciones de JavaScript 1.8.5 que están disponibles para nosotros en las versiones beta de Firefox 4. Te alegrará descubrir que la mayoría de las últimas versiones de otros navegadores también tienen estos ... excepto uno. Esta vez, es Opera, ya que IE9 ha incluido muchos de estos.
Este método es muy importante; Realmente limpia la herencia prototípica. Anteriormente (en la 3ª edición de ECMAScript), para crear un objeto y configurar su prototipo, haría algo como esto:
función Cat (nombre) este.nombre = nombre; this.paws = 4; this.hungry = falso; this.eaten = []; Cat.prototype = constructor: Cat, play: function () this.hungry = true; vuelve "jugando!"; , feed: function (food) this.eaten.push (food); this.hungry = falso; , habla: function () return "Meow";
¿Soy el único que piensa que parece extraño tener el prototipo? fuera de ¿La función constructora? Y la herencia se vuelve aún más desordenada. Con Object.create
, Las cosas se ponen mucho más fáciles. Lo anterior podría ser codificado así:
var dog = nombre: "dog", patas: 4, hambriento: falso, comido: nulo, play: function () this.hungry = true; vuelve "jugando!"; , feed: function (food) if (! this.eaten) this.eaten = []; this.eaten.push (comida); this.hungry = falso; , habla: function () return "Woof!" ; var my_dog = Object.create (dog);
Lo que está pasando aquí es esto: estoy llamando object.create
, pasándole un objeto para usarlo como prototipo del nuevo objeto que Object.create
está regresando Cuando usas Object.create
, No tengo que preocuparme por definir el prototipo por separado. De hecho, tengo mucha más flexibilidad para decidir cómo crear y heredar objetos. Por ejemplo, no puedo poner el comido
matriz en el prototipo, porque una matriz es un valor de referencia, por lo que cada objeto creado a partir de perro
compartirá esa matriz. He decidido comprobarlo antes de usarlo aquí, pero si quisiera envolverlo Object.create (perro)
en un make_dog
función, podría asignarlo allí tan fácilmente.
Eso es lo bueno de Object.create
; puedes elegir como hacerlo.
Hay un segundo parámetro que Object.create
toma; Es un objeto descriptor de propiedades. Es un poco complicado, pero también es una parte de la siguiente función que veremos, así que echemos un vistazo.
Si tienes un objeto en el que quieres definir una propiedad, probablemente lo harás de esta manera:
my_dog.age = 2;
Esto aún funciona bien en ES5, pero si desea un control más preciso, puede tenerlo con Object.defineProperty
. El primer parámetro es el objeto al que está asignando la propiedad. El segundo parámetro es el nombre de la propiedad, como una cadena. La propiedad final es el objeto descriptor. Así es como funciona eso. Es (obviamente) un objeto y puede tener una combinación de las siguientes propiedades, todas las cuales describen la propiedad que estamos agregando:
indefinido
.cierto
. Por defecto a falso
.cierto
. Por defecto a falso
.falso
.indefinido
.indefinido
.Tenga en cuenta que los valores predeterminados para las opciones booleanas anteriores son el reverso de la anterior obj.prop = val
normas Además, debes saber que no puedes definir valor
o escribible
cuando obtener
o conjunto
Se definen, y viceversa..
Entonces, ¿cómo usarías esto? Prueba esto:
// asume my_dog de Object.defineProperty anterior (my_dog, "age", set: function (age) this.human_years = age * 7;, get: function () return this.human_years / 7;, enumerable : cierto ); my_dog.age = 2; my_dog.human_years; // 14
Aparte del hecho de que los años de los perros no son realmente 7 años humanos, debes notar que no establecimos valor
o escribible
aquí, porque estamos usando obtener
y conjunto
. Estas funciones nunca son accedidas directamente. Se ejecutan "mágicamente" detrás de escena cuando asigna o solicita una propiedad. En este ejemplo, estoy usando estas funciones para mantener años
y human_years
en "sincronización". Si no desea que se pueda acceder al "otro" valor, puede usar una función anónima de auto-invocación para ocultarlo con el cierre:
Object.defineProperty (my_dog, "age", (function () var human_years; return set: function (age) human_years = age * 7;, get: function () return human_years / 7;, enumerable: cierto ; ()));
Por supuesto, no hay nada que te impida hacer algo estúpido por dentro. obtener
o conjunto
, así que úsalo sabiamente.
Puede utilizar una forma del objeto descriptor de propiedad para agregar propiedades a los objetos con Object.create
. Hazlo de la siguiente manera:
var your_dog = Object.create (dog, age: get: function () / *… * /, set: function () / *… * /, enumerable: true, gender: value: " femenino ");
Simplemente use el nombre de la propiedad como una propiedad del objeto descriptor; luego, establezca los atributos a través de un objeto en el valor.
Si desea definir varias propiedades a la vez, puede usar un objeto de descriptores de propiedades al igual que con Object.create
para definirlos, utilizando Object.defineProperties
.
Object.defineProperties (my_dog, age: get: function () / *… * /, set: function () / *… * /, enumerable: true, gender: value: "female" );
Deberá tener en cuenta, en el caso excepcional de que no esté utilizando un objeto literal como segundo parámetro, que solo se utilizarán las propiedades enumerables del objeto de propiedades..
Si alguna vez desea conocer los detalles de una propiedad, puede utilizar esta función, Object.getOwnPropertyDescriptor
. Tome nota de la "Propia"; esto solo funciona con las propiedades del objeto en sí, no con su cadena de prototipo.
var person = nombre: "Joe"; Object.getOwnPropertyDescriptor (persona, "nombre"); // configurable: true, enumerable: true, valor: "Joe", escribible: true
Como puede ver, esto funciona con las propiedades establecidas tanto en la forma antigua como en la nueva.. Object.getOwnPropertyDescriptor
toma dos parámetros: el objeto y el nombre de la propiedad como una cadena.
¿Alguna vez has querido conseguir todas las llaves de un objeto? Ahora, puedes hacerlo fácilmente con Object.keys
. Pase a esta función un objeto y devolverá una matriz de todas las propiedades enumerables de ese objeto. También puede pasarle una matriz, y obtendrá una matriz de los índices.
var horse = nombre: "Ed", edad: 4, trabajo: "saltando", propietario: "Jim"; var horse_keys = Object.keys (horse); // ["nombre", "edad", "trabajo", "propietario"];
Este es como Object.keys
, excepto que incluye todas las propiedades, incluso las que no son enumerable Por el nombre más largo de la función, puedes decir que desalientan su uso. Por lo general, querrás llaves
en lugar.
Si alguna vez ha querido crear una función que no acepte nuevos parámetros, puede hacerlo ahora. Ejecuta tu objeto a través Object.preventExtensions
, y rechazará todos los intentos de agregar nuevos parámetros. Esta función va de la mano con Object.isExtensible
, que devuelve cierto
si puedes extender el objeto y falso
si no puedes.
var producto = nombre: "Foobar", calificación: 3.5; Object.isExtensible (producto); // true Object.preventExtentions (producto); Object.isExtensible (producto); // false product.price = "$ 10.00"; // no funciona product.price; // indefinido
Debe tener en cuenta que todas las propiedades del objeto en el momento de ejecutar Object.preventExtensions
Todavía se puede cambiar o eliminar (suponiendo que sus atributos lo permitan).
Sellar un objeto es un paso adelante para evitar extensiones. Un objeto sellado no le permitirá agregar o eliminar propiedades, o cambiar las propiedades de un valor (como una cadena) a un elemento de acceso (un método) o viceversa. Todavía podrás leer y escribir propiedades, por supuesto. Puedes averiguar si un objeto está sellado usando Object.isSealed
.
var pet = nombre: "Navegador", escribe: "perro"; Object.seal (mascota); pet.name = "Oreo"; pet.age = 2; // no funciona pet.type = function () / ** /; // no funciona borrar pet.name; // no funciona
Congelarlo un paso más. Un objeto congelado no puede ser cambiado de ninguna manera; es de sólo lectura. Puedes verificar la congelación de un objeto, lo has adivinado, Object.isFrozen
.
var obj = saludo: "Hola!" ; Object.freeze (obj); Object.isFrozen (obj); // cierto
Usted pensaría que no sería demasiado difícil determinar que una variable dada es una matriz. Después de todo, todo lo demás funciona bien con el tipo de
operador. Sin embargo, las matrices de JavaScript son de tipo inconsistente. En realidad, son objetos más parecidos a una matriz (aunque generalmente usamos ese término para referirnos a cosas como argumentos
y NodeList
s). Esta función le brinda una forma de estar 100% seguro de que está trabajando con una matriz. Pásale una variable, y devuelve el booleano..
nombres var = ["Collis", "Cyan"]; Array.isArray (nombres); // cierto
Para más información sobre por qué necesitamos esta función, echa un vistazo a los documentos, vinculados a continuación.
Esto no es demasiado grande, pero si alguna vez desea almacenar fechas en JSON, puede que le resulte útil. Los objetos de fecha ahora tienen una aJSON
Función que convertirá la fecha en una fecha de cadena JSON..
nueva fecha (). toJSON (); // "2010-12-06T16: 25: 40.040Z"
Probablemente estés familiarizado con el uso llamada
y aplicar
para reasignar el valor de esta
en una función.
var arr1 = ["1", "2", "3"], arr2 = ["4", "5", "6"]; Array.prototype.push.apply (arr1, arr2);
Estos métodos le permiten cambiar el valor de esta
dentro de una función. Si quieres hacer algo así a menudo., Function.prototype.bind
devuelve una nueva función con esta
atado a lo que pase, para que pueda guardarlo en una variable.
var tooltip = text: "Haga clic aquí para ...", overlay = text: "Ingrese el número de asistentes"; function show_text () // realmente, haga algo más útil aquí console.log (this.text); tooltip.show = show_text.bind (tooltip); tooltip.show (); overlay.show = show_text.bind (overlay); overlay.show ();
Por supuesto, este podría no ser el ejemplo más práctico, pero te da la idea!
Esas son las funciones ECMAScript 5th Edition (o JavaScript 1.8.5) que se han agregado a las versiones beta de Firefox 4. También se están implementando algunos otros cambios en JavaScript, que puede consultar en las notas de la versión..
Sin embargo, hay un montón de funciones de ECMAScipt 5 que ya eran compatibles con Firefox 3 y varios otros navegadores. ¿Has jugado con alguno de estos?
Nota: estos están vinculados a su documentación MDN..
Si desea ver qué navegadores y versiones son compatibles con estas funciones, puede consultar esta tabla de compatibilidad, realizada por Juriy Zaytsev (Kangax). Lo bueno de la mayoría de estas funciones es que si un navegador no lo admite, generalmente puedes agregar soporte, con algo como esto:
if (typeof Object.create! == 'function') Object.create = function (o) function F () F.prototype = o; devolver nuevo F (); ; // Cortesía de Douglas Crockford: http://javascript.crockford.com/prototypal.html
La gran cantidad de funciones nuevas que hemos visto aquí es en realidad solo una pequeña parte de la bondad agregada al estándar ECMAScript en la quinta edición. ¿Hay alguna otra característica que desees usar específicamente, o quizás incluso usar ahora mismo? Vamos aquí en los comentarios.!