for..in e hasOwnProperty

Duplicar Possível:
Como faço para verificar se um object tem uma propriedade em JavaScript?

Eu encontrei o seguinte trecho nos arquivos JS do Twitter. Eu estava me perguntando por que eles precisam chamar a function hasOwnProperty para ver o dict tem a propriedade de key ? O loop for está sendo executado para cada ‘chave’ em ‘dict’, o que significa que ‘dict’ tem ‘chave’, estou perdendo um ponto?

 function forEach(dict, f) { for (key in dict) { if (dict.hasOwnProperty(key)) f(key, dict[key]); } } 

Porque se você não fizer isso, ele passará por todas as propriedades na cadeia de protótipos, incluindo aquelas que você não conhece (que possivelmente foram adicionadas por alguém mexendo com protótipos de objects nativos).

Desta forma, você está garantido apenas as chaves que estão na própria instância do object.

O método hasOwnProperty permite saber se uma propriedade está diretamente em uma instância de um object ou herdada de sua cadeia de protótipos.

Considere o seguinte

 function ObjWithProto() { this.foo = 'foo_val'; } ObjWithProto.prototype = {bar: 'bar_val'}; var dict = new ObjWithProto(); dict.foobar = 'foobar_val'; 

isto é, você tem um Object dict com propriedades foo e foobar que também herda uma bar propriedades de sua cadeia de protótipos.

Agora execute-o através de uma versão modificada do seu código

 function forEach(dict) { var key; for (key in dict) { if ( dict.hasOwnProperty(key) ) console.log('has', key, dict[key]); else console.log('not', key, dict[key]); } } forEach( dict ); 

Você verá

 has foo foo_val has foobar foobar_val not bar bar_val 

Isso permite separar as propriedades que um object possui e as que ele herdou (que geralmente são methods que não são relevantes para o loop).

Além disso, se você agora faz dict.bar = 'new_bar_val'; , o último resultado será alterado para a has bar new_bar_val , permitindo que você diferencie até mesmo as propriedades do mesmo nome herdadas.

Todo object em javascript é um dictionary, isso significa que “toString” e todo outro método é uma chave de cada Objeto

 var myObj = {}; console.log(myObj["toString"]); 

Mas essa function é herdada da class Object, então hasOwnProperty informa se essa chave pertence ao dictionary ou se é herdada.

 "toString" in myObj; // true myObj.hasOwnProperty("toString") // false 

@blockhead está bem aqui. Por exemplo, a estrutura Prototype.js usada para estender matrizes nativas com methods auxiliares extras (não conheço a situação com as versões atuais de uma estrutura). Assim, o uso direto de “for (key in dict)” retornaria todos os elementos do div mais referências aos methods auxiliares. O que é meio inesperado 🙂