Pergunta

Se eu tenho um objeto JavaScript, dizer

var myObject = new Object();
myObject["firstname"] = "Gareth";
myObject["lastname"] = "Simpson";
myObject["age"] = 21;

há um built-in ou melhores práticas aceites maneira para obter o comprimento deste objeto?

Foi útil?

Solução

O mais robusto de resposta (i.e.que capta a intenção de que você está tentando fazer, enquanto causando o menor número de bugs) seria:

Object.size = function(obj) {
    var size = 0, key;
    for (key in obj) {
        if (obj.hasOwnProperty(key)) size++;
    }
    return size;
};

// Get the size of an object
var size = Object.size(myObj);

Há uma espécie de convenção em JavaScript que você não adicionar coisas a um Objeto.protótipo, porque ele pode quebrar enumerações em várias bibliotecas.A adição de métodos para o Objeto é geralmente seguro, embora.


Aqui está uma atualização a partir de 2016 e ampla implementação de ES5 e além. Para IE9+ e todas as outras moderno ES5+ capaz navegadores, você pode usar Object.keys() assim o código acima torna-se:

var size = Object.keys(myObj).length;

Isso não é necessário modificar qualquer protótipo existente desde Object.keys() agora é construído em.

Editar:Objetos podem ter simbólico propriedades que não podem ser devolvidos via Objeto.o método de chave.Portanto, a resposta seria incompleta sem mencioná-los.

Tipo de símbolo que foi adicionado à linguagem para criar identificadores exclusivos para as propriedades do objeto.Principal benefício do tipo de Símbolo é a prevenção de substitui.

Object.keys ou Object.getOwnPropertyNames não funciona para o simbólico propriedades.Para devolvê-los você precisa usar Object.getOwnPropertySymbols.

var person = {
  [Symbol('name')]: 'John Doe',
  [Symbol('age')]: 33,
  "occupation": "Programmer"
};

const propOwn = Object.getOwnPropertyNames(person);
console.log(propOwn.length); // 1

let propSymb = Object.getOwnPropertySymbols(person);
console.log(propSymb.length); // 2

Outras dicas

Se você sabe que você não tem que se preocupar hasOwnProperty verifica, você pode fazer isto de forma muito simples:

Object.keys(myArray).length

Atualizado:Se você estiver usando Underscore.js (recomendado, é leve!), em seguida, você pode apenas fazer

_.size({one : 1, two : 2, three : 3});
=> 3

Se não, e você não quer mexer com propriedades de Objecto, por qualquer motivo, e já estão usando o lightbox, um plugin é igualmente acessível a:

$.assocArraySize = function(obj) {
    // http://stackoverflow.com/a/6700/11236
    var size = 0, key;
    for (key in obj) {
        if (obj.hasOwnProperty(key)) size++;
    }
    return size;
};

Aqui está o mais cross-browser solução.

Isso é melhor do que o aceitou responder, porque ele usa o Objeto nativo.chaves, se houver.Assim, ele é o mais rápido de todos os navegadores modernos.

if (!Object.keys) {
    Object.keys = function (obj) {
        var arr = [],
            key;
        for (key in obj) {
            if (obj.hasOwnProperty(key)) {
                arr.push(key);
            }
        }
        return arr;
    };
}

Object.keys(obj).length;

Eu não sou um especialista em JavaScript, mas parece que você teria para percorrer os elementos e contá-las uma vez que o Objeto não tem um método de comprimento:

var element_count = 0;
for (e in myArray) {  if (myArray.hasOwnProperty(e)) element_count++; }

@palmsey:Na justiça do OP, o JavaScript documentação, na verdade, explicitamente referem-se ao uso de variáveis do tipo Objecto desta forma como "arrays associativos".

Este método obtém todas as suas propriedade do objeto de nomes em uma matriz, para que você possa obter o comprimento da matriz, que é igual ao seu objeto chaves' de comprimento.

Object.getOwnPropertyNames({"hi":"Hi","msg":"Message"}).length; // => 2

Para não mexer com o protótipo ou outro código, você pode criar e ampliar seu próprio objeto:

function Hash(){
    var length=0;
    this.add = function(key, val){
         if(this[key] == undefined)
         {
           length++;
         }
         this[key]=val;
    }; 
    this.length = function(){
        return length;
    };
}

myArray = new Hash();
myArray.add("lastname", "Simpson");
myArray.add("age", 21);
alert(myArray.length()); // will alert 2

Se você sempre usa o método add, a propriedade length será correta.Se você está preocupado que você ou outras pessoas se esquecer de usar ele, você pode adicionar a propriedade do contador de que os outros têm lançado para o método de comprimento, também.

Claro, você pode sempre substituir os métodos.Mas mesmo se você fizer isso, seu código seria, provavelmente, falhar visivelmente, tornando-a fácil de depurar.;)

O mais simples é

Object.keys(myObject).length

Veja como e não se esqueça de verificar se o imóvel não estiver na cadeia de protótipos:

var element_count = 0;
for(var e in myArray)
    if(myArray.hasOwnProperty(e))
        element_count++;

Basta usar isso para obter o length:

Object.keys(myObject).length

Para alguns casos, é melhor armazenar o tamanho de uma variável separada.Especialmente, se você estiver adicionando à matriz de um elemento em um só lugar e pode facilmente incrementar o tamanho.Seria, obviamente, muito mais rápido se você precisa verificar o tamanho, muitas vezes.

Aqui é uma solução muito diferente que só vai trabalhar em mais navegadores modernos (IE9+, Chrome, Firefox 4+, Opera 11.60+, Safari 5.1+)

Ver jsFiddle

Configuração de sua Matriz Associativa de classe

/**
 * @constructor
 */
AssociativeArray = function () {};

// Make the length property work
Object.defineProperty(AssociativeArray.prototype, "length", {
    get: function () {
        var count = 0;
        for (var key in this) {
            if (this.hasOwnProperty(key))
                count++;
        }
        return count;
    }
});

Agora você pode usar este código como segue...

var a1 = new AssociativeArray();
a1["prop1"] = "test";
a1["prop2"] = 1234;
a1["prop3"] = "something else";
alert("Length of array is " + a1.length);

Utilização:

var myArray = new Object();
myArray["firstname"] = "Gareth";
myArray["lastname"] = "Simpson";
myArray["age"] = 21;
obj = Object.keys(myArray).length;
console.log(obj)

@palmsey:Na justiça do OP, o javascript do google docs, na verdade, explicitamente referem-se ao uso de variáveis do tipo Objecto desta forma como "arrays associativos".

E na justiça para @palmsey, ele foi muito correto, eles não são arrays associativos, eles estão definitivamente objetos :) - fazendo o trabalho de uma matriz associativa.Mas no que respeita ao maior ponto de você, definitivamente, parece ter o direito de acordo com isso, ao invés de multa de artigo que encontrei:

JavaScript "Arrays Associativos" Considerado Prejudicial

Mas de acordo com tudo isso, não é o aceito respostas a própria prática ruim?

Especificar o protótipo de uma função size() para o Objeto

Se algo foi adicionado ao Objeto .protótipo e, em seguida, a sugestão de código irá falhar:

<script type="text/javascript">
Object.prototype.size = function () {
  var len = this.length ? --this.length : -1;
    for (var k in this)
      len++;
  return len;
}
Object.prototype.size2 = function () {
  var len = this.length ? --this.length : -1;
    for (var k in this)
      len++;
  return len;
}
var myArray = new Object();
myArray["firstname"] = "Gareth";
myArray["lastname"] = "Simpson";
myArray["age"] = 21;
alert("age is " + myArray["age"]);
alert("length is " + myArray.size());
</script>

Eu não acho que a resposta deve ser aceito, uma vez que não podem ser confiáveis para o trabalho, se você tiver qualquer outro código em execução no mesmo contexto de execução.Para fazê-lo de modo robusto, certamente, você precisará definir o método de tamanho dentro de myArray e de seleção para o tipo de membros que como você iterar através deles.

Que sobre algo como isso --

function keyValuePairs() {
    this.length = 0;
    function add(key, value) { this[key] = value; this.length++; }
    function remove(key) { if (this.hasOwnProperty(key)) { delete this[key]; this.length--; }}
}

Se temos o hash

hash = {"a" :"b", "c":"d"};

podemos obter o comprimento, usando o comprimento das chaves, que é o comprimento de um hash:

chaves(hash).comprimento

Se você estiver usando o AngularJS 1.x você pode fazer coisas que o AngularJS caminho através da criação de um filtro e usando o código a partir de qualquer um dos outros exemplos, tais como o seguinte:

// Count the elements in an object
app.filter('lengthOfObject', function() {
  return function( obj ) {
    var size = 0, key;
    for (key in obj) {
      if (obj.hasOwnProperty(key)) size++;
    }
   return size;
 }
})

Utilização

No seu controller:

$scope.filterResult = $filter('lengthOfObject')($scope.object)

Ou no seu ponto de vista:

<any ng-expression="object | lengthOfObject"></any>

<script>
myObj = {"key1" : "Hello", "key2" : "Goodbye"};
var size = Object.keys(myObj).length;
console.log(size);
</script>

<p id="myObj">The number of <b>keys</b> in <b>myObj</b> are: <script>document.write(size)</script></p>

Isso funciona para mim:

var size = Object.keys(myObj).length;

Se você precisa de um associativa estrutura de dados que expõe o seu tamanho, melhor usar um mapa em vez de um objeto.

var myMap = new Map();
myMap.set("firstname", "Gareth");
myMap.set("lastname", "Simpson");
myMap.set("age", 21);
myMap.size; // 3

Uma variação em alguns dos itens acima é:

var objLength = function(obj){    
    var key,len=0;
    for(key in obj){
        len += Number( obj.hasOwnProperty(key) );
    }
    return len;
};

Ele é um pouco mais elegante forma de integrar hasOwnProp.

Se você não se preocupa em apoiar o Internet Explorer 8 ou inferior, você pode facilmente obter o número de propriedades em um objeto aplicando-se os seguintes dois passos:

  1. Executar Object.keys() para obter uma matriz que contém os nomes de apenas as propriedades que são enumerable ou Object.getOwnPropertyNames() se você também quiser incluir os nomes de propriedades que não são enumeráveis.
  2. Obter o .length propriedade da matriz.

Se você precisa fazer isso mais de uma vez, você pode moldar-se a essa lógica em uma função:

function size(obj, enumerablesOnly) {
    return enumerablesOnly === false ?
        Object.getOwnPropertyNames(obj).length :
        Object.keys(obj).length;
}

Como usar esta função em particular:

var myObj = Object.create({}, {
    getFoo: {},
    setFoo: {}
});
myObj.Foo = 12;

var myArr = [1,2,5,4,8,15];

console.log(size(myObj));        // Output : 1
console.log(size(myObj, true));  // Output : 1
console.log(size(myObj, false)); // Output : 3
console.log(size(myArr));        // Output : 6
console.log(size(myArr, true));  // Output : 6
console.log(size(myArr, false)); // Output : 7

Veja também este Violino para uma demonstração.

var myObject = new Object();
myObject["firstname"] = "Gareth";
myObject["lastname"] = "Simpson";
myObject["age"] = 21;
  1. Objecto.valores(meuobjeto).comprimento
  2. Objecto.entradas(meuobjeto).comprimento
  3. Objecto.chaves(meuobjeto).comprimento

Aqui está uma versão diferente do James Cogan resposta.Em vez de passar um argumento, apenas o protótipo de fora a classe de Objeto e tornar o código mais limpo.

Object.prototype.size = function () {
    var size = 0,
        key;
    for (key in this) {
        if (this.hasOwnProperty(key)) size++;
    }
    return size;
};

var x = {
    one: 1,
    two: 2,
    three: 3
};

x.size() === 3;

jsfiddle exemplo: http://jsfiddle.net/qar4j/1/

Você pode simplesmente usar Object.keys(obj).length em qualquer objeto para obter o seu comprimento.Objecto.chaves retorna um array contendo todos do objeto chaves (propriedades) que pode vir a calhar para encontrar o comprimento do objeto usando o comprimento da matriz correspondente.Você pode até mesmo escrever um função para este.Vamos começar criativo e escrever um método para ele também (juntamente com mais convenientes getter propriedade):

function objLength(obj)
{
  return Object.keys(obj).length;
}

console.log(objLength({a:1, b:"summit", c:"nonsense"}));

// Works perfectly fine
var obj = new Object();
obj['fish'] = 30;
obj['nullified content'] = null;
console.log(objLength(obj));

// It also works your way, which is creating it using the Object constructor
Object.prototype.getLength = function() {
   return Object.keys(this).length;
}
console.log(obj.getLength());

// You can also write it as a method, which is more efficient as done so above

Object.defineProperty(Object.prototype, "length", {get:function(){
    return Object.keys(this).length;
}});
console.log(obj.length);

// probably the most effictive approach is done so and demonstrated above which sets a getter property called "length" for objects which returns the equivalent value of getLength(this) or this.getLength()

A maneira mais simples é assim

Object.keys(myobject).length

onde myobject é o objeto que você deseja que o comprimento

Você sempre pode fazer Object.getOwnPropertyNames(myObject).length para obter o mesmo resultado como [].length daria para matriz normal.

Abaixo, uma versão de James Coglan a resposta em CoffeeScript para aqueles que abandonaram a reta JavaScript :)

Object.size = (obj) ->
  size = 0
  size++ for own key of obj
  size

Propriedade

Object.defineProperty(Object.prototype, 'length', {
    get: function () {
        var size = 0, key;
        for (key in this)
            if (this.hasOwnProperty(key))
                size++;
        return size;
    }
});

Utilização

var o = {a: 1, b: 2, c: 3};
alert(o.length); // <-- 3
o['foo'] = 123;
alert(o.length); // <-- 4

Podemos encontrar o comprimento do Objeto usando :

Object.values(myObject).length

Um pouco tarde para o jogo, mas uma boa maneira de conseguir isso (IE9+ apenas) é definir uma magia getter sobre a propriedade length:

Object.defineProperty(Object.prototype, "length", {
    get: function () {
        return Object.keys(this).length;
    }
});

E você pode simplesmente usá-lo assim:

var myObj = { 'key': 'value' };
myObj.length;

Daria 1.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top