Em JavaScript, temos algumas maneiras de obter as propriedades de um objeto, dependendo do que desejamos obter.
1) Object.keys()
, que retorna todas as propriedades enumeráveis próprias de um objeto, um método ECMA5.
2) um for...in
loop, que retorna todas as propriedades enumeráveis de um objeto, independentemente de serem propriedades próprias ou herdadas da cadeia de protótipos.
3) Object.getOwnPropertyNames(obj)
que retorna todas as propriedades próprias de um objeto, enumeráveis ou não.
Também temos métodos que hasOwnProperty(prop)
nos permitem verificar se uma propriedade é herdada ou realmente pertence a esse objeto e propertyIsEnumerable(prop)
que, como o nome sugere, nos permitem verificar se uma propriedade é enumerável.
Com todas essas opções, não há como obter uma propriedade não enumerável e não própria de um objeto, que é o que desejo fazer. Há alguma maneira de fazer isso? Em outras palavras, posso de alguma forma obter uma lista das propriedades não enumeráveis herdadas?
Obrigado.
fonte
Respostas:
Como
getOwnPropertyNames
pode obter propriedades não enumeráveis, você pode usar isso e combiná-lo com a caminhada até a cadeia de protótipos.Eu testei isso no Safari 5.1 e consegui
Atualização: Refatorou o código um pouco (adicionou espaços e chaves e melhorou o nome da função):
fonte
while(curr = Object.getPrototypeOf(cure))
como a instrução condicional usa um operador de atribuição em vez de um operador de comparação, isso não retornaria sempre verdadeiro? Ou esta linha está essencialmente verificando se "curr" tem um protótipo?Object.getPrototypeOf(cure)
retornarnull
ao topo da cadeia de protótipos. Acho que isso não pressupõe cadeias circulares de protótipo!Function.prototype
nunca pode ser o protótipo "raiz", pois seu link de protótipo aponta paraObject.prototype
. A funçãoObject.getPrototypeOf( obj )
retorna o objeto mais alto na cadeia de protótipos deobj
. Ele permite que você siga a cadeia de protótipos deobj
até chegar ao seu fim (onull
valor). Não tenho certeza de qual é o seu problema com isso ...undefined
.Object.getPrototypeOf(John)
retorna oBoy.prototype
objeto (como deveria) - veja aqui: jsfiddle.net/aeGLA/1 . Observe que o construtor nãoBoy
está na cadeia de protótipos de . A corrente do protótipo é a seguinte: .John
John
Boy.prototype -> Object.prototype -> null
John
, seu construtor éBoy
, e aprototype
propriedade deBoy
éBoy.prototype
. EntãoObject.getPrototypeOf(John)
retornaBoy.prototype
.Uma solução mais limpa usando recursão:
Editar
Funções mais genéricas:
Este mesmo modelo pode ser aplicado usando
Object.getOwnPropertySymbols
, etc.fonte
Tirar proveito dos Sets leva a uma solução um tanto mais limpa, IMO.
fonte
Iterativo direto no ES6:
Exemplo de execução:
Exibir trecho de código
fonte
Para obter todas as propriedades ou métodos herdados para alguma instância, você pode usar algo assim
fonte
Object.getInherited
do queObject.prototype.getInherited
. Isso também elimina a necessidade do!(name == 'getInherited')
cheque feio . Além disso, em sua implementação, aprops
matriz pode conter propriedades duplicadas. Por último, qual é o propósito de ignorar aconstructor
propriedade?Aqui está a solução que eu encontrei enquanto estudava o assunto. Para obter todas as propriedades não enumeráveis não próprias do
obj
objeto, façagetProperties(obj, "nonown", "nonenum");
fonte
Exemplo de uso:
fonte
se você está tentando registrar propriedades não enumeráveis de um objeto pai ex. por padrão, os métodos definidos dentro de uma classe em es6 são configurados no prototype, mas são configurados como não enumeráveis.
fonte
Uma implementação em minhas preferências pessoais :)
fonte