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

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

你怎么看?


当前回答

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

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

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

其他回答

如果你在第一次使用时声明了一个变量(使用var x;),你就不能删除它。 但是,如果你的变量x第一次出现在脚本中没有声明,那么你可以使用delete操作符(delete x;),你的变量将被删除,这与删除数组的元素或删除对象的属性非常相似。

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

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

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声明的变量,尽管在适当的情况下可以这样做。

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

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

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

与简单的属性相比,变量具有属性[[可配置的]],这意味着不可能通过删除操作符删除变量。

但是,有一个执行上下文不受此规则的影响。它是eval上下文:其中没有为变量设置[[Configurable]]属性。