How to unset a JavaScript variable?
我在javascript中有一个全局变量(实际上是一个
我把
你怎么认为?
(1)如果是用
例如:
1 2 3 | var g_a = 1; //create with var, g_a is a variable delete g_a; //return false console.log(g_a); //g_a is still 1 |
(2)如果创建时没有
1 2 3 | g_b = 1; //create without var, g_b is a property delete g_b; //return true console.log(g_b); //error, g_b is not defined |
技术说明1。使用
在这种情况下,引用
变量环境中的引用通常不可删除-ECMAScript 10.5中详细介绍的过程对此进行了详细说明,但足以说明除非您的代码在
当尝试在不使用
重要的是要记住,
以上讨论是在未启用"严格模式"时进行的。当使用"严格模式"时,查找规则有点不同,如果词汇引用解析为没有"严格模式"的窗口属性,则会在"严格模式"下引发"未声明的变量"错误。我不太明白这是在哪里指定的,但它是浏览器的行为方式。
@斯坎利夫的回答是可行的,但从技术上讲应该是可行的。
1 | delete window.some_var; |
当目标不是对象属性时,delete应该是no-op。例如。,
1 2 3 4 5 6 | (function() { var foo = 123; delete foo; // wont do anything, foo is still 123 var bar = { foo: 123 }; delete bar.foo; // foo is gone }()); |
但是,由于全局变量实际上是窗口对象的成员,所以它可以工作。
当涉及到原型链时,使用delete会变得更复杂,因为它只从目标对象中移除属性,而不是原型。例如。,
1 2 3 4 5 6 7 8 | 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. |
所以小心点。
编辑:我的回答有点不准确(见末尾的"误解")。链接解释了所有的详细信息,但总结是,浏览器之间可能存在很大的差异,这取决于要从中删除的对象。只要
如果隐式声明不带
但是,在删除它之后,如果您试图在诸如addition之类的操作中使用它,那么会抛出
1 2 3 4 | x = 5; delete x alert('foo' + x ) // ReferenceError: x is not defined |
在某些情况下,将它赋给false、null或undefined可能更安全,因此它是声明的,不会抛出这种类型的错误。
1 | foo = false |
注意,在ecmascript中,
还要注意,
1 2 3 4 5 | 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) |
如果您用
1 2 3 4 5 | (function() { var x = 5; alert(delete x) // false })(); |
Rhino:
1 2 3 | js> var x js> delete x false |
也不能删除一些预定义的属性,如
1 2 | 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
1 2 3 4 | some_var = null; //or remove it.. delete some_var; |
tldr:简单定义的变量(没有
铬55:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | simpleVar ="1"; "1" delete simpleVar; true simpleVar; VM439:1 Uncaught ReferenceError: simpleVar is not defined at :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" |
FF Nightly 53.0A1显示相同的行为。
ECMAScript 2015提供反映API。可以使用reflect.delete property()删除对象属性:
1 2 3 4 | Reflect.deleteProperty(myObject, 'myProp'); // it is equivalent to: delete myObject.myProp; delete myObject['myProp']; |
删除全局
1 | Reflect.deleteProperty(window, 'some_var'); |
在某些情况下,无法删除属性(当属性不可配置时),然后此函数返回
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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 |
在严格模式下运行时,
1 2 3 4 5 6 7 | '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 |
与简单属性相比,变量具有属性[[可配置]],这意味着无法通过删除运算符删除变量。但是,有一个执行上下文不受此规则影响。它是eval上下文:这里没有为变量设置[[可配置]]属性。
删除运算符从对象中删除属性。
1 2 | delete object.property delete object['property'] |
https://developer.mozilla.org/en-us/docs/web/javascript/reference/operators/delete
根据你需要的问题
1 2 3 | delete some_var; delete window.some_var; delete window['some_var']; |
除了每个人都写过的以外,还要注意
更新:
在最新的Chrome上测试,一切都是可以删除的。
1 2 3 4 5 6 7 8 9 10 11 | implicit_global = 1; window.explicit_global = 1; function_set = function() {}; function function_dec() { }; var declared_variable = 1; delete delete implicit_global; // true, tested on Chrome 52 delete window.explicit_global; // true, tested on Chrome 52 delete function_set; // true, tested on Chrome 52 delete function_dec; // true, tested on Chrome 52 delete declared_variable; // true, tested on Chrome 52 |
如果在首次使用时声明了变量(使用var x;),则不能删除该变量。但是,如果变量x第一次出现在脚本中而没有声明,则可以使用删除运算符(delete x;)删除变量,这与删除数组元素或删除对象属性非常相似。
我有点困惑。如果您只想让一个变量值不传递给另一个脚本,那么就不需要从作用域中删除该变量。只需使变量无效,然后显式检查它是否为空。为什么要从作用域中删除变量?这台服务器的无效不能有什么目的?
1 2 | foo = null; if(foo === null) or if(foo !== null) |