cuando se utiliza el objeto.defineProperty()
Me pregunto cuándo debo usar
Object.defineProperty
Para crear nuevas propiedades para un objeto. Soy consciente de que soy capaz de establecer cosas como
enumerable: false
Pero ¿cuándo necesitas esto realmente? Si acaba de establecer una propiedad como
myObject.myprop = 5;
Sus descriptores están todos en true, ¿verdad? De hecho, tengo más curiosidad cuando ustedes usan esa llamada bastante detallada .defineProperty() y por qué razones.
7 answers
Object.defineProperty
se utiliza principalmente para establecer propiedades con descriptores de propiedad específicos (por ejemplo, solo lectura (constantes), enumerabilidad( para no mostrar una propiedad en un for (.. in ..)
loop, getters, setters).
"use strict";
var myObj = {}; // Create object
// Set property (+descriptor)
Object.defineProperty(myObj, 'myprop', {
value: 5,
writable: false
});
console.log(myObj.myprop);// 5
myObj.myprop = 1; // In strict mode: TypeError: myObj.myprop is read-only
Ejemplo
Este método extiende el prototipo Object
con una propiedad. Solo se define el getter, y la enumerabilidad se establece en false
.
Object.defineProperty(Object.prototype, '__CLASS__', {
get: function() {
return Object.prototype.toString.call(this);
},
enumerable: false // = Default
});
Object.keys({}); // []
console.log([].__CLASS__); // "[object Array]"
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-04-11 12:29:59
Características como 'enumerable' rara vez se utilizan en mi experiencia. El caso de uso principal son las propiedades calculadas:
var myObj = {};
myObj.width = 20;
myObj.height = 20;
Object.defineProperty(myObj, 'area', {
get: function() {
return this.width*this.height;
}
});
console.log(myObj.area);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-20 13:38:09
Una muy buena razón para usar Object.defineProperty es que le permite recorrer una función en un objeto como una propiedad calculada, que ejecuta la función en lugar de devolver el cuerpo de la función.
Por ejemplo:
var myObj = {};
myObj.width = 20;
myObj.height = 20;
Object.defineProperty(myObj, 'area', {
get: function() {
return this.width*this.height;
},
enumerable: true
});
for (var key in myObj) {
if (myObj.hasOwnProperty(key)) {
console.log(key + " -> " + myObj[key]);
}
}
//width -> 20, height -> 20, area -> 400
Versus agregar la función como una propiedad a un objeto literal:
var myObj = {};
myObj.width = 20;
myObj.height = 20;
myObj.area = function() {
return this.width*this.height;
};
for (var key in myObj) {
if (myObj.hasOwnProperty(key)) {
console.log(key + " -> " + myObj[key]);
}
}
// width -> 20, height -> 20, area -> function() { return this.width*this.height;}
Asegúrese de establecer la propiedad enumerable en true para recorrer el bucle.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-06 11:37:51
Un buen caso de uso que he visto para defineProperty
es que las bibliotecas proporcionen una propiedad de error al usuario que, si no se accede dentro de un cierto intervalo, se lanzaría usted mismo. Por ejemplo:
let logErrorTimeoutId = setTimeout(() => {
if (error) {
console.error('Unhandled (in <your library>)', error.stack || error);
}
}, 10);
Object.defineProperty(data, 'error', {
configurable: true,
enumerable: true,
get: () => {
clearTimeout(logErrorTimeoutId);
return error;
},
});
Fuente de este código: https://github.com/apollographql/react-apollo/blob/ddd3d8faabf135dca691d20ce8ab0bc24ccc414e/src/graphql.tsx#L510
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-22 18:38:32
Un buen uso es cuando necesitas hacer alguna intercepción o aplicar un patrón de Observador/Observable clásico de una manera elegante:
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-06 14:30:51
Resumen:
En Javascript los objetos son colecciones de pares clave-valor.
Object.defineProperty()
es una función que puede definir una nueva propiedad en un objeto y puede establecer los siguientes atributos de una propiedad:
-
valor
<any>
: El valor asociado con la clave -
escribible
<boolean>
: si writable se establece entrue
La propiedad se puede actualizar asignándole un nuevo valor. Si se establece enfalse
no se puede cambiar el valor. -
enumerable
<boolean>
: si enumerable se establece en la propiedadtrue
se puede acceder a través de un buclefor..in
. Además, son las únicas claves de propiedad enumerables devueltas conObject.keys()
-
configurable
<boolean>
: Si configurable se establece enfalse
no puede cambiar cambiar los atributos de propiedad (valor/escribible/enumerable/configurable), también como no puede cambiar el valor no puede eliminarlo usando el operadordelete
.
Ejemplo:
let obj = {};
Object.defineProperty(obj, 'prop1', {
value: 1,
writable: false,
enumerable: false,
configurable: false
}); // create a new property (key=prop1, value=1)
Object.defineProperty(obj, 'prop2', {
value: 2,
writable: true,
enumerable: true,
configurable: true
}); // create a new property (key=prop2, value=2)
console.log(obj.prop1, obj.prop2); // both props exists
for(const props in obj) {
console.log(props);
// only logs prop2 because writable is true in prop2 and false in prop1
}
obj.prop1 = 100;
obj.prop2 = 100;
console.log(obj.prop1, obj.prop2);
// only prop2 is changed because prop2 is writable, prop1 is not
delete obj.prop1;
delete obj.prop2;
console.log(obj.prop1, obj.prop2);
// only prop2 is deleted because prop2 is configurable and prop1 is not
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-04 18:26:08
@Gerard Simpson
Si 'área' debe ser enumerable se puede escribir sin Objeto.Definitivamente propiedad, también.
var myObj = {
get area() { return this.width * this.height }
};
myObj.width = 20;
myObj.height = 20;
for (var key in myObj) {
if (myObj.hasOwnProperty(key)) {
console.log(key + " -> " + myObj[key]);
}
}
//area -> 400, width -> 20, height -> 20
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-11 11:22:29