informatica:programacion:cursos:programacion_avanzada_javascript:notacion_objetos
Diferencias
Muestra las diferencias entre dos versiones de la página.
| Ambos lados, revisión anteriorRevisión previaPróxima revisión | Revisión previa | ||
| informatica:programacion:cursos:programacion_avanzada_javascript:notacion_objetos [2024/10/16 12:26] – [DEMO: Prototipos en funciones constructoras] tempwin | informatica:programacion:cursos:programacion_avanzada_javascript:notacion_objetos [2024/10/30 13:01] (actual) – [Propiedades con nombre dinámico] tempwin | ||
|---|---|---|---|
| Línea 124: | Línea 124: | ||
| En el caso del uso de funciones constructoras, | En el caso del uso de funciones constructoras, | ||
| - | <WRAP center round todo 60%> | + | {{ : |
| - | Cambio de Foo.prototype | + | |
| - | </ | + | |
| En la imagen anterior el valor de '' | En la imagen anterior el valor de '' | ||
| Línea 180: | Línea 178: | ||
| ===== DEMO: Prototipos en funciones constructoras - herencia ===== | ===== DEMO: Prototipos en funciones constructoras - herencia ===== | ||
| + | Veamos cómo utilizar el prototipo en funciones constructoras para crear relaciones de herencia. | ||
| + | |||
| + | Partimos del siguiente código: | ||
| + | |||
| + | <code javascript> | ||
| + | var Animal = function() { | ||
| + | }; | ||
| + | |||
| + | var a = new Animal(); | ||
| + | </ | ||
| + | |||
| + | '' | ||
| + | |||
| + | <code javascript> | ||
| + | var b = new Animal(); | ||
| + | |||
| + | console.log(a.__proto__ === b.__proto__); | ||
| + | </ | ||
| + | |||
| + | Modificamos ahora la función constructora: | ||
| + | |||
| + | <code javascript> | ||
| + | var Animal = function() { | ||
| + | this.comer = function() { | ||
| + | console.log(" | ||
| + | } | ||
| + | }; | ||
| + | </ | ||
| + | |||
| + | Ahora crearemos una función constructura que permita crear objetos derivados de la otra función '' | ||
| + | |||
| + | <code javascript> | ||
| + | var Perro = function() { | ||
| + | this.ladrar = function() { | ||
| + | console.log(" | ||
| + | } | ||
| + | }; | ||
| + | </ | ||
| + | |||
| + | <code javascript> | ||
| + | Establecemos una relación de jerarquía / herencia entre Perro y Animal | ||
| + | Perro.prototype = new Animal(); | ||
| + | |||
| + | var a = new Animal(); | ||
| + | |||
| + | console.log(a.__proto__ === Animal.prototype); | ||
| + | |||
| + | var p = new Perro(); | ||
| + | |||
| + | console.log(p.__proto__ === Perro.prototype); | ||
| + | </ | ||
| + | |||
| + | Al haber establecido una relación de jerarquía / herencia gracias a que JavaScript utiliza la cadena de prototipos, podemos hacer lo siguiente: | ||
| + | |||
| + | <code javascript> | ||
| + | p.comer(); | ||
| + | </ | ||
| + | |||
| + | JavaScript no lo encontrará en '' | ||
| ===== Prototipos en ECMAScript 2015 ===== | ===== Prototipos en ECMAScript 2015 ===== | ||
| + | Una de las novedades de ECMAScript 6 es que **soporta oficialmente la propiedad '' | ||
| + | |||
| + | Puede parecer raro que algo que no existía en la versión 5 pase a existir directamente como obsoleto en la versión 6 del estándar. La razón es que el estándar incorpora '' | ||
| + | |||
| + | La razón de que se considere obsoleta es que **ECMAScript 6 incorpora sus propios mecanismos para obtener y establecer el prototipo de un objeto una vez creado éste**. | ||
| + | |||
| + | <WRAP center round important 60%> | ||
| + | Importante: A pesar de que en ECMAScript 6 cambiar el prototipo de un objeto sea una operación soportada, debemos tener presente que el impacto en rendimiento es importante. Mejor evitarlo siempre que sea posible. | ||
| + | </ | ||
| + | |||
| + | Para obtener el prototipo de un objeto podemos usar '' | ||
| + | |||
| + | <code javascript> | ||
| + | var Foo = function() {}; | ||
| + | var f1 = new Foo(); | ||
| + | console.log(Object.getPrototypeOf(f1) === Foo.prototype) | ||
| + | console.log(Reflect.getPrototypeOf(f1) === Foo.prototype) | ||
| + | </ | ||
| + | |||
| + | Y para establecer el prototipo de un objeto se puede usar '' | ||
| + | |||
| + | <code javascript> | ||
| + | var obj = Object.create({name: | ||
| + | console.log(obj.name); | ||
| + | Object.setPrototypeOf(obj, | ||
| + | console.log(obj.name); | ||
| + | console.log(obj.age); | ||
| + | </ | ||
| + | |||
| + | ==== Establecer el prototipo en notación de objeto ==== | ||
| + | |||
| + | Una de las novedades de ECMAScript 6 es que **permite establecer el prototipo de un objeto creado con notación de objeto**. Para ello basta con declarar una propiedad '' | ||
| + | |||
| + | <code javascript> | ||
| + | var a={answer: 42}; | ||
| + | var obj={ | ||
| + | question: 'what is the sense of life, the universe and everything?', | ||
| + | __proto__: a | ||
| + | } | ||
| + | console.log(obj.question, | ||
| + | </ | ||
| + | |||
| + | Se puede ver que '' | ||
| + | |||
| + | {{ : | ||
| ===== Propiedades con nombre dinámico ===== | ===== Propiedades con nombre dinámico ===== | ||
| + | Desde siempre hemos podido construir objetos con una propiedad cuyo nombre fuese dinámico, es decir dependiese de cualquier operación en tiempo de ejecución. El siguiente código crea un objeto con un método que se llama '' | ||
| + | |||
| + | <code javascript> | ||
| + | var a = {}; | ||
| + | a[" | ||
| + | </ | ||
| + | |||
| + | Una vez se ha creado esa propiedad podemos acceder a ella con la notación de punto o de array, siendo ambas equivalentes: | ||
| + | |||
| + | {{ : | ||
| + | |||
| + | |||
| + | Ahora bien, en **ECMAScript 5 solo podemos crear esas propiedades, | ||
| + | |||
| + | Una de las novedades en ECMAScript 2015 consiste en que también podemos declarar esas propiedades utilizando notación de objeto: | ||
| + | |||
| + | <code javascript> | ||
| + | var a={ | ||
| + | [" | ||
| + | }; | ||
| + | </ | ||
| + | |||
| + | Observa como el nombre de la propiedad es realmente una cadena y se coloca entre corchetes. Debes usar los corchetes porque sino obtendrás errores de sintaxis. Los corchetes sirven para indicarle al //parser// dónde empieza y termina la expresión que genera el nombre de la propiedad. | ||
| + | |||
| + | ==== Nombres de propiedades duplicadas ==== | ||
| + | |||
| + | En ECMAScript 5, en modo estricto, declarar un objeto con nombres de propiedades duplicadas generaba un error de sintaxis. Es lógico puesto que no tiene mucho sentido declarar un objeto con una propiedad definida más de una vez: | ||
| + | |||
| + | <code javascript> | ||
| + | var a= {p: 20, p:30}; | ||
| + | </ | ||
| + | |||
| + | Pero si pruebas este código en un entorno ECMAScript 2015 incluso con el modo estricto habilitado, verás que no produce error alguno. | ||
| + | |||
| + | A partir de ECMAScript 2015 esta restricción se ha eliminado. La razón es que ahora, al poder usar nombres de propiedades dinámicos, puede ocurrir que una propiedad con nombre dinámico genere el mismo nombre que otra propiedad, digamos " | ||
| + | |||
| + | <code javascript> | ||
| + | var a={p:20, p:30}; | ||
| + | console.log(a.p); | ||
| + | </ | ||
| ===== Métodos y propiedades simplificadas ===== | ===== Métodos y propiedades simplificadas ===== | ||
| + | Acostúmbrate a la " | ||
| + | |||
| + | Imagina un objeto '' | ||
| + | |||
| + | <code javascript> | ||
| + | var hello = { | ||
| + | greetings: function(name) { | ||
| + | return "hello " + name; | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Pues bien, ahora tenemos disponible una **sintaxis simplificada** para métodos, que te permite declarar exactamente este mismo objeto sin necesidad de la palabra clave '' | ||
| + | |||
| + | <code javascript> | ||
| + | var hello = { | ||
| + | greetings(name) { | ||
| + | return "hello " + name; | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Esa sintaxis simplificada puedes usarla también para //getters// y //setters// de propiedades: | ||
| + | |||
| + | <code javascript> | ||
| + | var hello = { | ||
| + | get salute() {return " | ||
| + | } | ||
| + | console.log(hello.salute); | ||
| + | </ | ||
| + | |||
| + | Un ejemplo un poco más completo, donde muestra un //getter// y un //setter// simulando una variable privada cuyo valor debe ser siempre positivo: | ||
| + | |||
| + | <code javascript> | ||
| + | var hello = (() => { | ||
| + | var _private = 42; | ||
| + | return { | ||
| + | get value() {return _private}, | ||
| + | set value(v) { | ||
| + | if (v > 0) { | ||
| + | _private = v; | ||
| + | } | ||
| + | return _private; | ||
| + | } | ||
| + | } | ||
| + | })(); | ||
| + | console.log(hello.value); | ||
| + | hello.value = -10; | ||
| + | console.log(hello.value); | ||
| + | hello.value = 20; | ||
| + | console.log(hello.value); | ||
| + | </ | ||
| ===== DEMO: Novedades en notación de objetos ===== | ===== DEMO: Novedades en notación de objetos ===== | ||
| + | |||
| + | Repaso de las 4 novedades importantes de **ECMAScript 6** en notación de objetos. | ||
| + | |||
| + | Posibilidad de **especificar el prototipo** del objeto en notación del objeto a la vez que declaramos el objeto: | ||
| + | |||
| + | <code javascript> | ||
| + | var a = {name: " | ||
| + | |||
| + | var b = { | ||
| + | __proto__: a, | ||
| + | cursos: [" | ||
| + | } | ||
| + | |||
| + | b.name; // -> ' | ||
| + | </ | ||
| + | |||
| + | Antes no se podía hacer, era necesario el uso de '' | ||
| + | |||
| + | Otra de las novedades son las **propiedades con nombre dinámico**: | ||
| + | |||
| + | <code javascript> | ||
| + | var b = { | ||
| + | __proto__: a, | ||
| + | cursos: [" | ||
| + | [" | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Lo ejecutamos: | ||
| + | |||
| + | <code javascript> | ||
| + | b; // -> Object { cursos: Array[1], i_0.123412341234: | ||
| + | </ | ||
| + | |||
| + | En ECMAScript 5 podíamos hacer: | ||
| + | |||
| + | <code javascript> | ||
| + | b[" | ||
| + | </ | ||
| + | |||
| + | Pero no podíamos hacerlo en la declaración de un objeto. | ||
| + | |||
| + | Otra novedad más es una **sintaxis simplificada para declarar funciones**. | ||
| + | |||
| + | <code javascript> | ||
| + | var b = { | ||
| + | __proto__: a, | ||
| + | cursos: [" | ||
| + | [" | ||
| + | foo(p) {return p + 1} // No es necesario usar ' | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Finalmente, otra característica nueva son los //shorthand properties names//: | ||
| + | |||
| + | <code javascript> | ||
| + | var url = " | ||
| + | |||
| + | var options = { | ||
| + | url, // en lugar de url: url | ||
| + | method: " | ||
| + | }); | ||
| + | </ | ||
informatica/programacion/cursos/programacion_avanzada_javascript/notacion_objetos.1729074418.txt.gz · Última modificación: por tempwin
