Propriedade .length de funções e arrays
Que o JavaScript é doido, maluco, até biruta da cabeça, todos nós sabemos. De uma linguagem que aponta como verdadeiro uma comparação que na teoria é a junção de duas outras comparações, sendo que as duas comparações isoladas apontam como falso a operação com os mesmos valores (null >= 0, cof, cof.), nada pode se esperar. O motivo dessa minha escrita? O site WTFJS. Na data dessa postagem, mais especificamente de madrugada, estava navegando por ele, clicando em tópicos aleatórios e tentando entender os problemas. Até que me deparo com: Object.create(Array).length === 1 //true Object.keys(Object.create(Array)).length === 0 //true Esse tópico certamente está se referindo a duas coisas completamente distintas: objetos e arrays. Apesar do nome da propriedade ser o mesmo, elas não representam a mesma coisa. Object.create é responsável por criar uma cópia de um objeto utilizando outro como base. Na primeira linha está explícito que estamos criando uma cópia do construtor Array (que é uma função, guarde bem essa informação). Funções também trazem a propriedade .length, mas que, diferente dos arrays, indica o número mínimo de argumentos que são esperados. Ou seja, a primeira linha não está criando um array, ela está clonando uma função. E segundo a documentação oficial do construtor do array, ela espera no mínimo um único argumento. Por isso .length retorna 1. Na segunda linha estamos "buscando" as propriedades presentes no novo objeto, obtido através da clonagem do construtor do array. No entanto, ela não apresenta propriedades fora do seu protótipo. Então por que .length retorna 0? Justamente por que Object.keys retorna uma nova instância de array. Percebem a diferença? Primeiro obtemos a quantidade de parâmetros esperados pela função construtora de array, e depois obtemos a quantidade de propriedades (fora do protótipo) que aquele objeto tem. É por isso que retornam valores diferentes.

Que o JavaScript é doido, maluco, até biruta da cabeça, todos nós sabemos. De uma linguagem que aponta como verdadeiro uma comparação que na teoria é a junção de duas outras comparações, sendo que as duas comparações isoladas apontam como falso a operação com os mesmos valores (null >= 0
, cof, cof.), nada pode se esperar.
O motivo dessa minha escrita? O site WTFJS. Na data dessa postagem, mais especificamente de madrugada, estava navegando por ele, clicando em tópicos aleatórios e tentando entender os problemas. Até que me deparo com:
Object.create(Array).length === 1 //true
Object.keys(Object.create(Array)).length === 0 //true
Esse tópico certamente está se referindo a duas coisas completamente distintas: objetos e arrays. Apesar do nome da propriedade ser o mesmo, elas não representam a mesma coisa.
Object.create
é responsável por criar uma cópia de um objeto utilizando outro como base. Na primeira linha está explícito que estamos criando uma cópia do construtor Array (que é uma função, guarde bem essa informação).
Funções também trazem a propriedade .length
, mas que, diferente dos arrays, indica o número mínimo de argumentos que são esperados.
Ou seja, a primeira linha não está criando um array, ela está clonando uma função. E segundo a documentação oficial do construtor do array, ela espera no mínimo um único argumento. Por isso .length
retorna 1.
Na segunda linha estamos "buscando" as propriedades presentes no novo objeto, obtido através da clonagem do construtor do array. No entanto, ela não apresenta propriedades fora do seu protótipo. Então por que .length
retorna 0? Justamente por que Object.keys
retorna uma nova instância de array.
Percebem a diferença? Primeiro obtemos a quantidade de parâmetros esperados pela função construtora de array, e depois obtemos a quantidade de propriedades (fora do protótipo) que aquele objeto tem. É por isso que retornam valores diferentes.