Perché undefined non è scrivibile in JavaScript?


59

Secondo la documentazione di MDN suundefined :

Nei browser moderni (JavaScript 1.8.5 / Firefox 4+), undefined è una proprietà non configurabile, non scrivibile secondo la specifica ECMAScript 5. Anche quando questo non è il caso, evitare di ignorarlo.

Uno degli attributi di proprietà di undefined è che non è scrivibile.

Ma se lo faccio:

var undefined = 'hello';
var test = undefined;
console.log(typeof test);
//string

Ciò significa che posso sovrascrivere il valore di undefined? Cosa succede se qualcuno lo fa? JavaScript dovrebbe avvisarlo?


5
puoi dirci quale browser usi? (Firefox 72.0b10 (64 bit) su Linux funziona come previsto typeof test === "undefined")
jonatjano,

3
@DmitryReutov typeof undefinedritorna "undefined"in circostanze normali.
Amy,

3
@DmitryReutov Naturalmente "undefined"è una stringa. La domanda non è chiedere cosa typeof (typeof undefined)valuta. Si sta chiedendo cosa typeof undefinedvaluta. Esso restituisce "undefined", non"string"
Amy

2
@DmitryReutov typeof ______è un'espressione che restituisce una stringa contenente il tipo di ______. Stai fraintendendo la domanda.
Amy,

3
@Amy lo so, ma Edge restituisce "stringa" e Chrome "non definito"
Alon Eitan,

Risposte:


50

Un commento rimosso da Amy fornisce la soluzione. Stai creando una variabile denominata undefinede non funziona se esegui i tuoi snippet nell'ambito globale:

var undefined = 'hello';
var test = undefined;
console.log(typeof test);

Funziona in modo efficace se lo fai in un ambito locale in cui undefined non fa più riferimento alla variabile globale:

(()=>{
  var undefined = 'hello';
  var test = undefined;
  console.log(typeof test);
})()

Per evitare questo errore, è possibile utilizzare la 'use strict';direttiva:

'use strict';
var undefined = 'hello';
var test = undefined;
console.log(typeof test);

Se stai scrivendo un codice in cui non puoi controllare dove verrà eseguito (ad es. Libreria, embed, ecc.) È un buon modello usare un IIFE che lo rende così puoi garantire che undefined sia sempre corretto / utilizzabile. Ecco un esempio:

(function(undefined){
  // undefined will equal `undefined` because we didn't pass in an argument to the IIFE
  
  console.log(undefined); // always `undefined`, even if undefined !== `undefined`outside of the IIFE scope
})(); // No argument supplied


Tutti i miei test sono stati effettuati utilizzando Firefox 72.0b10 (64 bit) su Ubuntu e il risultato per il primo frammento potrebbe differire su un browser meno recente.


3
@pmiranda non mio, l'ho trovato molto interessante
jonatjano,

2
Grazie ancora. Tutto questo dubbio ha origine in questo: un nuovo sviluppatore qui stava traducendo alcune variabili di nome spagnolo in inglese. Nel nostro codice, avevamo una variabile chiamata let indefinido= dataArray( (a) => (anotherArray.includes(someName)));stavamo controllando se quel var era "indefinito" (il risultato di findsenza elementi trovati) o no. Poi ha tradotto indefinidoper undefinedaver visto che l'ho provato su Chrome e Edge, vedendo qualche differenza. Ecco perché sono venuto qui per chiedere l'opinione del resto, perché sto imparando anche io.
pmiranda,

@pmiranda Questa risposta non risponde rigorosamente alla parte "why". Ma è una buona risposta.
Ismael Miguel,

2
Se alla fine hai bisogno del valore effettivo di indefinito, usavoid 0
Utente che non è un utente il

2
@Jon perché per alcuni motivi il Consorzio Ecmascript ha scelto di non rendere indefinita una parola chiave riservata ma una proprietà dell'oggetto globale
jonatjano,

17

Mentre è possibile usarlo come identificatore (nome della variabile) in qualsiasi ambito diverso dall'ambito globale (perché non definito non è una parola riservata), farlo è una pessima idea che renderà difficile mantenere ed eseguire il debug del codice.

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

undefinednon è riservato quindi è possibile assegnargli un nuovo valore.

Quando non si utilizza, strict modesi crea essenzialmente una variabile chiamata undefinednell'ambito locale e si assegna un stringvalore ad essa.

undefinedè una proprietà dell'oggetto globale . Il valore iniziale di undefined è il valore primitivoundefined.

use strict aiuterà a prevenire questo errore nell'ambito globale mentre può ancora essere sovrascritto nell'ambito locale.

Se vuoi essere più sicuro devi usare al void 0posto del undefined quale ritorna sempre undefined.

'use stict'

const test = (() => {
  let undefined = "test"
  console.log(typeof undefined)
  console.log(typeof void 0)
})()


1
ecco l' elenco delle parole chiave per maggiori dettagli
jonatjano,

1
Vale la pena notare che in tale IIFE si può anche ottenere un riferimento undefinedleggendolo come argomento. Poiché all'IIFE non viene mai passato alcun argomento, essi saranno al undefinedsuo interno. Ad esempio((undefined) => console.log(typeof undefined))()
SeinopSys,
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.