Warum ist undefiniert in JavaScript nicht beschreibbar?

59

Laut MDN-Dokumentation zuundefined :

In modernen Browsern (JavaScript 1.8.5 / Firefox 4+) ist undefined eine nicht konfigurierbare, nicht beschreibbare Eigenschaft gemäß der ECMAScript 5-Spezifikation. Vermeiden Sie es, dies zu überschreiben, auch wenn dies nicht der Fall ist.

Eines der Eigenschaftsattribute von undefined ist, dass es nicht beschreibbar ist.

Aber wenn ich es mache:

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

Bedeutet das, dass ich den Wert von überschreiben kann undefined? Was passiert, wenn jemand das tut? Sollte JavaScript davor warnen?

Pmiranda
quelle
5
Können Sie uns sagen, welchen Browser Sie verwenden? (Firefox 72.0b10 (64 Bit) unter Linux funktioniert wie vorgesehen mit typeof test === "undefined")
Jonatjano
3
@DmitryReutov typeof undefinedkehrt "undefined"unter normalen Umständen zurück.
Amy
3
@DmitryReutov Natürlich "undefined"ist eine Zeichenfolge. Die Frage ist nicht, was typeof (typeof undefined)bewertet wird. Es wird gefragt, was typeof undefinedbewertet wird. Es kehrt zurück "undefined", nicht"string"
Amy
2
@DmitryReutov typeof ______ist ein Ausdruck, der zu einer Zeichenfolge ausgewertet wird, die den Typ des enthält ______. Sie verstehen die Frage falsch.
Amy
3
@ Amy, ich weiß, aber Edge gibt "string" und Chrome "undefined" zurück
Alon Eitan

Antworten:

50

Ein entfernter Kommentar von Amy gibt die Lösung. Sie erstellen eine Variable mit dem Namen undefinedund es funktioniert nicht, wenn Sie Ihre Snippets im globalen Bereich ausführen:

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

Aber es funktioniert effektiv, wenn Sie es in einem lokalen Bereich tun, in dem undefined nicht mehr auf die globale Variable verweist:

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

Um diesen Fehler zu vermeiden, können Sie die folgende 'use strict';Anweisung verwenden:

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

Wenn Sie Code schreiben, bei dem Sie nicht steuern können, wo er ausgeführt wird (z. B. Bibliothek, Einbettung usw.), ist es ein gutes Muster, ein IIFE zu verwenden, mit dem Sie sicherstellen können, dass undefiniert immer korrekt / verwendbar ist. Hier ist ein Beispiel:

(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


Alle meine Tests wurden mit Firefox 72.0b10 (64 Bit) unter Ubuntu durchgeführt, und das Ergebnis für das erste Snippet kann in einem älteren Browser abweichen.

Jonatjano
quelle
3
@pmiranda nicht meins, fand es sehr interessant
Jonatjano
2
Danke noch einmal. All dieser Zweifel hat seinen Ursprung darin: Ein neuer Entwickler hier übersetzte einige spanische Namensvariablen ins Englische. In unserem Code hatten wir eine Variable namens " let indefinido= dataArray( (a) => (anotherArray.includes(someName)));Wir haben überprüft, ob diese Variable " undefiniert "ist (das Ergebnis von findohne gefundene Elemente) oder nicht. Dann übersetzte er indefinidozu undefinedIch sah, dass ich es auf Chrome und Edge testete und einen Unterschied sah. Deshalb bin ich hierher gekommen, um die Meinung der anderen zu erfragen, weil ich auch lerne.
Pmiranda
@pmiranda Diese Antwort beantwortet nicht unbedingt den "Warum" -Teil. Aber es ist eine gute Antwort.
Ismael Miguel
2
Wenn Sie am Ende den tatsächlichen Wert von undefined benötigen, verwenden Sievoid 0
Benutzer, der kein Benutzer ist
2
@ Jon, weil das Ecmascript-Konsortium aus bestimmten Gründen beschlossen hat, nicht undefiniert ein reserviertes Schlüsselwort, sondern eine Eigenschaft des globalen Objekts zu machen
jonatjano
17

Es ist zwar möglich, es als Bezeichner (Variablenname) in einem anderen Bereich als dem globalen Bereich zu verwenden (da undefiniert kein reserviertes Wort ist), dies ist jedoch eine sehr schlechte Idee, die es schwierig macht, Ihren Code zu warten und zu debuggen.

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

undefinedist nicht reserviert, daher ist es möglich, ihm einen neuen Wert zuzuweisen.

Wenn Sie nicht verwenden strict mode, erstellen Sie im Wesentlichen eine Variable, die undefinedim lokalen Bereich aufgerufen wird, und weisen ihr einen stringWert zu.

undefinedist eine Eigenschaft des globalen Objekts . Der Anfangswert von undefined ist der Grundwertundefined.

use strict Dies hilft, diesen Fehler im globalen Bereich zu vermeiden, solange er im lokalen Bereich überschrieben werden kann.

Wenn Sie sicherer sein möchten, sollten Sie void 0stattdessen undefined immer zurückkehren undefined.

'use stict'

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

Kooskoos
quelle
1
Hier ist die Keyword-Liste für weitere Details
Jonatjano
1
Es ist erwähnenswert, dass man in einem solchen IIFE auch einen Hinweis erhalten kann, undefinedindem man es als Argument liest. Da dem IIFE hier niemals Argumente übergeben werden, werden sie undefineddarin enthalten sein. ZB((undefined) => console.log(typeof undefined))()
SeinopSys