¿Por qué no se puede escribir indefinido en JavaScript?

59

De acuerdo con la documentación de MDN sobreundefined :

En los navegadores modernos (JavaScript 1.8.5 / Firefox 4+), undefined es una propiedad no configurable, no escribible según la especificación ECMAScript 5. Incluso cuando este no sea el caso, evite anularlo.

Uno de los atributos de propiedad de undefined es que no se puede escribir.

Pero si lo hago:

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

¿Eso significa que puedo sobrescribir el valor de undefined? ¿Qué pasa si alguien hace eso? ¿Debería JavaScript advertir sobre eso?

pmiranda
fuente
55
¿Puedes decirnos qué navegador usas? (Firefox 72.0b10 (64 bits) en Linux funciona según lo previsto typeof test === "undefined")
jonatjano
3
@DmitryReutov typeof undefinedregresa "undefined"en circunstancias normales.
Amy
3
@DmitryReutov Por supuesto, "undefined"es una cadena. La pregunta no es preguntar a qué se typeof (typeof undefined)evalúa. Se está preguntando a qué se typeof undefinedevalúa. Regresa "undefined", no"string"
Amy
2
@DmitryReutov typeof ______es una expresión que se evalúa como una cadena que contiene el tipo de ______. Estás malinterpretando la pregunta.
Amy
3
@ Amy, lo sé, pero Edge devuelve "cadena" y Chrome "indefinido"
Alon Eitan

Respuestas:

50

Un comentario eliminado por Amy da la solución. Está creando una variable llamada undefined, y no funciona si hace sus fragmentos en el ámbito global:

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

Pero funciona efectivamente si lo hace en un ámbito local donde indefinido ya no se refiere a la variable global:

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

Para evitar este error, puede usar la 'use strict';directiva:

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

Si está escribiendo código donde no puede controlar dónde se ejecutará (p. Ej., Biblioteca, incrustación, etc.), es un buen patrón utilizar un IIFE que lo hace para que pueda garantizar que indefinido siempre será correcto / utilizable. Aquí hay un ejemplo:

(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


Todas mis pruebas se realizaron con Firefox 72.0b10 (64 bits) en Ubuntu, y el resultado para el primer fragmento puede diferir en un navegador anterior.

jonatjano
fuente
3
@pmiranda no es mío, lo encontré muy interesante
jonatjano
2
Gracias de nuevo. Toda esta duda tiene su origen en esto: un nuevo desarrollador aquí estaba traduciendo algunas variables de nombre en español al inglés. En nuestro código, teníamos una variable llamada let indefinido= dataArray( (a) => (anotherArray.includes(someName)));que estábamos verificando si esa var estaba 'indefinida' (el resultado de que findno se encontraron elementos) o no. Luego tradujo indefinidoa undefinedVi que lo probé en Chrome y Edge, viendo alguna diferencia. Por eso vine aquí para pedir la opinión del resto, porque también estoy aprendiendo.
pmiranda
@pmiranda Esta respuesta no responde estrictamente la parte "por qué". Pero es una buena respuesta.
Ismael Miguel
2
Si termina necesitando el valor real de undefined, usevoid 0
Usuario que no es usuario
2
@ Jon porque para algunas razones del Consorcio EcmaScript no chosed para hacer sin definir una palabra clave reservada , sino una propiedad del objeto global
jonatjano
17

Si bien es posible usarlo como un identificador (nombre de variable) en cualquier ámbito que no sea el ámbito global (porque indefinido no es una palabra reservada), hacerlo es una muy mala idea que dificultará el mantenimiento y la depuración de su código.

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

undefinedno está reservado, por lo tanto, es posible asignarle un nuevo valor.

Cuando no está utilizando strict mode, básicamente está creando una variable llamada undefineden el ámbito local y asignándole un stringvalor.

undefinedes una propiedad del objeto global . El valor inicial de indefinido es el valor primitivoundefined.

use strict ayudará a prevenir este error en el ámbito global, mientras que aún puede sobrescribirse en el ámbito local.

Si desea estar más seguro, debe usar en void 0lugar de lo undefined que siempre regresa undefined.

'use stict'

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

kooskoos
fuente
1
aquí está la lista de palabras clave para más detalles
jonatjano
1
Vale la pena señalar que en un IIFE de este tipo también se puede obtener una referencia al undefinedleerlo como un argumento. Como el IIFE nunca pasa ningún argumento aquí, estarán undefineddentro de él. Por ejemplo((undefined) => console.log(typeof undefined))()
SeinopSys