我在JavaScript中有一个全局变量(实际上是一个窗口属性,但我不认为这很重要),它已经由以前的脚本填充,但我不希望另一个脚本稍后运行,以查看它的值或它甚至被定义。
我已经把some_var = undefined,它用于测试类型的some_var ==“undefined”的目的,但我真的不认为这是正确的方法。
你怎么看?
我在JavaScript中有一个全局变量(实际上是一个窗口属性,但我不认为这很重要),它已经由以前的脚本填充,但我不希望另一个脚本稍后运行,以查看它的值或它甚至被定义。
我已经把some_var = undefined,它用于测试类型的some_var ==“undefined”的目的,但我真的不认为这是正确的方法。
你怎么看?
当前回答
与简单的属性相比,变量具有属性[[可配置的]],这意味着不可能通过删除操作符删除变量。
但是,有一个执行上下文不受此规则的影响。它是eval上下文:其中没有为变量设置[[Configurable]]属性。
其他回答
注意,delete操作成功时返回true。
2021年更新:在Chrome 88和Firefox 84上测试:
implicit_global = 1;
delete implicit_global; // true
window.explicit_global = 1;
delete explicit_global; // true
const _object = {property: 1};
delete _object.property; // true
function_set = function() {};
delete function_set; // true
function function_declaration() {};
delete function_declaration; // false
(function () {
var _var = 1;
console.log(delete _var); // false
console.log(_var); // 1
})()
(function () {
let _let = 1;
console.log(delete _let); // false
console.log(_let); // 1
})()
(function () {
const _const = 1;
console.log(delete _const); // false
console.log(_const); // 1
})()
由于浏览器更新,此答案的先前编辑已不再相关。
delete操作符从对象中删除属性。
delete object.property
delete object['property']
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/delete
根据问题,你需要下列其中一项
delete some_var;
delete window.some_var;
delete window['some_var'];
如果隐式声明变量时不使用var,正确的方法是使用delete foo。
然而,在你删除它之后,如果你试图在一个操作中使用它,比如添加,一个ReferenceError将被抛出,因为你不能将一个字符串添加到一个未声明的,未定义的标识符。例子:
x = 5;
delete x
alert('foo' + x )
// ReferenceError: x is not defined
在某些情况下,将它赋值为false、null或undefined可能更安全,这样它就被声明了,不会抛出这种类型的错误。
foo = false
请注意,在ECMAScript中,null, false, undefined, 0, NaN或“都将计算为false。只要确保你不使用!==操作符,而是在类型检查布尔值时,你不想进行身份检查(因此null将== false和false == undefined)。
还要注意,delete并没有“删除”引用,而是直接删除对象上的属性,例如:
bah = {}, foo = {}; bah.ref = foo;
delete bah.ref;
alert( [bah.ref, foo ] )
// ,[object Object] (it deleted the property but not the reference to the other object)
如果你用var声明了一个变量,你不能删除它:
(function() {
var x = 5;
alert(delete x)
// false
})();
在Rhino中:
js> var x
js> delete x
false
也不能删除一些预定义的属性,比如Math。PI:
js> delete Math.PI
false
就像任何语言一样,有一些奇怪的例外需要删除,如果你足够在乎,你应该读一下:
https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Operators/Special_Operators/delete_Operator http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf
TLDR:简单定义的变量(没有var, let, const)可以用delete删除。如果你使用var, let, const -它们不能被delete或Reflect.deleteProperty删除。
Chrome 55:
simpleVar = "1";
"1"
delete simpleVar;
true
simpleVar;
VM439:1 Uncaught ReferenceError: simpleVar is not defined
at <anonymous>:1:1
(anonymous) @ VM439:1
var varVar = "1";
undefined
delete varVar;
false
varVar;
"1"
let letVar = "1";
undefined
delete letVar;
true
letVar;
"1"
const constVar="1";
undefined
delete constVar;
true
constVar;
"1"
Reflect.deleteProperty (window, "constVar");
true
constVar;
"1"
Reflect.deleteProperty (window, "varVar");
false
varVar;
"1"
Reflect.deleteProperty (window, "letVar");
true
letVar;
"1"
Firefox Nightly 53.0a1显示相同的行为。
ECMAScript 2015提供了Reflect API。可以使用Reflect.deleteProperty()删除对象属性:
Reflect.deleteProperty(myObject, 'myProp');
// it is equivalent to:
delete myObject.myProp;
delete myObject['myProp'];
删除全局窗口对象的一个属性:
Reflect.deleteProperty(window, 'some_var');
在某些情况下,属性不能被删除(当属性不可配置时),然后该函数返回false(以及删除操作符)。在其他情况下,它返回true:
Object.defineProperty(window, 'some_var', {
configurable: false,
writable: true,
enumerable: true,
value: 'some_val'
});
var frozen = Object.freeze({ myProperty: 'myValue' });
var regular = { myProperty: 'myValue' };
var blank = {};
console.log(Reflect.deleteProperty(window, 'some_var')); // false
console.log(window.some_var); // some_var
console.log(Reflect.deleteProperty(frozen, 'myProperty')); // false
console.log(frozen.myProperty); // myValue
console.log(Reflect.deleteProperty(regular, 'myProperty')); // true
console.log(regular.myProperty); // undefined
console.log(Reflect.deleteProperty(blank, 'notExistingProperty')); // true
console.log(blank.notExistingProperty); // undefined
在严格模式下运行时,deleteProperty函数和delete操作符之间有区别:
'use strict'
var frozen = Object.freeze({ myProperty: 'myValue' });
Reflect.deleteProperty(frozen, 'myProperty'); // false
delete frozen.myProperty;
// TypeError: property "myProperty" is non-configurable and can't be deleted