Javascript delete

前言:

一直没有注意到JavaScript 还有 delete 这个操作符.  这几天看Creator 引擎代码,出来蛮多,这里记录一下


正文:

     2021/1/30补充:

     最近学习v8的一些东西,了解到使用delete的坏处,会是对象的属性内存结构变成map结构,而降低对象属性的查找速度。

     但是,下面的代码,又故意使用delete,这是为什么?

      其实这里是强制对象转变成map结构,这样,其实是对与属性数量不确认的对象进行优化,应为在对象属性不多的时候,每次添加一个属性,都对促使对象生成新的隐藏类,这个哥开销,相对来说是比较大的。

/**
 * !#en
 * A simple wrapper of `Object.create(null)` which ensures the return object have no prototype (and thus no inherited members). So we can skip `hasOwnProperty` calls on property lookups. It is a worthwhile optimization than the `{}` literal when `hasOwnProperty` calls are necessary.
 * !#zh
 * 该方法是对 `Object.create(null)` 的简单封装。`Object.create(null)` 用于创建无 prototype (也就无继承)的空对象。这样我们在该对象上查找属性时,就不用进行 `hasOwnProperty` 判断。在需要频繁判断 `hasOwnProperty` 时,使用这个方法性能会比 `{}` 更高。
 *
 * @method createMap
 * @param {Boolean} [forceDictMode=false] - Apply the delete operator to newly created map object. This causes V8 to put the object in "dictionary mode" and disables creation of hidden classes which are very expensive for objects that are constantly changing shape.
 * @return {Object}
 */
js.createMap = function (forceDictMode) {
    var map = Object.create(null);
    if (forceDictMode) {
        const INVALID_IDENTIFIER_1 = '.';
        const INVALID_IDENTIFIER_2 = '/';
        map[INVALID_IDENTIFIER_1] = true;
        map[INVALID_IDENTIFIER_2] = true;
        delete map[INVALID_IDENTIFIER_1];
        delete map[INVALID_IDENTIFIER_2];
    }
    return map;
};

 

 

 

 

 

首先声明: delete 操作符 与直接释放内存没有关系(C++是真的会释放内存), 内存管理是通过引用来判断的

delete 会从某个对象上移除指定元素.成功删除返回true,  否则返回 false

下面是基本用法:

var Employee = {
  age: 28,
  name: 'abc',
  designation: 'developer'
}

console.log(delete Employee.name);   // returns true
console.log(delete Employee.age);    // returns true

// 当试着删除一个不存在的属性时
// 同样会返回true
console.log(delete Employee.salary); // returns true

几种删除不了的情况

1.不可配置属性,内建金泰属性  删除不了

var Employee = {};
Object.defineProperty(Employee, 'name', {configurable: false});
console.log(delete Employee.name);  // returns false

// delete 对内建静态属性不起作用
delete Math.PI; // 返回 false 

2.原型属性删除不了(当然可以通过,原型对象删除)

function Foo() {
  this.bar = 10;
}

Foo.prototype.bar = 42;

var foo = new Foo();

// 返回 true,因为删除的是 foo 对象的自身属性
delete foo.bar;           

// foo.bar 仍然可用,因为它在原型链上可用。
console.log(foo.bar);

// 从原型上删除属性
delete Foo.prototype.bar; 

// 输出 "undefined",因为不能继承这个属性了
console.log(foo.bar);

3.全局或者函数作用域中声明的不能从作用域中删除(注意全局变量)

// 在全局作用域创建 empCount 属性
// 因为我们使用了 var,它会标记为不可配置。同样 let 或 const 也是不可配置的。
var empCount = 43;

delete empCount;       // 返回 false 

console.log(empCount)  //  43


function f() {
  var z = 44;

  // delete 对局部变量名不起作用
  delete z;     // 返回 false
}

//注意:

// 在全局作用域创建 adminName 属性  这里没有用 var let 等
adminName = 'xyz'; 
/ adminName 是全局作用域的一个属性。
// 因为它不是用 var 创建的,所在可以删除。
// 因此,它是可配置的。
delete adminName;       // 返回 true

4.数组元素的删除并不会改变数组长度,类似于赋值undefind ,却又有所差别

//注意:和下面的差别
var trees = ["redwood","bay","cedar","oak","maple"];
delete trees[3];
if (3 in trees) {
   // 这里不会执行
}
for(var i =0; i < trees.length; i++){
	console.log(trees[i])
}


var trees = ["redwood","bay","cedar","oak","maple"];
trees[3] = undefined;
if (3 in trees) {
   // 这里会被执行
}
for(var i =0; i < trees.length; i++){
	console.log(trees[i])
}

//删除某个元素用下面的形式
var trees = ['redwood', 'bay', 'cedar', 'oak', 'maple'];
trees.splice(3,1);
console.log(trees); // ["redwood", "bay", "cedar", "maple"]

 

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值