我在JavaScript中有一个全局变量(实际上是一个窗口属性,但我不认为这很重要),它已经由以前的脚本填充,但我不希望另一个脚本稍后运行,以查看它的值或它甚至被定义。

我已经把some_var = undefined,它用于测试类型的some_var ==“undefined”的目的,但我真的不认为这是正确的方法。

你怎么看?


当前回答

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显示相同的行为。

其他回答

详见诺亚的回答

//Option A.) set to null
some_var = null;

//Option B.) set to undefined
some_var = undefined;

//Option C.) remove/delete the variable reference
delete obj.some_var
//if your variable was defined as a global, you'll need to
//qualify the reference with 'window'
delete window.some_var;

引用:

MDN删除API 在严格模式下删除非限定变量名时出现MDN SyntaxError

如果隐式声明变量时不使用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

我有点糊涂了。如果你只是想让一个变量的值不传递给另一个脚本,那么就没有必要从作用域中删除这个变量。

只需使变量为空,然后显式检查它是否为空。为什么要麻烦地从作用域删除变量呢?这样做的目的是什么呢?

foo = null;
if(foo === null) or if(foo !== null)

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显示相同的行为。

斯坎利夫的答案是可行的,但从技术上讲,它应该是可行的

delete window.some_var;

当目标不是对象属性时,Delete应该是一个无操作。例如,

(function() {
   var foo = 123;
   delete foo; // wont do anything, foo is still 123
   var bar = { foo: 123 };
   delete bar.foo; // foo is gone
}());

但是由于全局变量实际上是窗口对象的成员,所以它是可行的。

当涉及原型链时,使用delete会变得更加复杂,因为它只从目标对象中删除属性,而不是从原型中删除。例如,

function Foo() {}
Foo.prototype = { bar: 123 };
var foo = new Foo();
// foo.bar is 123
foo.bar = 456;
// foo.bar is now 456
delete foo.bar;
// foo.bar is 123 again.

所以要小心。

注:我的回答有些不准确(见末尾的“误解”)。这个链接解释了所有血腥的细节,但总的来说,不同的浏览器之间可能有很大的差异,这取决于你要删除的对象。删除对象。someProp通常应该是安全的,只要object !== window。我仍然不会使用它来删除用var声明的变量,尽管在适当的情况下可以这样做。