В чем разница между удалением неопределенного свойства и свойством, объявленным const, например, с помощью оператора delete в Javascript? - PullRequest
0 голосов
/ 21 января 2019

Пожалуйста, посмотрите на код,

foo = 1;
delete foo; // true
Object.getOwnPropertyDescriptor(this,'foo').configurable // true
var bar = 2;
delete bar; // false
Object.getOwnPropertyDescriptor(this,'bar').configurable // false
const fooBar = 3;
Object.getOwnPropertyDescriptor(this,'fooBar').configurable // undefined
delete fooBar; //false
Object.getOwnPropertyDescriptor(this,'noexist').configurable // undefined
delete noexist; // true

На основе MDN оператор удаления может работать только со свойствами, для которых их собственный настраиваемый дескриптор равен true, так почему существует разница между возвращаемым значением delete "fooBar" и "noexist"?

Ответы [ 4 ]

0 голосов
/ 21 января 2019

Добавление к отличному ответу от CertainPerformance . Когда вы присваиваете значения необъявленной переменной, такой как foo = 1, это происходит:

Object.defineProperty(window, 'foo', {configurable: true, value: 1});
console.log(delete foo);
console.log(window.foo); //deleted from window

Таким образом, атрибут configurable имеет значение true, и вы можете удалить это свойство, используя ключевое слово delete, и оно вернет true.

Когда вы объявляете переменную с var bar = 2, это происходит:

Object.defineProperty(window, 'bar', {configurable: false, value: 2});
console.log(delete bar);
console.log(window.bar); //still the property exists, delete does not work in a non-configurable property

Здесь атрибут configurable равен false, поэтому вы не сможете удалить его, используя ключевое слово delete. В режиме use strict это приведет к TypeError.

Помните, что в JavaScript объявление переменной в глобальной области действия с использованием var также добавляет эту переменную в качестве неконфигурируемого свойства к глобальному объекту. Но такое поведение не происходит, когда вы делаете то же самое, используя const и let.

Чтобы узнать больше о переменных let и const и о том, как они хранятся, прочитайте этот ответ . Переменные let и const хранятся в декларативной записи среды, которая недоступна.

В последнем случае, когда переменная не существует, по-прежнему delete возвращает true, потому что так устроен оператор удаления.

Из документов :

Если свойство, которое вы пытаетесь удалить, не существует, удалите не будет иметь никакого эффекта и вернет true

0 голосов
/ 21 января 2019

Переменные, объявленные с const или let, не назначаются глобальному объекту, поэтому ваш

const fooBar = 3;

не отображается, когда вы делаете

Object.getOwnPropertyDescriptor(this,'fooBar').configurable

Глобальные объекты присваиваются только переменным, объявленным с var (или никогда не объявляемым вообще, только назначенным, например, с foo).

delete будет возврат :

true для всех случаев, кроме случаев, когда свойство является собственным ненастраиваемым свойством, и в этом случае возвращается false в нестрогом режиме.

window.foo, не объявленный с var, let или const, , является настраиваемым свойством. window.bar, объявленное с помощью var bar, присваивается window как ненастраиваемое свойство.

delete fooBar возвращает false, потому что fooBar, хотя фактически не является свойством window, является автономным идентификатором, который не может быть удален - delete приведет к false всякий раз, когда используется delete подобным образом выкинул бы ошибку в строгом режиме:

'use strict';
const someVar = true;
delete someVar;

Но noexist не является идентификатором в вашем коде, поэтому нет никакой операции, чтобы даже пытаться выполнить, поэтому он возвращает true (и в строгом режиме не будет выдано никакой ошибки).

0 голосов
/ 21 января 2019

Вы не можете удалить константу, как указано в MDN.

Любое свойство, объявленное с помощью let или const, не может быть удалено из области, в которой они были определены

Таким образом, при удалении константы fooBar возвращает false.Если что-то не может быть удалено, вы получите ложь, возвращенную оператором delete.Так, например, если вы попытаетесь удалить переменную, как в var x=20; delete x;//returns false, вы получите ложное значение, поскольку переменная не может быть удалена в своей области видимости.Таким же образом const и let переменные не могут быть удалены в пределах их областей, и они также возвращали бы false.

Итак, я бы подумала так: если что-то не может быть удалено, когда оно существует, тогда выполучить ложное значение, возвращаемое оператором удаления .

Кроме того, если вы пытаетесь удалить несуществующее свойство, оператор удаления возвращает истину, как указано в MDN.

Если свойство, которое вы пытаетесь удалить, не существует, удаление не будет иметь никакого эффекта и вернет true.

Итак, когда вы удаляете noexistсвойство объекта this, возвращает true.

0 голосов
/ 21 января 2019

Насколько я понимаю, переменная, объявленная с const, существует, но свойство configurable не установлено, поэтому delete не выполняется (и, следовательно, возвращает false) - переменная все еще существует.

Очевидно, что удаление несуществующей переменной не является недопустимой операцией, цель операции - удалить переменную, и, поскольку она не существует, операция не состоялась, но желаемый эффект был достигнутдостигнут (вот почему возвращает true).

...