如何取消设置JavaScript变量?
我在JavaScript中有一个全局变量(实际上是一个如何取消设置JavaScript变量?,javascript,global-variables,undefined,variable-declaration,unset,Javascript,Global Variables,Undefined,Variable Declaration,Unset,我在JavaScript中有一个全局变量(实际上是一个窗口属性,但我认为这并不重要),它已经由以前的脚本填充,但我不希望以后运行的另一个脚本看到它的值,甚至不希望它被定义 我把some\u var=undefined放进去,它是为了测试some\u var==“undefined”的类型,但我真的认为这不是正确的方法 你怎么看?编辑了更新,以澄清各种选项(取决于你想要的意图) 有关详细信息,请参见@noah的答案 //Option A.) set to null some_var = null;
窗口
属性,但我认为这并不重要),它已经由以前的脚本填充,但我不希望以后运行的另一个脚本看到它的值,甚至不希望它被定义
我把some\u var=undefined
放进去,它是为了测试some\u var==“undefined”的类型,但我真的认为这不是正确的方法 你怎么看?编辑了更新,以澄清各种选项(取决于你想要的意图) 有关详细信息,请参见@noah的答案
var >代码>的函数执行上下文(尽管当您考虑<代码>让/<代码>时,它可能会变得更复杂一些),或者在“全局”的情况下。代码将VariableEnvironment附加到全局对象(通常是参考资料://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;
如果隐式声明变量而不使用,正确的方法是使用var
但是,在删除它之后,如果您尝试在诸如添加之类的操作中使用它,将抛出一个delete foo
,因为您无法将字符串添加到未声明、未定义的标识符中。例如:ReferenceError
在某些情况下,将其指定为false、null或undefined可能更安全,这样它就被声明了,不会抛出这种类型的错误x = 5; delete x alert('foo' + x ) // ReferenceError: x is not defined
请注意,在ECMAScript中,foo = false
,null
,false
,undefined
,0
或NaN
都将计算为'
。只要确保你不使用false
操作符从对象中删除属性。它不能删除变量。所以这个问题的答案取决于全局变量或属性是如何定义的 (1) 如果它是使用==代码>运算符,而不是
当类型检查布尔值时,您不希望进行身份检查(因此=
将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
在Rhino中:(function() { var x = 5; alert(delete x) // false })();
也不能删除一些预定义属性,如js> var x js> delete x false
:Math.PI
与任何语言一样,js> delete Math.PI false
也有一些奇怪的例外,如果你足够在意,你应该阅读:delete
@scunlife的答案是可行的,但从技术上讲应该是可行的
当目标不是对象属性时,delete应该是no-op。e、 gdelete window.some_var;
但由于全局变量实际上是window对象的成员,所以它可以工作 当涉及到原型链时,使用delete会变得更复杂,因为它只从目标对象中删除属性,而不从原型中删除属性。e、 g(function() { var foo = 123; delete foo; // wont do anything, foo is still 123 var bar = { foo: 123 }; delete bar.foo; // foo is gone }());
所以要小心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.
编辑:我的答案是(见最后的“误解”)。该链接解释了所有血淋淋的细节,但总结是浏览器之间可能存在很大的差异,这取决于您要从中删除的对象<代码>删除对象。只要。我仍然不会用它来删除用对象!==窗口
声明的变量,尽管在正确的情况下可以这样做。deletevar
创建的,则无法删除 例如:var
(2) 如果创建时未使用var g_a=1//使用var创建,g_a是一个变量 删除g_a//返回错误 控制台日志(g_a)//g_a仍然是1
,则可以将其删除var
技术说明 1.使用g_b=1//不使用var创建,g_b是一个属性 删除g_b//返回真值 控制台日志(g_b)//错误,未定义g_b
在这种情况下,引用“代码> GyAvar
窗口
) VariableEnvironment中的引用通常不可删除-中详细介绍的过程对此进行了详细解释,但足以说明,除非您的代码在
上下文中执行(大多数基于浏览器的开发控制台都使用该上下文),否则无法删除使用eval
声明的变量 2.不使用var
当试图在不使用var
关键字的情况下为名称赋值时,Javascript会尝试在ECMAScript规范所称的“”中定位命名引用,主要区别在于LexicalEnvironment是嵌套的,也就是说,LexicalEnvironment有一个父级(ECMAScript规范所称的“外部环境引用”)当Javascript无法在LexicalEnvironment中找到引用时,它会在父LexicalEnvironment中查找(如和中所述)。顶级词典环境是“”,它绑定到全局对象,因为它的引用是全局对象的属性。因此,如果您试图访问当前作用域或任何外部作用域中未使用var
关键字声明的名称,Javascript最终将获取var
对象的属性作为该引用。如前所述,可以删除对象上的属性 笔记窗口
重要的是要记住, 声明是“被提升的”——即,它们总是被认为发生在它们所处的范围的开始处——尽管不是可以在var
语句中完成的值初始化——它们被放在原来的位置。因此,在以下代码中,var
是来自VariableEnvironment的引用,而不是a
属性,其值将在代码末尾为窗口
:10
函数测试(){a=5;var a=10;}
上述讨论是在未启用“严格模式”时进行的。查找规则a 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 })()
implicit_global = 1; window.explicit_global = 1; function_set = function() {}; function function_dec() { }; var declared_variable = 1; 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
delete object.property delete object['property']
delete some_var; delete window.some_var; delete window['some_var'];
Reflect.deleteProperty(myObject, 'myProp'); // it is equivalent to: delete myObject.myProp; delete myObject['myProp'];
Reflect.deleteProperty(window, 'some_var');
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
'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
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"
foo = null; if(foo === null) or if(foo !== null)
x = null;