我有点搞不懂JavaScript的删除操作符。以下面这段代码为例:

var obj = {
    helloText: "Hello World!"
};

var foo = obj;

delete obj;

执行这段代码后,obj为空,但foo仍然引用与obj完全相同的对象。我猜这个对象就是foo指向的那个对象。

这让我很困惑,因为我以为写delete obj删除的是obj在内存中所指向的对象——而不仅仅是变量obj。

这是因为JavaScript的垃圾收集器是在保留/释放的基础上工作的,所以如果我没有任何其他变量指向对象,它将从内存中删除?

(顺便说一下,我的测试是在Safari 4中完成的。)


当前回答

刚刚找到一个jsperf,你可能认为有趣的在这个问题上。(把它放在周围可以方便地完成图片)

它比较了delete、设置null和设置undefined。

但请记住,当您多次删除/设置属性时,它会测试情况。

其他回答

delete命令对常规变量无效,只对属性有效。在删除命令之后,属性没有值null,它根本不存在。

如果属性是对象引用,则delete命令删除属性,但不删除对象。如果该对象没有其他引用,则垃圾收集器将处理该对象。

例子:

var x = new Object();
x.y = 42;

alert(x.y); // shows '42'

delete x; // no effect
alert(x.y); // still shows '42'

delete x.y; // deletes the property
alert(x.y); // shows 'undefined'

(在Firefox中测试。)

刚刚找到一个jsperf,你可能认为有趣的在这个问题上。(把它放在周围可以方便地完成图片)

它比较了delete、设置null和设置undefined。

但请记住,当您多次删除/设置属性时,它会测试情况。

Setting a variable to null makes sure to break any references to objects in all browsers including circular references being made between the DOM elements and Javascript scopes. By using delete command we are marking objects to be cleared on the next run of the Garbage collection, but if there are multiple variables referencing the same object, deleting a single variable WILL NOT free the object, it will just remove the linkage between that variable and the object. And on the next run of the Garbage collection, only the variable will be cleaned.

来自Mozilla文档,“您可以使用delete操作符删除隐式声明的变量,但不能删除用var语句声明的变量。”

链接如下:https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference:Operators:Special_Operators:delete_Operator

我们有多种方法来删除Object属性。

箭头函数:我们还可以使用箭头函数从对象中删除属性,这是一个单行解决方案。

const obj = {
    'first': 'one',
    'second': 'two',
    'third': 'three'
}

const fn = (key, { [key]: deletedKey, ...others }) => others;

console.log(fn('first', obj))        // { 'second': 'two', 'third': 'three' }

Reduce方法:在javascript中我们可以使用Reduce方法从原始对象中删除特定的属性。

const obj = {
    'first': 'one',
    'second': 'two',
    'third': 'three'
}

const exceptSecond = Object.keys(obj).reduce((acc, key) => {
    if (key !== 'second') {
        acc[key] = obj[key]
    }
    return acc
}, {})

console.log(exceptSecond)    // { 'first': 'one', 'third': 'three' }

删除:这是一种简单的删除方法。

delete obj.first; 
// Or
delete obj['first'];

使用unset,省略,Pic方法从"loadash" lib:

    import { unset } from 'lodash'


const obj = {
    'first': 'one',
    'second': 'two',
    'third': 'three'
}

unset(obj, 'third')        // true

console.log(obj)        // { 'first': 'one', 'second': 'two' }

// Using omit 
import { omit } from 'lodash'
const obj1 = {
    'first': 'one',
    'second': 'two',
    'third': 'three'
}

omit(obj1, [ 'first', 'second' ])

console.log(obj1)  

反射删除属性:这是ES6中引入的新的内置对象。现在可以通过调用这个Refect对象的deleted property()函数来删除对象属性。

这个函数等价于我们在第一个方法中讨论的delete操作符。

const someObject = {
    'first': 'one',
    'second': 'two',
    'third': 'three'
}

Reflect.deleteProperty(someObject, 'second')

console.log(someObject)        //  { 'first': 'one', 'third': 'three' }