2016-04-09 34 views
58

Cosa fa questa riga qui sotto?Cosa succede se impostiamo il valore di undefined?

undefined = 'A value'; 

Se non cambia il valore del undefined poi cosa succede dietro le quinte?

+29

il fatto che esso non genera un errore è preoccupante – JCOC611

+0

appena provato nella console e non abbiamo neanche un errore, in pratica non è successo nulla https://gyazo.com/6703d9f7768e272c1aad7d3750b08ef1 – vahanpwns

+0

@AshishMishra non è vero. È solo una proprietà del contesto globale. – Pointy

risposta

53

undefined is a property of the global object, i.e. it is a variable in global scope. The initial value of undefined is the primitive value undefined .

Vedi https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined

Quindi, è solo una variabile, niente di speciale. Ora, per rispondere alle vostre domande:

  1. undefined = 'A value'; tenta di assegnare una stringa 'A value' alla variabile globale undefined
  2. Nei browser meno recenti le variazioni di valore, vale a dire undefined === 'A value'; // true. Nei nuovi browser in modalità rigorosa l'operazione genera un errore.

è possibile verificare quanto segue in una console del browser (sto usando un browser moderno qui - Google Chrome):

undefined = true; 
console.log(undefined); // undefined 
// in older browsers like the older Internet Explorer it would have logged true 

Il valore di undefined non cambia nell'esempio di cui sopra. Questo perché (sottolineatura mia):

In modern browsers (JavaScript 1.8.5/Firefox 4+), undefined is a non-configurable, non-writable property per the ECMAScript 5 specification.

In modalità rigorosa:

'use strict'; 
undefined = true; // VM358:2 Uncaught TypeError: Cannot assign to read only property 'undefined' of object 
+2

Informazioni sui nuovi browser in modalità "non rigida"? non mostra alcun errore. Fa qualcosa. perché non cambia il valore né –

+1

@Cgraphics Nei browser moder in modalità non rigida non accade nulla. Il valore non può essere sovrascritto e non c'è nessun errore ... ancora, ma potrebbe cambiare in futuro. – Oleg

+0

Questo è il motivo per cui a volte si vede l'operatore 'void' usato - valuta il suo argomento e poi restituisce' undefined', e poiché si tratta di un operatore, non può essere assegnato un valore. Quindi puoi sempre ottenere 'undefined' con l'espressione' void 0' o 'void (0)' (gli operatori non richiedono parens intorno agli argomenti). –

3

ho fatto un po 'di POC con e senza strict mode.

L'effetto è che, se non si utilizza strict mode, tutto va bene. Se stai usando strict mode avrete un bel:

TypeError: Cannot assign to read only property 'undefined'

Ora veniamo al POC:

"use strict" 
var c; 

if (c === undefined) { 
    console.log("nothing happened") 
} 

undefined = "goofy" 

c = "goofy" 

if (c === undefined) { 
    console.log("c is 'goofy' and it's equal to undefined.. gosh.. we broke js") 
} 

Ora, come ho detto, con modalità rigorosa si ottiene un TypeError durante la rimozione del "use strict" lo script va bene e l'output è semplicemente nothing happened.

ho trovato this Q/A che potrebbe essere utile se si desidera sapere di più

NOTA: Ho provato questo codice utilizzando Node.js.

+0

Perché node.js? Ho pensato che fosse per il lato server –

+2

@Cgraphics node.js utilizza V8 - lo stesso motore JavaScript di Google Chrome, quindi è fondamentalmente le stesse regole, ma API diverse (i browser hanno 'window',' querySelector' ecc., Il nodo ha ' global', 'fs.write', ecc.). – Oleg

+1

Dal nodo.js è costruito su V8 ​​(il motore di Google Chrome) che usa ES6 sembrava il modo più veloce per creare il POC. :) – FredMaggiowski

24

A differenza di cose come true, 123 o null, undefined non è un literal. Ciò significa che l'utilizzo di undefinedidentifier non è un modo infallibile per ottenere lo undefined value. Invece, puoi utilizzare lo void operator, ad es. void 0.

Per impostazione predefinita, undefined ha definito una proprietà di global object, ovvero una variabile globale.Prima ECMAScript 5, che la proprietà era scrivibile, così

undefined = "A value"; 

sostituito il valore di window.undefined, supponendo che non era in ombra da una variabile locale. Quindi se hai usato "A value" === undefined, avresti ottenuto true. E void 0 === undefined produrrebbe false.

ECMAScript 5 ha modificato questo comportamento e ora la proprietà non è scrivibile né configurabile. Pertanto, le assegnazioni a undefined verranno ignorate in modalità non rigida e genereranno un'eccezione in modalità rigorosa. Sotto il cofano,

  1. undefined = "A value"; è un Simple Assignment
  2. che utilizza PutValue mettere il valore "A value" in un riferimento con base all'oggetto globale, nome riferimento "undefined" e rigorosa flag se l'assegnazione avviene in modalità rigorosa.
  3. Chiama il metodo interno [[Put]] dell'oggetto globale, passando "undefined" come nome della proprietà, "A value" come valore e il flag strict come flag di lancio.
  4. Chiama il metodo interno [[DefineOwnProperty]] dell'oggetto globale, passando "undefined", il descrittore di proprietà {[[Value]]: "A value"} e il flag di lancio come argomenti.
  5. Rifiuta, ovvero, genera un'eccezione TypeError se il flag di lancio è true, altrimenti restituisce false.

Tuttavia, sono ancora in grado di dichiarare locali undefined variabili:

(function() { 
    var undefined = "A value"; 
    alert(undefined); // "A value"; 
})(); 
+3

"Tuttavia, si è ancora in grado di dichiarare variabili locali non definite:" - Buon punto! –