你确定你会使用 delete 吗?

978 阅读1分钟

delete 是项目中使用频率并不很高的一个操作,但是某些情况下,delete 的操作结果与我设想的不太一样。

一般情况下,使用 delete 删除一个对象的某个属性时:

语法

delete expression

其中 expression 的计算结果是某个属性的引用

const Employee = {
  firstname: 'John',
  lastname: 'Doe'
}
console.log(Employee.firstname); // > "John"
delete Employee.firstname;
console.log(Employee.firstname); // > undefined

返回

  • 返回 true

  • 属性不可配置时,非严格模式返回 false ,严格模式抛出语法错误

      var Employee = {};
      Object.defineProperty(Employee, 'name', {configurable: false});
      console.log(delete Employee.name);  //  > false
    
  • 属性不存在时,依然返回 true ,只是 delete 语句没什么作用

      var Employee = {
        age: 28,
        name: 'abc',
        designation: 'developer'
      }
      console.log(delete Employee.name);   // > true
      console.log(delete Employee.salary); // > true
    

注意

  • delete 只对对象自身属性起作用,不能删除原型链上的属性

      function Foo() {
        this.bar = 10;
      }
      
      Foo.prototype.bar = 42;
      var foo = new Foo();
      delete foo.bar;           // > true
      console.log(foo.bar);  // > 42
      delete Foo.prototype.bar; 
      console.log(foo.bar); // > undefined
    
  • 使用 var 声明的属性都是不可配置的, delete 不能删除

      var nameOther = 'XYZ'; // window.nameOther = ‘XYZ’
      Object.getOwnPropertyDescriptor(window, 'nameOther');  
      
      // >  Object {value: "XYZ", 
      //                  writable: true, 
      //                  enumerable: true,
      //                  configurable: false}
      
      delete nameOther;   // > false
    
  • 不使用 var 、let、const 创建的全局作用域属性可以被 delete 删除

      adminName = 'xyz';        // window.adminName = ‘xyz’    
      Object.getOwnPropertyDescriptor(window, 'adminName')
      // > Object {value: ‘xyz’,
      // writable: true,
      // enumerable: true,
      // configurable: true}
      
      delete adminName;       // > true
    
  • delete 不能删除全局作用域中的函数,不能删除任何作用域中的 let const 声明的属性

      function f() {
        var z = 44;
        console.log(delete z); 
      }
      f() // >false
      
      delete f // >false
    
  • delete 不能删除内建静态属性

      delete Math.PI // > false
    
  • 删除数组元素时,数组长度不受影响,但被删除的元素不再属于该数组,且 delete 操作并不能直接释放内存。

      var trees = ["redwood","bay","cedar","oak","maple"];
      delete trees[3];
      if (3 in trees) {
         console.log('will not be printed')
      }
      console.log(trees)  // > (5)["redwood","bay","cedar", empty,”maple"]