2010-01-17 22 views
16

¿Hay alguna manera de hacer que un objeto devuelva falso en javascript?¿Puede un objeto ser falso?

var obj = new Object(); 

console.log(!!obj) // prints "true" even if it's empty 

Respuesta

20

No. Un objeto que no tiene ninguna propiedad asignada no se considera "vacío".

El hecho de que una variable contenga una instancia de un objeto es suficiente para hacer que javascript trate la variable como teniendo el valor de true cuando una expresión requiere un valor booleano.

Editar

está claro que hay algunos matices por aclarar que buscan en las otras respuestas aquí.

null no es un objeto, es la falta distintiva de un objeto. La pregunta se refiere a un objeto, que es uno que acaba de crearse.

+1

Tenga en cuenta que incluso 'new Boolean (false)' se considera 'true'. Entonces, no, todos los objetos son verdaderos. – Thilo

5

No. Pero null se convertirán en false.

> typeof(null) 
"object" 
> null instanceof Object 
false 
> !!null 
false 

para ver si el objeto contiene propiedades, uso (descaradamente copiados de How do I count a JavaScript object's attributes?):

function isEmpty (obj) { 
    for (var k in obj) 
     if (obj.hasOwnProperty(k)) 
      return false; 
    return true; 
} 
+3

para aclarar cosas: 'null' es un valor primitivo de tipo 'Nulo' y no es un objeto; es simplemente que 'typeof' está algo roto – Christoph

+0

' typeof' es una palabra clave JS no una función. Los paréntesis son innecesarios. –

+1

@Web_Designer: Lo sé, pero creo que es más claro de esta manera. – kennytm

5

Un "objeto" nulo (valor de verdad) devolverá falso.

var obj = null; 

console.log(!!obj); 

Si quería comprobar si no tiene propiedades, puede intentar:

var obj = new Object(); 
var empty = true; 
for (var p in obj) { 
    if (obj.hasOwnProperty(p)) { 
     empty = false; 
     break; 
    } 
} 
console.log(empty); 
+0

null no es un objeto. – Taurus

2

creo que con la primera ! necesita modelar obj a un valor lógico y negando su de valor que resulta en true si obj es nulo, y con el segundo ! negándolo nuevamente.

+1

No, el primer '!' Arroja el objeto a boolean * y luego * lo niega. El segundo '!' Lo niega * nuevamente * haciendo que el resultado final sea equivalente a convertir el objeto en booleano. El asker no tiene problemas en esa declaración. – kennytm

+0

Por supuesto, gracias por la corrección. Editado –

3

No estoy seguro de por qué usted quiere esto, pero hay una manera que podría hacer algo como esto, pero es un poco hacky ...

var obj = { 
    toString: function() { return ''; } 
}; 

alert(!! (''+obj)); 
+1

Una posible razón: Tiene un código que pasa alrededor de un booleano. Ahora quiere cambiar ese código para que en el caso 'falso ', también se adjunte una razón por la cual el valor sea falso. Si puede hacer que algo parezca falso para las operaciones booleanas, pero también adjuntar algunos datos adicionales, entonces el código existente no tendrá que cambiar. Lamentablemente, parece que esto no es posible. – joeytwiddle

0

En su caso

console.log(!obj); devolverá falso.

porque un objeto o un objeto vacío es siempre una verdad.

1

Podemos sobreescribir Object.prototype.valueOf para hacer que un objeto parezca que es falsa cuando es coaccionado en una primitiva, por ejemplo, durante ==.

Sin embargo, no aparecerá ser falsa cuando la fuerza en un valor lógico utilizando !!, por lo que no funciona muy bien en el caso general.

var obj = { 
    valueOf: function() { 
     return false 
    } 
} 

> obj == false 
true    // Good, we fooled them! 

> !!obj 
true    // Not so good, we wanted false here 

> Boolean(obj) 
true    // Not so good, we wanted false here 
0

En la consola:

> ({})?true:false 
< true 

Así que la respuesta es no.

6

A partir de ES8, no, no se puede hacer que un objeto se evalúe como falso en JavaScript.

En la memoria descriptiva, todos los cheques booleanos (?!if etc.) depende de ToBoolean,
que es muy, muy simple:

  • False si indefinido, null, falso, cero, NaN, o cadena vacía
  • verdadera para todo lo demás (Object, Proxy, símbolo, etc.)

Si el tipo de la entrada es objeto, el resultado es verdadero. Sin pregunta. No valueOf, ningún caso especial.

No hay forma de crear un objeto falsy en JavaScript. Solo los objetos no pueden ser falsos.

A veces puede toparse con "cosas" similares a objetos que devuelven falso. Cadena vacía, por ejemplo, se usan como un objeto todo el tiempo. document.all es otro falso "objeto".

Sin embargo, estos no son objetos reales. No pueden tener propiedades personalizadas, no se pueden usar como prototipo y no siempre se comportan como un objeto, p. typeof o igual estricto.

Probablemente, este comportamiento persistirá por compatibilidad con versiones anteriores.

+1

Oh, esa cosa 'document.all' es interesante. Aunque, parece ser un objeto real de hecho. Usted * puede * agregarle propiedades personalizadas, * puede * usarse como prototipo y * se comporta * como un objeto con igual estricta. Solo pretende ser 'indefinido' cuando se usa con' typeof', loose igual o 'ToBoolean'. Aún así, eso probablemente no ayude en absoluto a menos que esté dispuesto a sacrificar un nuevo 'document.implementation.createHTMLDocument(). All' cada vez que necesite un objeto falsy. – Robert

+1

@Robert El problema es que tales usos están fuera de especificación y dependen del navegador. IE 11 devuelve 'undefined' para' Object.create (document.all) ', y en otros navegadores perdiste la propiedad falsy.En Firefox 52 no puedes asignar +5 propiedades numéricas. En resumen, el uso de objetos nativos como objeto falsy no es compatible con las especificaciones dom o es, y usted corre el riesgo de que los navegadores futuros rompan su código de una manera que puede ser difícil de depurar y corregir. – Sheepy

+0

seguro. Solo lo dije * puede * usarse como prototipo. Ni siquiera estoy seguro de si funciona en todos los navegadores. Pero, por supuesto, la cadena de prototipos no está involucrada en la comprobación de la falsedad, por lo que realmente no importa. Curiosamente, IE11 se niega a mostrar el resultado de 'Object.create (document.all)' en la consola, pero todavía 'Object.create (document.all) .__ proto__ === document.all' en mi prueba. En cuanto a las propiedades no modificables, bueno, por supuesto hay mucha magia detrás de ellas y cada navegador parece comportarse de manera diferente a este respecto. – Robert

Cuestiones relacionadas