mdn - object length javascript jquery




Comprimento de um objeto JavaScript (20)

Eu tenho um objeto JavaScript, existe uma maneira de prática recomendada aceita ou incorporada para obter o comprimento desse objeto?

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

@palmsey: Para ser justo com o OP, os documentos javascript na verdade se referem explicitamente ao uso de variáveis ​​do tipo Object dessa maneira como "matrizes associativas".

Para ser justo com @palmsey, ele estava certo, eles não são matrizes associativas, são definitivamente objetos :) - fazendo o trabalho de uma matriz associativa. Mas no que diz respeito ao ponto mais amplo, você definitivamente parece ter o direito de acordo com este artigo bastante interessante que eu descobri:

"Matrizes associativas" do JavaScript consideradas prejudiciais

Mas, de acordo com tudo isso, a resposta aceita não é uma prática ruim?

Especifique uma função size () do protótipo para Object

Se alguma outra coisa tiver sido adicionada ao objeto .prototype, o código sugerido 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 essa resposta deva ser aceita, pois não pode ser confiável funcionar se você tiver outro código em execução no mesmo contexto de execução. Para fazer isso de uma maneira robusta, certamente você precisará definir o método de tamanho no myArray e verificar o tipo de membros à medida que itera por eles.


Propriedade

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

Usar

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

A resposta mais robusta (ou seja, que captura a intenção do que você está tentando fazer enquanto causa o menor número de erros) 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);

Existe um tipo de convenção no JavaScript que você não adiciona coisas ao Object.prototype , porque ele pode quebrar as enumerações em várias bibliotecas. Adicionar métodos ao Object geralmente é seguro, no entanto.

Aqui está uma atualização a partir de 2016 e implantação generalizada do ES5 e além. Para o IE9 + e todos os outros navegadores modernos compatíveis com ES5 +, você pode usar Object.keys() para que o código acima se torne:

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

Isso não precisa modificar nenhum protótipo existente, já que Object.keys() agora está embutido.

Editar : os objetos podem ter propriedades simbólicas que não podem ser retornadas pelo método Object.key. Portanto, a resposta seria incompleta sem mencioná-los.

O tipo de símbolo foi adicionado ao idioma para criar identificadores exclusivos para propriedades do objeto. O principal benefício do tipo Symbol é a prevenção de substituições.

Object.keys ou Object.getOwnPropertyNames não funciona para propriedades simbólicas. 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

Abaixo está uma versão da resposta de James Coglan no CoffeeScript para aqueles que abandonaram o JavaScript direto :)

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

Aqui está uma solução completamente diferente que funcionará apenas em navegadores mais modernos (IE9 +, Chrome, Firefox 4+, Opera 11.60+, Safari 5.1+)

Veja jsFiddle

Configure sua classe Matriz Associativa

/**
 * @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 esse código da seguinte maneira ...

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

Aqui está uma versão diferente da resposta de James Cogan. Em vez de passar um argumento, apenas protótipo da classe Object e torne 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;

Exemplo de jsfiddle: http://jsfiddle.net/qar4j/1/


Em alguns casos, é melhor armazenar apenas o tamanho em uma variável separada. Especialmente, se você estiver adicionando à matriz por um elemento em um local e puder aumentar facilmente o tamanho. Obviamente, isso funcionaria muito mais rápido se você precisar verificar o tamanho com frequência.


Esse método obtém todos os nomes de propriedades do seu objeto em uma matriz, para que você possa obter o comprimento dessa matriz igual ao comprimento das chaves do seu objeto.

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

O mais simples é

Object.keys(myObject).length

Para não mexer com o protótipo ou outro código, você pode criar e estender 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 usar o método add, a propriedade length estará correta. Se você estiver preocupado com o fato de você ou outras pessoas se esquecerem de usá-la, adicione o contador de propriedades que os outros publicaram no método length também.

Claro, você sempre pode substituir os métodos. Mas mesmo se você o fizer, seu código provavelmente falhará notavelmente, facilitando a depuração. ;)


Que tal algo assim -

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 tivermos o hash

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

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

keys (hash) .length


Se você não se preocupa em oferecer suporte ao Internet Explorer 8 ou inferior, pode obter facilmente o número de propriedades em um objeto aplicando as duas etapas a seguir:

  1. Execute developer.mozilla.org/en/docs/Web/JavaScript/Reference/… para obter uma matriz que contenha apenas os nomes das propriedades enumerable ou Object.getOwnPropertyNames() se você desejar incluir também os nomes das propriedades que não são enumeráveis.
  2. Obtenha a propriedade .length dessa matriz.

Se você precisar fazer isso mais de uma vez, poderá envolver 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 específica:

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 Fiddle para uma demonstração.


Se você precisar de uma estrutura de dados associativa que exponha seu tamanho, use melhor um mapa em vez de um objeto.

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

Um pouco tarde para o jogo, mas uma boa maneira de conseguir isso (apenas no IE9 +) é definir um getter mágico na propriedade length:

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

E você pode usá-lo assim:

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

Daria 1 .


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;
};

É uma maneira um pouco mais elegante de integrar o hasOwnProp.


Veja como e não se esqueça de verificar se a propriedade não está na cadeia de protótipos:

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

Você pode simplesmente usar Object.keys(obj).length em qualquer objeto para obter seu comprimento. Object.keys retorna uma matriz contendo todas as chaves (propriedades) do objeto, que podem ser úteis para encontrar o comprimento desse objeto usando o comprimento da matriz correspondente. Você pode até escrever uma função para isso. Vamos ser criativos e escrever um método para ele também (junto com uma propriedade getter mais conveniente):

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()


Atualizado : se você estiver usando o Underscore.js (recomendado, é leve!), Poderá fazer

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

Caso contrário , e você não quer mexer nas propriedades do objeto por qualquer motivo, e já está usando o jQuery, um plug-in é igualmente acessível:

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

<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;




javascript-objects