Este artigo traz a você conhecimento relevante sobre JavaScript, que apresenta principalmente questões relacionadas à orientação a objetos, incluindo descritores de atributos, descritores de dados, descritores de acesso, etc.
[Recomendações relacionadas: tutorial em vídeo javascript, front-end da web]
Na verdade, o JavaScript suporta uma variedade de paradigmas de programação, incluindo programação funcional e programação orientada a objetos:
Objetos em JavaScript são projetados como uma coleção não ordenada de atributos , como uma tabela de hip-hop, composta por chaves e valores;
A chave é um nome identificador e o valor pode ser de qualquer tipo ou outro tipo de objeto ou função;
Se o valor for uma função, podemos chamá-lo de método do objeto ;
A maneira mais comum de criar objetos no início é usar a classe Object e usar a palavra-chave new para criar um objeto e, em seguida, armazenar as propriedades ou métodos no objeto:
var obj = novo objeto() obj.name = 'por que' console.log(obj.name, obj) // por que { nome: 'por que' }
Mais tarde, por conveniência, muitos desenvolvedores criaram objetos diretamente na forma de literais:
//Método literal var obj2 = { nome: 'jam', idade: '8' } console.log(obj) // { nome: 'jam', idade: '8' }
Anteriormente, nossas propriedades eram definidas diretamente dentro do objeto ou adicionadas diretamente ao objeto;
Mas desta forma não podemos impor algumas restrições a este atributo: por exemplo, este atributo pode ser excluído através de delect
e pode ser percorrido durante a travessia for-in
?
Se quisermos ter um controle operacional mais preciso sobre um atributo, então posso usar descritores de atributos . As propriedades de um objeto podem ser adicionadas ou modificadas com precisão por meio de descritores de propriedades;
Os descritores de propriedades precisam usar Object.defineProperty
para adicionar ou modificar propriedades.
属性描述符分为两种:数据描述符和存取描述符
Um descritor de dados é uma propriedade com um valor que pode ou não ser gravável. O descritor de dados possui os seguintes valores-chave opcionais:
valor: o valor correspondente a este atributo. Pode ser qualquer valor JavaScript válido (valor numérico, objeto, função, etc.). O padrão é indefinido.
gravável: se e somente se o gravável deste atributo for verdadeiro, o valor pode ser alterado pelo operador de cópia. O padrão é falso.
configurável: Se e somente se o configurável do atributo for verdadeiro, o descritor do atributo pode ser alterado e o atributo também pode ser excluído do objeto correspondente. O padrão é falso.
enumerável: se e somente se o enumerável da propriedade for verdadeiro, a propriedade pode aparecer na propriedade de enumeração do objeto. O padrão é falso.
O método Object.getOwnPropertyDescriptor() retorna o descritor de propriedade correspondente a uma propriedade própria no objeto especificado.
Object.getOwnPropertyDescriptor(obj, prop)
obj: o objeto alvo a ser encontrado
prop: nome do atributo no objeto alvo (tipo String).
Valor de retorno: se a propriedade especificada existir no objeto, seu objeto descritor de propriedade será retornado, caso contrário, indefinido será retornado.
Nota: Se o primeiro parâmetro deste método não for um objeto, um erro (TypeError) será reportado.
O método Object.defineProperty() define diretamente uma nova propriedade em um objeto ou modifica uma propriedade existente de um objeto e retorna o objeto.
Object.defineProperty(obj, prop, descritor)
obj: O objeto no qual as propriedades devem ser definidas.
prop: O nome da propriedade a ser definida ou modificada.
descritor: o descritor do atributo a ser definido ou modificado
Valor de retorno: o objeto passado para a função
O código de exemplo a seguir mostra a configuração e obtenção de descritores de atributos var obj = { nome: 'geléia', idade: 8 } Object.defineProperty(obj, 'trabalho', { valor: 'advogado' }) console.log(Object.getOwnPropertyDescriptor(obj, 'age')) // {valor: 8, gravável: verdadeiro, enumerável: verdadeiro, configurável: verdadeiro } console.log(obj.job) // Advogado // Nova propriedade através de defineProperty, esta nova propriedade não é modificável, não pode ser excluída e não enumerável console.log(Object.getOwnPropertyDescriptor(obj, 'job')) // {valor: 'Advogado', gravável: falso, enumerável: falso, configurável: falso}
注意:通过defineProperty新增的属性,该新属性是不可修改、不可删除以及不可枚举的
varobj = { nome: 'geléia', idade: 8 } Object.defineProperty(obj, 'endereço', { valor: 'Hebei', // configurável Esta propriedade não pode ser excluída, nem você pode usar defineProperty para modificar o descritor da propriedade novamente configurável: false, }) delete obj.address // Quero usar delete para excluir este atributo obj.address = 'Guangzhou' // Quero modificar o valor do endereço do atributo em obj para Guangzhou console.log(obj.address) // Resultado de saída: Hebei
Como o valor configurável do descritor de atributo é falso e não pode ser excluído ou modificado, a exclusão e a modificação não terão efeito.
varobj = { nome: 'geléia', idade: 8}Object.defineProperty(obj, 'sexo', { valor: 'Masculino', // enumerable configura se esta propriedade pode ser enumerada enumerable: true})for (i in obj) { console.log(i)}
Quando enumerável: falso, o resultado de saída é nome idade
Quando enumerável: verdadeiro, o resultado de saída é nome idade sexo
varobj = { nome: 'geléia', idade: 8}Object.defineProperty(obj, 'pontuação', { valor: 80, // gravável: verdadeiro gravável: falso})obj.score = 100 console.log(obj.score) // 80
Como o valor de gravável é falso, quando a pontuação é modificada para 100, a modificação não é bem-sucedida e o resultado final é 80.
Você acha que é complicado definir o descritor de propriedade de apenas uma propriedade por vez?
O método Object.defineProperties() define uma ou mais novas propriedades ou modifica propriedades existentes para um objeto e retorna o objeto.
Object.defineProperties(obj, adereços)
obj: O objeto no qual as propriedades devem ser definidas.
props: O objeto cujas propriedades enumeráveis ou descritores de propriedades modificados devem ser definidos.
Valor de retorno: o objeto passado para a função.
O código de exemplo é o seguinte:
varobj = { nome: 'jam',}Object.defineProperties(obj, { 'idade': { valor: 28, gravável: verdadeiro, configurável: falso, enumerável: verdadeiro }, 'trabalho': { valor: 'advogado', gravável: verdadeiro, configurável: falso, enumerável: verdadeiro }, 'sexo': { valor: 'Masculino', gravável: falso, configurável: falso, enumerável: verdadeiro }, 'altura': { valor: '1,8m', gravável: falso, configurável: falso, enumerável: verdadeiro }})console.log(obj) // nome: 'jam', idade: 28, trabalho: 'advogado', sexo: 'masculino', altura: '1,8m' }
Descritores de acesso são propriedades descritas por pares de funções getter-setter. O descritor de acesso possui os seguintes valores de chave opcionais:
get: fornece um método getter para a propriedade. Se não houver getter, ele será indefinido. Quando esta propriedade for acessada, o método será executado. Nenhum parâmetro será passado quando o método for executado, mas o objeto this será passado.
set: Fornece um método setter para a propriedade. Se não houver setter, será indefinido. Este método é acionado quando o valor da propriedade é modificado. Este método aceitará o único parâmetro, que é o novo valor do parâmetro da propriedade.
configurável: Se e somente se o configurável do atributo for verdadeiro, o descritor do atributo pode ser alterado e o atributo também pode ser excluído do objeto correspondente. O padrão é falso.
Enurnerável: Se e somente se o enumerável do atributo for verdadeiro, o atributo pode aparecer no atributo de enumeração do objeto. O padrão é falso.
O uso de configurável e enumerável é consistente com o dos descritores de dados, por isso não vou explicá-los em detalhes aqui.
Fale principalmente sobre o uso dos métodos get e set
varobj = { nome: 'geléia', idade: 8, _endereço: 'Hebei' } // Cenários de uso de descritores de acesso // 1. Ocultar um determinado atributo privado que se espera que seja usado e atribuído diretamente pelo mundo exterior // 2. Se quisermos entender o processo de acesso e configuração do valor de um determinado atributo , também usaremos o descritor de propriedade de armazenamento Object.defineProperty(obj, 'address', { enumerável: verdadeiro, configurável: verdadeiro, obter: função () { foo() retorne este._endereço }, definir: função (valor) { bar() this._address = valor } }) função foo(){ console.log("O valor do endereço foi interceptado uma vez") } barra de funções () { console.log("O valor do endereço é definido uma vez") }
O console de código de exemplo acima imprime os seguintes resultados: