#javascript #node.js
#javascript #node.js
Вопрос:
Итак, я просто играл в Node.js командная строка и вспомнил, что undefined
это не зарезервированное ключевое слово в JS, и вполне допустимо объявлять переменную с именем undefined
, подобным
let undefined = 7;
Я объявил эту переменную, но, увидев, что Node.js не переопределяет undefined
значение по умолчанию (иначе говоря, переменная существует, но к ней нельзя получить доступ, поскольку она использует undefined
по умолчанию), я попытался удалить ее, используя delete
инструкцию. Мой вывод выглядел так:
> delete undefined
false
Это вызвало у меня любопытство, поскольку я никогда не видел, чтобы удаление возвращало false в Node.js CL (он даже возвращает true, если вы пытаетесь удалить необъявленные переменные или что-то подобное delete asdasddsa
).
Теперь я попробовал, что произойдет, если я использую это как
> delete null
true
Это также работает для всех других примитивных значений, таких как true
, 1
или "string"
.
Итак, почему это возвращает false, но возвращает true для null? Мне просто любопытно и я пытаюсь глубже понять, как работает язык
Комментарии:
1. 12.5.3
delete
Оператор -> 12.5.3.2 Семантика среды выполнения: оценка -> Шаги 3, 4b, 5e2. Если вы посмотрите на результат
Object.getOwnPropertyDescriptor(self, 'undefined')
, вы увидите, чтоconfigurable
этоfalse
означает, что свойство не может быть изменено или удалено.3. Эти строки кода на самом деле ничего не делают,
delete
удаляют свойства объекта, а не объекты или примитивы. Семантика среды выполнения, на которую ссылается Андреас, объясняет возвращаемые значения.4. Ах, я понимаю, спасибо за объяснение. Я знаю, что вы можете сделать свойства не конфигурируемыми с помощью
Object.freeze
илиObject.defineProperty
, но есть ли какие-либо более естественные случаи этого? До сих пор я не сталкивался ни с одним5. Вы можете использовать это
Object.keys(self).filter(k => !Object.getOwnPropertyDescriptor(self, k).configurable)
, чтобы получить массив всех свойств, которые не настраиваются.
Ответ №1:
Поведение определено в 12.5.3.2 Семантика среды выполнения: оценка delete
оператора, а точнее, на шагах 3, 4b и 5e
- Пусть
ref
будет результатом вычисленияUnaryExpression
.ReturnIfAbrupt(ref)
.- Если
Type(ref)
это не ссылка, вернитеtrue
.- Если
IsUnresolvableReference(ref)
равноtrue
, то
a. Утверждение:IsStrictReference(ref)
естьfalse
.
b. Returntrue
.- Если
IsPropertyReference(ref)
равноtrue
, то
a. ЕслиIsSuperReference(ref)
естьtrue
, создайтеReferenceError
исключение.
b. ПустьbaseObj
будет !ToObject(GetBase(ref))
.
c. ПустьdeleteStatus
будет ?baseObj.[[Delete]](GetReferencedName(ref))
.
d. ЕслиdeleteStatus
естьfalse
иIsStrictReference(ref)
естьtrue
, создайтеTypeError
исключение.
e. ReturndeleteStatus
.- Else,
a. Assert:ref
является ссылкой на привязку записи среды.
b. Пустьbindings
будетGetBase(ref)
.
c. Return ?bindings.DeleteBinding(GetReferencedName(ref))
.
Примечание
Когдаdelete
оператор возникает в коде строгого режима, выдаетсяSyntaxError
исключение, если оноUnaryExpression
является прямой ссылкой на переменную, аргумент функции или имя функции. Кроме того, еслиdelete
оператор встречается в коде строгого режима и свойство, подлежащее удалению, имеет атрибут{ [[Configurable]]: false }
,TypeError
генерируется исключение.