Can't understand the behavior of deleting vars in JavaScript

后端 未结 3 1381
后悔当初
后悔当初 2021-01-19 22:01

Here is the issue:

var x = 5;
window.x === x // true. x, as it seems, is a property of window
delete x; // false
delete window.x; // false;

相关标签:
3条回答
  • 2021-01-19 22:18

    This is how I understand that:

    var x = 5; declared in the global scope creates the new window property x.

    window.x = 5; declared (whereever) creates the new window property x as well. That's why window.x === x gives you true.

    The difference is that javascript by default sets different descriptors for x property according to the way (one of two above) it is declared.

    var x = 5 is equal to:

    Object.defineProperty(window,'x',{
      value: 5,
      writable: true,
      enumerable: true,
      configurable: false
    });
    

    while window.x = 5 is equal to:

    Object.defineProperty(window,'x',{
      value: 5,
      writable: true,
      enumerable: true,
      configurable: true
    });
    

    The configurable descriptor, if false, forbides to delete the property. We can assume, that javascript use Object.defineProperty with different descriptor settings under the hood when we declare variables in a simple way with var keyword or without it (automatically assigned to window). You can simply check that:

    var x = 5;
    window.y = 5;
    
    console.log(Object.getOwnPropertyDescriptor(window,'x')); //configurable:false
    console.log(Object.getOwnPropertyDescriptor(window,'y')); //configurable:true
    
    0 讨论(0)
  • 2021-01-19 22:24

    Essentially the reason is that declared variables are created with an internal DontDelete attribute, while properties created via assignment are not.

    Here is great article explaining the inner details of delete: Understanding delete

    When declared variables and functions become properties of a Variable object — either Activation object (for Function code), or Global object (for Global code), these properties are created with DontDelete attribute. However, any explicit (or implicit) property assignment creates property without DontDelete attribute. And this is essentialy why we can delete some properties, but not others:

    0 讨论(0)
  • 2021-01-19 22:24

    You can use delete only for deleting objects, object properties or array element.

    delete expression

    delete will be not working if expression can't be represented as property. So delete can remove global variable, but not variables inited by var.

    So, let me explain:

    var x = 5;
    

    You create variable in global scope by var, not property of window object. This var is just linked to window.x. And then you compare window.x === x it will return true. But:

    delete x; // deleting variable, not property, return false
    delete window.x; // resolve link to x and also deleting variable, not property, return false
    

    BUT

    window.x = 5;//add property
    delete window.x; // can delete property, return true
    

    AND

    window.x = 5;//add property
    delete x; //resolve x. it's a propery of window, return true
    

    and older

    In ECMAScript 262/3 as @Peter explain is available DontDelete flag. But in ECMAScript 262/5.1 in strict mode deleting is regulated by Configurable flag:

    When a delete operator occurs within strict mode code, a SyntaxError exception is thrown if its UnaryExpression is a direct reference to a variable, function argument, or function name. In addition, if a delete operator occurs within strict mode code and the property to be deleted has the attribute { [[Configurable]]: false }, a TypeError exception is thrown.

    0 讨论(0)
提交回复
热议问题