Подтвердить что ты не робот

Что произойдет, если мы установим значение undefined?

Что делает эта строка ниже?

undefined = 'A value';

Если это не изменит значение undefined, то что происходит за кулисами?

4b9b3361

Ответ 1

undefined является свойством глобального объекта, т.е. является переменной в глобальной области. Начальное значение undefined - это примитивное значение undefined.

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

Итак, это просто переменная, ничего особенного. Теперь, чтобы ответить на ваши вопросы:

  • undefined = 'A value'; пытается присвоить строку 'A value' глобальной переменной undefined
  • В старых браузерах значение изменяется, т.е. undefined === 'A value'; // true. В новых браузерах в строгом режиме операция приводит к ошибке.

Вы можете протестировать следующее в консоли браузера (я использую современный браузер здесь - Google Chrome):

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

В приведенном выше примере значение undefined не изменяется. Это потому, что (внимание мое):

В современных браузерах (JavaScript 1.8.5/Firefox 4+) undefined представляет собой неконфигурируемое, не записываемое свойство по спецификации ECMAScript 5.

В строгом режиме:

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

Ответ 2

В отличие от true, 123 или null, undefined не является литералом. Это означает, что использование идентификатора undefined не является надежным способом получения значения undefined. Вместо этого можно использовать оператор void, например. void 0.

По умолчанию undefined определено свойство глобального объекта то есть глобальная переменная, До ECMAScript 5 это свойство было доступно для записи, поэтому

undefined = "A value";

заменил значение window.undefined, считая, что оно не затенено локальной переменной. Тогда, если вы использовали "A value" === undefined, вы получили бы true. И void 0 === undefined создаст false.

ECMAScript 5 изменил это поведение, и теперь свойство не доступно для записи и не настраивается. Поэтому присваивания undefined будут игнорироваться в нестрогом режиме и будут вызывать исключение строгого режима. Под капотом

  • undefined = "A value"; является Простым назначением
  • Это использует PutValue, чтобы поместить значение "A value" в ссылку с базой глобального объекта, имя ссылки "undefined" и строгий флаг, если задание выполнено в строгом режиме.
  • Он вызывает внутренний метод [[Put]] глобального объекта, передавая "undefined" в качестве имени свойства, "A value" в качестве значения, и строгий флаг как флаг throw.
  • Он вызывает [[DefineOwnProperty]] внутренний метод глобального объекта, передавая "undefined", дескриптор свойства {[[Value]]: "A value"} и флаг throw в качестве аргументов.
  • Он отклоняет, то есть выбрасывает исключение TypeError, если флаг throw равен true, в противном случае возвращает false.

Однако вы все же можете объявлять локальные переменные undefined:

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

Ответ 3

Я сделал небольшой POC с и без strict mode.

Эффект заключается в том, что если вы не используете strict mode, все будет хорошо. Если вы используете strict mode, вам будет приятно:

TypeError: не может назначить свойство только для чтения 'undefined'

Теперь перейдите в 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 equal to undefined.. gosh.. we broke js")
}

Теперь, как я уже сказал, при строгом режиме вы получаете TypeError, а при удалении "use strict" script идет нормально, а выход - просто nothing happened.

Я нашел этот Q/A, который может быть полезен, если вы хотите узнать больше

ПРИМЕЧАНИЕ. Я тестировал этот код с помощью Node.js.