O descritor de atributos é um novo conceito adicionado ao ES5, e sua função é adicionar mais controle às propriedades do objeto.
Object.DefineProperty
Para estudar descritores de atributos, devemos primeiro falar sobre o objeto.DefineProperty. O objetivo deste método é definir novas propriedades para o objeto ou modificar as propriedades existentes. O protótipo é o seguinte:
A cópia do código é a seguinte:
Object.DefineProperty (OBJ, prop, descritor)
Exemplo de uso:
A cópia do código é a seguinte:
var obj = {};
Object.DefineProperty (obj, 'att', {value: 1});
O código acima adiciona um atributo chamado Att ao objeto OBJ, com um valor de 1. Equivalente a:
A cópia do código é a seguinte:
var obj = {};
obj.attr = 1;
Em comparação, a redação do object.DefineProperty parece ser mais complicada. No entanto, seu maior segredo está em seu terceiro parâmetro.
Descritor de dados
Supondo que queremos que o ATTR seja um atributo somente leitura, podemos adicionar o descritor de dados graváveis:
A cópia do código é a seguinte:
var obj = {};
Object.DefineProperty (obj, 'att', {
Valor: 1,
gravável: falso
});
console.log (obj.attr);
obj.attr = 2; // falhar
console.log (obj.attr);
Execute o programa acima e você descobrirá que o valor do atribuído impresso duas vezes é 1, o que significa que a redação do atributo falhou. No entanto, esse resultado será um pouco inexplicável, porque a execução da declaração de atribuição não tem nenhuma exceção, mas falha. Imagine que, se esse problema ocorrer no código de sucesso de bilheteria, será difícil solucioná -lo. De fato, desde que o código seja executado no modo rigoroso, será gerada uma exceção:
A cópia do código é a seguinte:
'Use rigoroso'; // Digite o modo rigoroso
var obj = {};
Object.DefineProperty (obj, 'att', {
Valor: 1,
gravável: falso
});
obj.attr = 2; // Exceção de lançamento
Vamos dar uma olhada em outro descritor de dados enumerável, que pode controlar se o atributo pode ser enumerado. Se você simplesmente definir uma propriedade, essa propriedade pode ser enumerada no para ... em loop:
A cópia do código é a seguinte:
var obj = {};
obj.attr = 1;
para (var i em obj) {console.log (obj [i]); }
enumerável pode "esconder" isso:
var obj = {};
Object.DefineProperty (obj, 'att', {
Valor: 1,
enumerável: falso
});
para (var i em obj) {console.log (obj [i]); }
Execute o código acima e você descobrirá que o console não gera nada, porque o atributo ATTR não pode ser enumerado neste momento.
Dito isto, você pode ter uma pergunta: o descritor do atributo pode ser modificado? Por exemplo, uma propriedade somente leitura pode ser definida como gravável novamente? Na verdade, isso depende de outro descritor de dados configurável, que pode controlar se o descritor do atributo pode ser alterado.
A cópia do código é a seguinte:
var obj = {};
Object.DefineProperty (obj, 'att', {
Valor: 1,
gravável: falso,
Configurável: Verdadeiro
});
Object.DefineProperty (obj, 'att', {
gravável: verdadeiro
});
obj.attr = 2;
O código acima define primeiro o Att como um atributo somente leitura e depois o redefine como um gravador. Portanto, a redação para o Att é bem -sucedida.
Descritor de acesso
O descritor de acesso é semelhante ao acessador GET/Set em Orientado a objetos.
A cópia do código é a seguinte:
var obj = {};
Object.DefineProperty (obj, 'att', {
set: function (val) {this._attr = math.max (0, val); },
get: function () {return this._attr; }
});
obj.attr = -1;
console.log (obj.attr); // 0
No código acima, o acesso ao Att realmente se torna acesso a _ATTR, e o valor mínimo é limitado a 0 na função definida.
Obtenha o descritor de atributos
Os mencionados acima são todos descritores de atributos de configuração, então como obter os descritores de conjuntos? Object.GetownPropertyDescriptor pode fazer isso.
A cópia do código é a seguinte:
var obj = {};
Object.DefineProperty (obj, 'att', {
Valor: 1,
gravável: falso,
Configurável: Verdadeiro
});
var desc = object.getownPropertyDescriptor (obj, 'att');
console.dir (desc);
Controle de objetos
O object.DefineProperty mencionado anteriormente opera nas propriedades do objeto, enquanto os três métodos mencionados abaixo operam diretamente no objeto.
Object.PreventExtensions pode impedir que os objetos tenham novas propriedades:
A cópia do código é a seguinte:
var obj = {};
obj.attr = 1;
Object.PreventExtensions (OBJ);
obj.attr2 = 2; //falhar
Object.Seal pode fazer com que o objeto somente os valores da propriedade deixados para modificar (se a propriedade for somente leitura, mesmo os valores da propriedade não podem ser modificados):
A cópia do código é a seguinte:
var obj = {};
obj.attr = 1;
Object.Seal (OBJ);
obj.attr = 1.5;
excluir obj.attr; // falhar
Object.Freeze pode tornar os objetos completamente não modificados:
A cópia do código é a seguinte:
var obj = {};
obj.attr = 1;
Object.Freeze (OBJ);
obj.attr = 1.5; // falhar
obj.attr2 = 2; //falhar
Então você pode perguntar novamente: como você sabe se um objeto foi preventido, sele, selar ou congelar? A resposta é chamar Object.Sextensible, Object.iSiSealed e Object.isfrozen, respectivamente. O uso dessas três funções é relativamente simples e não é mais pesado.
Em geral, o objeto pode ser mais rigorosamente controlado através dos descritores de atributos e o rigor da lógica do programa é fortalecido. A única desvantagem é que o ES5 é basicamente implementado no IE9 (o IE9 ainda não suporta modo rigoroso). Considerando que a participação doméstica do IE8 ainda é relativamente alta, esse conjunto de coisas só pode ser usado em navegadores móveis e node.js.