为什么在Javascript5严格模式下不允许使用delete?

61

我对JavaScript还算是新手。我注意到在“使用严格模式”时,似乎不能删除对象。虽然我不太喜欢删除东西(因为理论上范围应该会自动处理),但我想知道删除此功能背后的动机是什么?


4
MDN严格模式中也有很好的解释:“将错误转换为错误”。 - Gustavo Carvalho
1
遇到了同样的问题。发现 MDN 的解释很有帮助:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Errors/Delete_in_strict_mode - CyberFonic
3个回答

93
delete语句在严格模式下仍然允许使用,但其中某些特定用法是错误的。它仅限于对象属性而非简单名称,并且仅适用于可删除的对象属性。

因此,

var a = {x: 0};
delete a.x;

还可以,但是

delete Object.prototype;

不是,而且也不是

delete a;

(后者实际上是语法级别的错误,而试图删除一个不可删除的属性是运行时错误。)


10
有趣。那为什么要禁止删除实际变量本身? - sircodesalot
3
因为让一个本地变量消失的做法相当奇怪,这使得代码块的语义描述更加困难。(我其实不确定是否有官方的解释。) - Pointy
12
变量绑定在作用域内不允许更改。如果一个作用域包含var foo,那么该作用域内对foo的所有引用都将引用为该作用域创建的变量。否则,如果外部作用域存在foo变量,则会引用该变量。由于变量不是由可执行语句创建的,也不能被其销毁。 - supercat
2
window.a 在全局变量的情况下似乎是可行的。这是一个可用的替代方案吗? - Mark
1
是的,除了(如您所指出的)那些几乎与JavaScript同时发生的情况。 - Pointy
显示剩余4条评论

9

[删除] 通过例子详细解释

// The delete statement is still allowed in strict mode, but some particular uses of it are erroneous. It's only allowed for object properties, not simple names, and only for object properties that can be deleted.

// "use strict";

// creates the property adminName on the global scope
adminName = "xyz";

// creates the property empCount on the global scope
// Since we are using var, this is marked as non-configurable. The same is true of let and const.
var empCount = 43;

EmployeeDetails = {
  name: "xyz",
  age: 5,
  designation: "Developer"
};

// adminName is a property of the global scope.
// It can be deleted since it is created without var.
// Therefore, it is configurable.
console.log("delete adminName =", delete adminName); // returns true

// On the contrary, empCount is not configurable,
// since var was used.
console.log("delete empCount =", delete empCount); // returns false

// delete can be used to remove properties from objects
console.log("delete EmployeeDetails.name =", delete EmployeeDetails.name); // returns true

// Even when the property does not exists, it returns "true"
console.log("delete EmployeeDetails.salary =", delete EmployeeDetails.salary); // returns true

// delete does not affect built-in static properties
console.log("delete Math.PI =", delete Math.PI); // returns false

// EmployeeDetails is a property of the global scope.
// Since it defined without "var", it is marked configurable
console.log("delete EmployeeDetails =", delete EmployeeDetails); // returns true

x = 1;
var y = 2;

function f() {
  var z = 44;

  console.log("delete x =", delete x); // returns true
  console.log("delete y =", delete y); // returns false
  // delete doesn't affect local variable names
  console.log("delete z =", delete z); // returns false
}

f.call();


1
// 因为我们使用了 var,所以它被标记为不可配置。let 和 const 也是如此。 这并不准确。let 和 const 不会向 window 添加属性。 - senocular

1

参考文献:Delete_in_strict_mode

在 JavaScript 中,普通变量不能使用 delete 操作符进行删除。delete 操作符只能删除对象上的属性

与常见的想法不同,delete 操作符与直接释放内存无关。通过断开引用间接完成内存管理,请参阅内存管理页面delete操作符页面获取更多详细信息。

此错误仅在严格模式代码中发生。在非严格代码中,该操作仅返回 false。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接