JS删除与delete操作符

我以为的删除以及我的测试

var a = 1;
b = 2;
let c =3;
const d = 4;
console.log(delete a);  // false
console.log(delete b);  // true
console.log(delete c);  // false
console.log(delete d);  // false

console.log(a);         // 1
console.log(b);         // b is not defined
console.log(c);         // 3 
console.log(d);         // 4

从结果中可以看到,使用关键词声明的变量均不可以删除。(let和const声明的变量不可重复声明,会抛出错误)

var a = {b: 1, c: 2};
var d = a;

a.b = 999;
console.log(a);        // Object { b: 999, c: 2 }
console.log(d);        // Object { b: 999, c: 2 }

console.log(delete a); // false

a = undefined;

console.log(a);        // undefined
console.log(d);        // Object { b: 999, c: 2 }

从以上代码结果得出:

  1. 对象是引用类型,原对象改变,那么引用此对象的所有变量都会改变。实际var d = a这里是吧a的对象地址赋值给了d,两个变量值实际是同一个对象
  2. delete关键词不能删除对象变量(实际是无法删除var关键词声明的变量)
  3. a变量整体被赋值成别的值时,d变量仍然是原对象,这佐证了var d = a实际传递的是对象的地址(不是a变量的地址)

让我们看看MDN是怎么说的

delete 操作符(MDN Web Docs)

delete 操作符用于删除对象的某个属性;如果没有指向这个属性的引用,那它最终会被释放。
原来delete操作符就是为了删除对象的属性...

var a = {a: 1, b: {c:2}, d: function(){console.log('function')}}
console.log(a);            // Object { a: 1, b: {…}, d: d() }
console.log(delete a.a);   // true
console.log(a);            // Object { b: {…}, d: d() }
console.log(delete a.b);   // true
console.log(a);            // Object { d: d() }
console.log(delete a.d);   // true
console.log(a);            // Object {  }
console.log(delete a.toString);  // true

JS中数组也是对象,那么数组也可以用delete操作符

var a = [1, {a: 1, b: 2}, [3, 4]];

console.log(delete a[0]);    // true
console.log(a);              // Array(3) [ <1 empty slot>, {…}, (2) […] ]
console.log(delete a[1]);    // true
console.log(a);              // Array(3) [ <2 empty slots>, (2) […] ]
console.log(delete a[2]);    // true
console.log(a);              // Array(3) [ <3 empty slots> ]
console.log(a.length);       // 3

由此看出,delete同样可以操作删除数组元素,但是会留下空插槽?数组的长度不会改变,因此不推荐使用delete操作符。

事实上文档还有这样说

与通常的看法不同,delete操作符与直接释放内存无关。内存管理 通过断开引用来间接完成的,查看内存管理页可了解详情。

在JS中当一个值没有被任何变量引用时,垃圾回收机制就会回收这个地址。
(内存管理页)[https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Memory_Management]

这个算法把“对象是否不再需要”简化定义为“对象是否可以获得”。
从2012年起,所有现代浏览器都使用了标记-清除垃圾回收算法。所有对JavaScript垃圾回收算法的改进都是基于标记-清除算法的改进,并没有改进标记-清除算法本身和它对“对象是否不再需要”的简化定义。

posted @ 2021-06-22 11:05  Aienming  阅读(411)  评论(0)    收藏  举报