El descriptor de atributos es un nuevo concepto agregado en ES5, y su función es agregar más control a las propiedades del objeto.
Object.defineProperty
Para estudiar los descriptores de atributos, primero debemos hablar sobre el objeto. DefineProperty Method. El propósito de este método es definir nuevas propiedades para el objeto o modificar las propiedades existentes. El prototipo es el siguiente:
La copia del código es la siguiente:
Object.DefineProperty (OBJ, Prop, Descriptor)
Ejemplo de uso:
La copia del código es la siguiente:
var obj = {};
Objeto.defineProperty (obj, 'attr', {valor: 1});
El código anterior agrega un atributo llamado ATTR al objeto OBJ, con un valor de 1. Equivalente a:
La copia del código es la siguiente:
var obj = {};
obj.attr = 1;
En comparación, la escritura de objeto. DefineProperty parece ser más complicada. Sin embargo, su mayor secreto radica en su tercer parámetro.
Descriptor de datos
Suponiendo que queremos que ATTR sea un atributo de solo lectura, podemos agregar el descriptor de datos de escritura:
La copia del código es la siguiente:
var obj = {};
Objeto.defineProperty (obj, 'attr', {
Valor: 1,
Writable: Falso
});
console.log (obj.attr);
obj.attr = 2; // fallar
console.log (obj.attr);
Ejecute el programa anterior y encontrará que el valor de ATTR imprimido dos veces es 1, lo que significa que la escritura del atributo falló. Sin embargo, este resultado será un poco inexplicable, porque la ejecución de la declaración de asignación no tiene ninguna excepción, pero falla. Solo imagine que si tal problema ocurre en el código de éxito de taquilla, será difícil solucionarlo. De hecho, mientras el código se ejecute en modo estricto, se generará una excepción:
La copia del código es la siguiente:
'Use estricto'; // Ingrese el modo estricto
var obj = {};
Objeto.defineProperty (obj, 'attr', {
Valor: 1,
Writable: Falso
});
obj.attr = 2; // Lanza excepción
Echemos un vistazo a otro descriptor de datos enumerable, lo que puede controlar si el atributo puede ser enumerado. Si simplemente define una propiedad, esta propiedad se puede enumerar en el for ... en bucle:
La copia del código es la siguiente:
var obj = {};
obj.attr = 1;
para (var i en obj) {console.log (obj [i]); }
enumerable puede "ocultarlo":
var obj = {};
Objeto.defineProperty (obj, 'attr', {
Valor: 1,
enumerable: falso
});
para (var i en obj) {console.log (obj [i]); }
Ejecute el código anterior y encontrará que la consola no genera nada, porque el atributo ATTR no puede enumerarse en este momento.
Dicho esto, puede tener una pregunta: ¿se puede modificar el descriptor de atributos? Por ejemplo, ¿se puede definir una propiedad de solo lectura como Writable nuevamente? En realidad, esto depende de otro descriptor de datos configurable, que puede controlar si se puede cambiar el descriptor de atributos.
La copia del código es la siguiente:
var obj = {};
Objeto.defineProperty (obj, 'attr', {
Valor: 1,
Writable: Falso,
configurable: verdadero
});
Objeto.defineProperty (obj, 'attr', {
Writable: verdadero
});
obj.attr = 2;
El código anterior primero define ATTR como un atributo de solo lectura, y luego lo redefine como un escritor. Entonces la escritura a ATTR es exitosa.
Descriptor de acceso
El descriptor de acceso es similar al accesor Get/Set en orientación a objetos.
La copia del código es la siguiente:
var obj = {};
Objeto.defineProperty (obj, 'attr', {
set: function (val) {this._attr = math.max (0, val); },
get: function () {return this._attr; }
});
obj.attr = -1;
console.log (obj.attr); // 0
En el código anterior, el acceso a ATTR en realidad se convierte en acceso a _ATTR, y el valor mínimo se limita a 0 en la función establecida.
Obtener descriptor de atributos
Los mencionados anteriormente son todos los descriptores de atributos de configuración, entonces, ¿cómo obtener los descriptores establecidos? Object.getownPropertyDescriptor puede hacer esto.
La copia del código es la siguiente:
var obj = {};
Objeto.defineProperty (obj, 'attr', {
Valor: 1,
Writable: Falso,
configurable: verdadero
});
var desc = objeto.getownpropertyDescriptor (obj, 'attr');
console.dir (DESC);
Control de objetos
El objeto.defineProperty mencionado anteriormente opera en las propiedades del objeto, mientras que los tres métodos mencionados a continuación funcionan directamente en el objeto.
Object.PreventExtensions puede evitar que los objetos tengan nuevas propiedades:
La copia del código es la siguiente:
var obj = {};
obj.attr = 1;
Object.preventExtensions (obj);
obj.attr2 = 2; //fallar
Object.Seal puede hacer que el objeto solo los valores de propiedad se queden para modificar (si la propiedad es de solo lectura, incluso los valores de la propiedad no se pueden modificar):
La copia del código es la siguiente:
var obj = {};
obj.attr = 1;
Object.Seal (obj);
obj.attr = 1.5;
eliminar obj.attr; // fallar
Object.freeze puede hacer que los objetos sean completamente sin modificar:
La copia del código es la siguiente:
var obj = {};
obj.attr = 1;
Objeto.freeze (obj);
obj.attr = 1.5; // fallar
obj.attr2 = 2; //fallar
Entonces puede preguntar de nuevo, ¿cómo saber si un objeto ha sido preventedExtensions, sello o congelación? La respuesta es llamar a Object.IsExtensible, Object.issealed y Object.Isfrozen respectivamente. El uso de estas tres funciones es relativamente simple y ya no engorroso.
En general, el objeto puede controlarse más estrictamente a través de descriptores de atributos y se fortalece el rigor de la lógica del programa. La única desventaja es que ES5 se implementa básicamente en IE9 (IE9 aún no admite el modo estricto). Teniendo en cuenta que la participación nacional del IE8 sigue siendo relativamente alta, este conjunto de cosas solo se puede usar en navegadores y nodos móviles.js.