delete 一个未定义的 属性 和一个由 const 声明的 属性 之间有什么区别,让我们使用 delete operatorin Javascript?

what is the difference between delete an undefined property and a property which declared by const, let using delete operatorin Javascript?

请看代码,

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" 之间存在差异]返回值?

我的理解是,用 const 声明的变量存在,但未设置 属性 configurable,这就是 delete 失败的原因(因此 returns false) - 变量仍然存在。

显然删除不存在的变量不是无效操作,操作的目的是删除变量,因为不存在所以没有进行操作,但是达到了预期的效果(这就是 returns true 的原因)。

使用 constlet 声明的变量不会分配给全局对象,因此您的

const fooBar = 3;

当你这样做时不显示

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

只有使用 var 声明的变量(或根本没有声明,仅分配给,例如使用 foo)被分配给全局对象。

deletereturn:

true for all cases except when the property is an own non-configurable property, in which case, false is returned in non-strict mode.

window.foo,没有用 varletconst 声明, 可配置的 属性。 window.bar,用您的 var bar 声明,作为不可配置的 属性 分配给 window

delete fooBar returns false 因为 fooBar 虽然实际上不是 window 上的 属性,但它是一个独立的标识符,不能已删除 - delete 将在使用 delete 时导致 false,这样会在严格模式下引发错误:

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

但是noexist不是你代码中的标识符,所以没有操作甚至attempt来执行,所以它returnstrue(在严格模式下不会抛出错误)。

不能 删除常量,如 MDN 中所述。

Any property declared with let or const cannot be deleted from the scope within which they were defined

因此,当您删除常量 fooBar 时,它 return 是错误的。如果无法删除某些内容,那么您将通过 delete 语句得到 false returned。因此,例如,如果您尝试删除 var x=20; delete x;//returns false 中的 var,那么您将得到一个错误值,因为无法在其范围内删除 var。同样,const 和 let 变量不能在其范围内删除,它们也会 return 为假。

所以,我会这样想:如果某些东西在存在时不能被删除,那么你会得到一个错误的值return由删除语句编辑

此外,如果您尝试删除不存在的 属性,则删除语句 return 如 MDN 中所述是正确的。

If the property which you are trying to delete does not exist, delete will not have any effect and will return true.

因此,当您删除 this 对象上的 noexist 属性 时,它 return 为真。

追加 的出色答案。当您将值分配给未声明的变量(如 foo = 1)时,会发生这种情况:

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

因此 configurable 属性为真,您可以使用 delete 关键字删除此 属性,它将 return 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 的变量声明也会将该变量作为不可配置的 属性 添加到全局对象中。但是,当您使用 constlet 执行相同操作时,不会发生此行为。

要了解有关 letconst 变量及其存储方式的更多信息,请阅读此 letconst 变量存储在不可访问的声明性环境记录中。

最后一个变量不存在的情况,还是delete returned true 因为delete操作符就是这么设计的

来自docs

If the property which you are trying to delete does not exist, delete will not have any effect and will return true