代码之家  ›  专栏  ›  技术社区  ›  Guss

如何取消设置JavaScript变量?

  •  532
  • Guss  · 技术社区  · 16 年前

    window 属性,但我认为这并不重要),它已经由之前的脚本填充,但我不希望稍后运行的另一个脚本看到它的值,甚至不希望它被定义。

    我把 some_var = undefined typeof some_var == "undefined" 但我真的不认为这是正确的做法。

    你怎么认为?

    10 回复  |  直到 4 年前
        1
  •  499
  •   Peter Mortensen Pieter Jan Bonestroo    4 年前

    delete

    var

    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
    

    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
    

    变量

    g_a VariableEnvironment “附加到当前作用域-在使用的情况下,这可能是函数执行上下文 变量 在函数内部(尽管当你考虑 let 多变的环境 window ).

    参考文献 多变的环境 ECMAScript 10.5 eval 变量 无法删除。

    变量

    当尝试在不使用的情况下为名称赋值时 变量 LexicalEnvironment 词汇环境 词汇环境 词汇环境 ,它看起来像父母 词汇环境 (详见 10.3.1 10.2.2.1 ).顶层 词汇环境 global environment 变量 在当前作用域或任何外部作用域中的关键字,JavaScript最终将获取 窗口 反对作为参考。正如我们之前所了解的,可以删除对象的属性。

    备注

    1. 重要的是要记住 变量 变量 a 多变的环境 而不是 窗口 财产及其价值将是 10 在代码末尾:

      function test() { a = 5; var a = 10; }
      
    2. 上述讨论是在未启用“严格模式”时进行的。当使用“严格模式”时,查找规则有点不同,在没有“严格模式“的情况下,解析为窗口属性的词法引用将在“严格模式下”引发“未声明的变量”错误。我真的不明白这是在哪里指定的,但它是浏览器的行为方式。

        2
  •  280
  •   Peter Mortensen Pieter Jan Bonestroo    4 年前

    scunliffe's answer

    delete window.some_var;
    

    删除 当目标不是对象属性时,应该是no操作。例如。,

    (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.
    

    所以要小心。

    注:我的答案是 somewhat inaccurate (见最后的“误解”)。该链接解释了所有血腥的细节,但总结是,浏览器之间可能存在很大差异,具体取决于您要删除的对象。 delete object.someProp object !== window 。我仍然不会用它来删除用声明的变量 var

        3
  •  37
  •   pimvdb    14 年前

    如果你隐式声明变量而没有 var ,正确的方法是使用 delete foo .

    ReferenceError 将被抛出,因为您无法将字符串添加到未声明、未定义的标识符中。例子:

    x = 5;
    delete x
    alert('foo' + x )
    // ReferenceError: x is not defined
    

    foo = false
    

    null , false , undefined , 0 , NaN ,或 '' !== 操作员,而是 != == 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)
    

    如果你声明了一个变量 变量 您无法删除它:

    (function() {
        var x = 5;
        alert(delete x)
        // false
    })();
    

    js> var x
    js> delete x
    false
    

    Math.PI :

    js> delete Math.PI
    false
    

    删除 与任何语言一样,如果你足够关心,你应该阅读:

        4
  •  33
  •   Peter Mortensen Pieter Jan Bonestroo    4 年前

    noah's answer 有关完整详细信息

    //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;
    

    参考文献

        5
  •  15
  •   Peter Mortensen Pieter Jan Bonestroo    4 年前

    TLDR:简单定义的变量(没有 var , let , const )可以删除 delete 。如果您使用 变量 , , 常量 -它们也无法删除 删除 也不与 Reflect.deleteProperty .

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

        6
  •  6
  •   Peter Mortensen Pieter Jan Bonestroo    4 年前

    公认的答案(和其他答案)已经过时了!

    太长,读不下去了

    例子:

    x = null;
    


    使用 删除 mark-and-sweep garbage-collection unreachable “(决定代码是否仍然需要它们)。

    使用JavaScript,在所有现代浏览器中:

    • 对象在内存中保留时 reachable .
    • 可到达的 :一组相互链接的对象可能无法作为一个整体访问。 ( source )

    删除 操作员仅用于 删除属性 删除变量。

    与普遍看法不同(可能是由于其他编程语言,如 delete in C++ 删除 ( source )

    strict mode ( 'use strict'; ,而不是常规/ "sloppy mode" )尝试删除变量将引发错误,这是不允许的。JavaScript中的普通变量不能使用 删除 操作员 ( 来源 )


    …唉,唯一的解决方案是:

    Freeing the contents of a variable

    null :

    var x;
    
    // ...
    
    x = null;    // (x can now be garbage collected)
    

    ( 来源 )


        7
  •  3
  •   Peter Mortensen Pieter Jan Bonestroo    4 年前

    Reflect.deleteProperty() :

    Reflect.deleteProperty(myObject, 'myProp');
    // it is equivalent to:
    delete myObject.myProp;
    delete myObject['myProp'];
    

    window

    Reflect.deleteProperty(window, 'some_var');
    

    false (以及 delete operator ).在其他情况下,它会返回 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
    
        8
  •  2
  •   Scarecrow    10 年前

    delete 回报 true

    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
    })()
    

        9
  •  2
  •   ashleedawg    5 年前

    与简单属性相比,变量具有以下属性 删除

    但是,在一个执行上下文中,此规则不受影响。这是 评估 上下文:没有为变量设置[[可配置]]属性。

        10
  •  2
  •   Guss    5 年前

    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'];
    
        11
  •  1
  •   oriadam    4 年前

    var x; x delete delete x;

        12
  •  0
  •   Peter Mortensen Pieter Jan Bonestroo    4 年前

    只需将变量清零,然后显式检查它是否为null。为什么要费心从作用域中删除变量?这有什么目的是无效不能实现的?

    foo = null;
    if(foo === null) or if(foo !== null)
    
    推荐文章