tag sirve que para funciona definicion como change caracteristicas javascript variables properties

javascript - sirve - title html



Agregar un alias para una propiedad en JavaScript (2)

Para ampliar la respuesta de @ AndrewLi, hay un montón de cosas similares a alias que puedes hacer con Object.defineProperty() .

  • Alias ​​de solo lectura (igual que su respuesta)
  • El alias sincronizado modifica la fuente cuando se modifica
  • El alias predeterminado lee desde o "por defecto" la fuente hasta que se modifica (en la cual se rompe la relación del punto)

Las escribiré como funciones que relacionan un objeto de origen con la propiedad, sProp y un objeto de destino con la propiedad, tProp . El origen y el destino pueden ser el mismo objeto (lo que permite que una propiedad sea un alias de otra propiedad en el mismo objeto), pero esto no es un requisito. Además, el origen (o destino) puede ser un prototipo (como Object.prototype, String.prototype, etc.)

Asignación "normal"

Este no es realmente un alias, ni utiliza Object.defineProperty() . Al destino se le asigna el VALOR de la fuente, no una referencia a él. Esto significa que cuando la fuente cambia, el objetivo no.

function assign(target, tProp, source, sProp) { target[tProp] = source[sProp]; return target; } let myTarget = {} let mySource = {b: 12} myTarget = assign(myTarget, ''a'', mySource, ''b'') // "alias" was assigned source value console.log(''"alias":'',myTarget.a) // 12 // changes to source independent of "alias" mySource.b = 13 console.log("source:", mySource.b) // 13 console.log(''"alias":'', myTarget.a) // still 12

Alias ​​de solo lectura (la solución anterior)

Cuando la definición de la propiedad no tiene un definidor, es efectivamente un valor de solo lectura. Los cambios en la propiedad de origen se reflejarán en el alias; sin embargo, no puede establecer el valor del alias.

function read(target, tProp, source, sProp){ Object.defineProperty(target, tProp, { enumerable: true, configurable: true, get(){ return source[sProp]; } }) return target; } let myTarget = {} let mySource = {b: 12} myTarget = read(myTarget, ''a'', mySource, ''b'') // Alias gets value from source console.log("alias:", myTarget.a) // 12 // No setter effectively means read-only myTarget.a = 15 console.log("alias:", myTarget.a) // 12 // Changes to source are seen in target mySource.b = 15 console.log("source:", mySource.b) //15 console.log("target:", myTarget.a) //15

Alias ​​sincronizados

Este alias modifica la versión de solo lectura anterior para establecer la propiedad de origen siempre que se establezca la propiedad de alias (destino). De esta manera, la fuente y el destino siempre permanecen sincronizados.

function sync(target, tProp, source, sProp){ Object.defineProperty(target, tProp, { enumerable: true, configurable: true, get(){ return source[sProp]; }, set(value){ source[sProp] = value; } }) return target; } let myTarget = {} let mySource = {b: 12} myTarget = sync(myTarget, ''a'', mySource, ''b'') // Alias gets value from source console.log("alias:", myTarget.a) // 12 // Changing alias'' value modifies the source myTarget.a = 15 console.log("alias:", myTarget.a) // 15 console.log("source:", mySource.b) // 15 // Changing source modifies alias still mySource.b = 20 console.log("source:", mySource.b) // 20 console.log("alias:", myTarget.a) // 20

Alias ​​como predeterminado

Esto le permite predeterminar un valor de alias / destino hasta que se actualice de otro modo. A diferencia del caso de solo lectura, puede cambiar el alias / valor objetivo, pero a diferencia de la sincronización, cuando cambia el alias no actualiza la fuente, en su lugar, el alias se convierte en un valor regular.

function setDefault(target, tProp, source, sProp){ Object.defineProperty(target, tProp, { enumerable: true, configurable: true, get(){ return source[sProp]; }, set(value){ delete target[tProp]; target[tProp] = value; } }) return target; } let myTarget = {} let mySource = {b: 12} myTarget = setDefault(myTarget, ''a'', mySource, ''b'') // Alias gets value from source console.log(''alias:'', myTarget.a) // 12 // Changing source modifies alias still mySource.b = 15 console.log(''source:'', mySource.b) // 15 console.log(''alias:'', myTarget.a) // 15 // Changing alias'' value DOES NOT modify source myTarget.a = 20 console.log("alias:", myTarget.a) // 20 console.log("source:", mySource.b) // 15 // The relationship between source and alias is BROKEN mySource.b = 100 console.log("source:", mySource.b) // 100 console.log("alias:", myTarget.a) // 20

Creo que esto es bastante simple,

¿Existe una forma sencilla de agregar un nombre secundario para una propiedad (creo que esta es específica de String, no estoy seguro), es decir,

c = length // this line pseudo code ''hello world''.length // returns 11 ''hello world''.c // this line is pseudo code, meant to return 11

En el ejemplo anterior, hay un alias creado para la longitud de la propiedad. ¿Es eso posible hacer en JavaScript?


1. Con notación de corchete

Con la notación de corchetes , puede acceder a la propiedad así:

''hello world''[c]

Esto hace lo mismo que ''hello world''.length si c es ''length'' como una cadena.

var c = ''length''; console.log(''hello world''[c]);

La única diferencia es que la propiedad es una cadena. La notación de corchetes es un accesorio de propiedad.

2. Con Object.defineProperty()

Ahora si quieres un alias:

Object.defineProperty(String.prototype, ''c'', { get: function() { return this.length; } }); console.log("hello world".c);

Lo anterior usa Object.defineProperty para definir una propiedad para el objeto existente, el objeto prototype de String. De esa manera, todas las instancias de una cadena tendrán esta nueva propiedad. Según la documentación:

El método Object.defineProperty() define una nueva propiedad directamente en un objeto, o modifica una propiedad existente en un objeto, y devuelve el objeto.

Sintaxis

Object.defineProperty(obj, prop, descriptor)

Donde obj es el objeto que se está modificando, prop es la propiedad nueva o existente y el descriptor es el descriptor de la propiedad nueva o existente.

Por lo tanto, lo anterior define una propiedad para el objeto String.prototype , con el nombre c . Su descriptor es una función de obtener que devuelve la longitud de this . En el ejemplo anterior, this refiere a la cadena por lo que devuelve la longitud de la cadena. Puedes leer más sobre los captadores here .

Esto también se puede definir para más tipos cambiando al prototipo aplicable ( obj ), como usar Object.prototype en Object.prototype lugar. Sin embargo, esto tiene problemas potenciales, ya que tratar de devolver this.length en un objeto sin una propiedad de longitud se volverá indefinido, como se ve here . También puede usar Object.defineProperties para definir múltiples propiedades a la vez.