美文网首页javascript
浅谈var和delete

浅谈var和delete

作者: nico1988 | 来源:发表于2019-12-17 00:12 被阅读0次
    image.png
    本文同发 掘金

    很久很久以前,有个人说他现在写个var,脑海中都会浮现一大堆……,不知所云……

    JavaScript6种变量声明方式中(ES5:var function ES6: let const import class),var声明可以显示的声明变量,并为变量初始化值(可选),也可以隐式声明。

    delete可以用来删除对象的属性,如果:

    • delete一个用var声明的变量
    • delete一个没有用var声明的变量
    • 如果加上'use strict' 又会如何

    请把下面两段分别放到控制台执行一下

    var a = 100;b = 200;
    delete a;
    delete b;
    console.log(a);
    console.log(b);
    

    如果加个use strict,又会如何?

    'use strict'
    var a = 100;b = 200;
    delete a;
    delete b;
    console.log(a);
    console.log(b);
    

    关于var

    语法

    var varname1 [= value1] [, varname2 [= value2] ... [, varnameN [= valueN]]];

    描述
    • var声明的变量存在声明提升,JavaScript引擎会在执行代码之前将当前的变量加入到词法栈中,也就是hosting,变量声明提升
    • 变量可以没有初始值,会保存一个特殊的值 undefined
    • 变量可以重复定义,且可以修改值
    • 变量声明语句从自动提升到所在作用域的顶端
    • 函数内重复定义对函数外无影响(局部变量)
    • 函数内重新赋值对函数外有影响
    • 对象上新增的属性,默认configurable为true
    var a = {}
    Object.getOwnPropertyDescriptor(window,'a')
    {value: {…}, writable: true, enumerable: true, configurable: false}
    a.b = 1
    Object.getOwnPropertyDescriptor(a,'b')
    {value: 1, writable: true, enumerable: true, configurable: true}
    
    • 使用var声明的变量,默认configurable为false
    var a = 1;
    Object.getOwnPropertyDescriptor(window,'a')
    {value: 1, writable: true, enumerable: true, configurable: false}
    

    关于delete

    语法
    delete object.property
    delete object['property']
    
    返回值

    非严格模式下返回true,除了遇到configurable为false和不能删除的情况

    说明
    • delete和内存管理无关,内存管理是通过判断引用标记来完成的
    • 如果在对象的原型链上存在同名属性,那么在删除之后,对象将使用原型链中的属性(换句话说,删除只对自己的属性有影响)。
    • 不能从全局作用域或函数作用域中删除用var声明的任何属性。(因为使用var声明的)
    • delete不能删除全局函数, 可以删除对象中的函数
    • 使用const和let声明的任何变量都不能通过delete删除
    • 无法删除不可配置的属性。包括内置对象(如Math、Array、Object)的属性,以及使用Object. defineproperty()等方法创建的不可配置的属性。
    • 严格模式和非严格模式的区别
      • 非严格模式,delete删除configurable为false和不能删除的返回false
      • 严格模式,delete删除configurable为false和不能删除的直接报错

    非严格模式

    function Employee() { 
      delete salary;
      var salary;
    }
    Employee();
    

    严格模式删除函数、configurable为false的都会报错

    "use strict";
    function Employee() {
      delete salary;  // SyntaxError 报错
      var salary;        
    }
    // Similarly, any direct access to a function
    // with delete will raise a SyntaxError
    function DemoFunction() {
      //some code
    }
    delete DemoFunction; // SyntaxError
    

    一些场景

    // Creates the property adminName on the global scope.
    adminName = 'xyz';            
    
    // Creates the property empCount on the global scope.
    // Since we are using var, this is marked as non-configurable. The same is true of let and const.
    var empCount = 43;
    
    EmployeeDetails = {
      name: 'xyz',
      age: 5,
      designation: 'Developer'
    };
    
    // adminName is a property of the global scope.
    // It can be deleted since it is created without var,
    // and is therefore configurable.
    delete adminName;       // returns true
    
    // On the contrary, empCount is not configurable
    // since var was used.
    delete empCount;       // returns false 
    
    // delete can be used to remove properties from objects.
    delete EmployeeDetails.name; // returns true 
    
    // Even when the property does not exist, delete returns "true".
    delete EmployeeDetails.salary; // returns true 
    
    // delete does not affect built-in static properties.
    delete Math.PI; // returns false 
    
    // EmployeeDetails is a property of the global scope.
    // Since it was defined without "var", it is marked configurable.
    delete EmployeeDetails;   // returns true
    
    function f() {
      var z = 44;
    
      // delete doesn't affect local variable names
      delete z;     // returns false
    }
    

    删除原型链上的属性(注意直接删除实例的属性,并不会影响原型的属性)

    function Foo() {
      this.bar = 10;
    }
    
    Foo.prototype.bar = 42;
    
    var foo = new Foo();
    
    // foo.bar is associated with the 
    // own property. 
    console.log(foo.bar); // 10 
    
    // Delete the own property within the 
    // foo object. 
    delete foo.bar; // returns true 
    
    // foo.bar is still available in the 
    // prototype chain. 
    console.log(foo.bar); // 42 
    
    // Delete the property on the prototype.
    delete Foo.prototype.bar; // returns true 
    
    // The "bar" property can no longer be 
    // inherited from Foo since it has been 
    // deleted. 
    console.log(foo.bar); // undefined
    

    删除数组的元素

    通过delete可以产生 稀疏数组

    var trees = ['redwood', 'bay', 'cedar', 'oak', 'maple'];
    delete trees[3]; // 这里相当于把trees变成了稀疏数组,why ? 因为 数组元素个数是4个,而数组的长度是5
    if (3 in trees) {
        // this is not executed
    }
    

    关于delete怪异的地方

    当然虽然没有违背原则,但是总觉得怪怪的


    image.png

    参考

    相关文章

      网友评论

        本文标题:浅谈var和delete

        本文链接:https://www.haomeiwen.com/subject/seydnctx.html