Perché ("foo" === new String ("foo")) restituisce false in JavaScript?


98

Stavo per iniziare a usare === (triplo uguale, confronto rigoroso) tutto il tempo durante il confronto dei valori di stringa, ma ora lo trovo

"foo" === new String("foo")

è falso, e lo stesso con questo:

var f = "foo", g = new String("foo");
f === g; // false

Ovviamente:

f == g; // true

Quindi è consigliabile usare sempre == per il confronto tra stringhe o convertire sempre le variabili in stringhe prima del confronto?


6
Forse perché fooè la stringa pura ed new String("foo")è Object String
Danilo Valente


6
Si consiglia di non creare stringhe con new String(Completamente inutile) piuttosto che utilizzare==
Esailija

2
Perché qualcuno dovrebbe voler usare il costrutto come new String("foo")in Javascript in primo luogo? Non ho mai visto un codice del genere nel codice, ad esempio jQuery ...
Robert Koritnik

2
È possibile utilizzare String(obj)per convertire una stringa in scatola nella primitiva dopo aver ricevuto il parametro "stringa". ("foo" === String(new String("foo"))) === true
OrangeDog

Risposte:


126

"foo"è una stringa primitiva . (questo concetto non esiste in C # o Java)

new String("foo") è un oggetto stringa in scatola.

L' ===operatore si comporta in modo diverso su primitive e oggetti .
Quando si confrontano primitive (dello stesso tipo), ===restituirà true se entrambe hanno lo stesso valore.

Quando si confrontano oggetti, ===restituirà true solo se si riferiscono allo stesso oggetto (confronto per riferimento). Così, new String("a") !== new String("a").

Nel tuo caso, ===restituisce false perché gli operandi sono di tipi diversi (uno è primitivo e l'altro è un oggetto).


Le primitive non sono affatto oggetti.
L' typeofoperatore non tornerà "object"per le primitive.

Quando si tenta di accedere a una proprietà di una primitiva (usandola come un oggetto), il linguaggio Javascript lo inscatolerà in un oggetto, creando ogni volta un nuovo oggetto. Questo è descritto nelle specifiche .

Questo è il motivo per cui non puoi mettere proprietà sulle primitive:

var x = "a";
x.property = 2;
alert(x.property) //undefined

Ogni volta che scrivi x.property, viene creato un diversoString oggetto in scatola .


33
+1 typeof "foo"; // "string",typeof new String("foo"); // "object"
Sampson

1
Interessante, pensavo che le stringhe fossero oggetti in JS.
Cameron Martin

1
@ Sarfraz: Quasi tutto. Non dimenticare nulle undefined.

2
if( Object(a) !== a ) { //it's a primitive }
Esailija

1
Java ha primitive / .Net no
Marcelo De Zen

34

Utilizzando ===,

  • un oggetto non è mai uguale a nulla tranne che a un altro riferimento a se stesso.

  • una primitiva è uguale rispetto a un'altra primitiva se il loro tipo e valore sono gli stessi.


3
new String("foo") === new String("foo")è false:-P
Rocket Hazmat

10

La newparola qui è un criminale ( come al solito , posso dire) ...

Quando usi new, esprimi esplicitamente il tuo desiderio di lavorare con l' oggetto . Potrebbe essere sorprendente per te, ma questo:

var x = new String('foo');
var y = new String('foo');
x === y; 

... ti darà un potente false. È semplice: a confronto non sono gli interni degli oggetti, ma i riferimenti degli oggetti. E, ovviamente, non sono uguali, poiché sono stati creati due oggetti diversi.

Quello che probabilmente vuoi usare è la conversione :

var x = String('foo');
var y = String('foo');
x === y;

... e questo ti darà, come previsto, truecome risultato, così potrai gioire e prosperare con il tuo pari foosper sempre. )


2
domanda veloce sull'utilizzo di questo. Stai chiamando String (un costruttore?) Senza la parola chiave "new". Questo non significa che inquinerai l'ambito con qualsiasi proprietà assegnata all'interno del costruttore String? O ciò non accade perché il costruttore è codice nativo? In altre parole, supponiamo che la funzione String contenga "this.a = 1;" - ciò significa che la tua funzione / oggetto ora avrebbe una proprietà a = 1.
Michael Butler

Suppongo (ma non posso dirlo con certezza) che ciascuna delle funzioni del "costruttore di boxe" controlli prima il suo contesto e, se non è "nuovo" (cioè un oggetto prototipo), passa immediatamente al metodo di conversione. In caso di String quello sarebbe il toString()metodo, per esempio.
raina77ow


2

Da node.js REPL ("node" sulla riga di comando se installato):

> "foo" === (new String("foo")).valueOf()
true
> "foo" === new String("foo")
false
> typeof("foo")
'string'
> typeof(new String("foo"))
'object'
> typeof((new String("foo")).valueOf())
'string'
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.