JavaScript中的delete操做符

文章同步到githubgit

在JavaScript中,delete操做符用的比較少,可是仍是比較重要的,我本人面試的時候就遇到過關於delete的問題,下面總結一下delete的具體用法。

做用:

delete 操做符用於刪除對象的某個屬性。github

語法:

直接使用delete操做符面試

delete object.property 或 delete object['property']

例如:數組

var person = {
    name: 'abc'
    age: 18
}

delete person.name

console.log(person) // {age: 18}

返回值:

delete操做符具備返回值,返回值爲布爾值,對於全部狀況都是true,即便是刪除不存在的屬性也會返回true,仍是如上代碼,不防打印一下返回值看看函數

console.log(delete person.name) //true
console.log(delete person.job) //即便刪除對象不存在的屬性依然返回true

可是也有例外的狀況(返回false),若是屬性是不可配置屬性(對於不可配置屬性的概念,能夠參考Object. defineProperty,我第一次據說這個概念的時候也有點蒙圈), 在非嚴格模式下,返回false,在嚴格模式下則會拋出語法錯誤的異常。this

具體使用

1. 對象屬性不存在

如上所述,若是刪除對象不存在的屬性,delete無效,可是返回值仍然爲truespa

2. 原型鏈上存在該同名屬性

若是delete操做符刪除屬性成功,則該屬性將永遠不存在,可是該對象原型鏈上存在該同名屬性,則該對象會從原型鏈上繼承該同名屬性。但和內存並沒有關聯,內存管理並非delete操做符能夠操做的,並且一點關係也沒有。內存管理推薦MDN這篇文章prototype

// 構造函數
function Person() {
    this.name = "張三",
    this.job = "工程師"
}

Person.prototype.name = "李四"
// 建立實例對象
var p = new Person();
// 只刪除p實例的name屬性
delete p.name;
console.log(p) => // 經過打印以下圖,name屬性成功刪除

圖片描述

接下來看: 
console.log(p.name) => // '李四' 依然能夠訪問到

因此能夠看出delete操做只會在自身的屬性上起做用,這裏能console出來'張三',是做用域鏈的緣由,當實例自己無該屬性的時候,就會去找它的protype身上有無該同名屬性。code

3. 使用var聲明

使用var聲明的屬性(包括函數),不能從全局做用域或函數做用域中刪除對象

在全局做用域中聲明屬性:

// 聲明屬性
var a = 1; // 等同於window.a
delete a  // 嚴格模式下拋出語法異常 SyntaxError
console.log(a); // 1 非嚴格模式下
console.log(delete a); // 非嚴格模式下false
// 聲明函數
var fn = function () {
    console.log(1);
}
delete fn // 嚴格模式下拋出語法異常  SyntaxError
fn() // 1 非嚴格模式下delete失效, 函數依然存在

// 另外, 除字面量定義外,匿名函數定義函數效果也是同樣

在函數做用域中聲明屬性(效果和在全局做用域中同樣):

// 局部做用域聲明屬性
funtion fn() {
    var a = 1;
    delete a; // 嚴格模式下拋出語法異常 SyntaxError
    console.log(a); // 1
    console.log(delete a); // 非嚴格模式下false
}

fn();
// 局部做用域聲明函數
var fn = function() {
    var fn2 = function() {
        console.log(1);
    };
    delete fn2 // 嚴格模式下拋出語法異常 SyntaxError 
    console.log(delete fn2); // false 非嚴格模式下
    fn2(); // 1
}
fn();

另外, 須要注意的是,在對象中定義的函數是能夠刪除的,和屬性同樣,好比

var person = {
    name: '張三',
    showName: function () {
        console.log(this.name);
    }
}
delete person.showName
console.log(person.showName) // undefined

4. let和const聲明的屬性

任何用let或const聲明的屬性不可以從它被聲明的做用域中刪除,我試了下,和var的效果是同樣的,目前只能理解到這,若是知道的大神請指點下

5. 不可設置的屬性

Math, Array, Object等內置對象的屬性不可刪除

console.log(Array.length); // 1
delete Array.length
console.log(Array.from); 0
delete Array.prototype //嚴格模式下拋出異常
console.log(Array.prototype) // 非嚴格模式下,prototype依然存在, 能夠本身試試了,本身動手,豐衣足食
console.log(Array.prototype.join); // 非嚴格模式下,join方法依然存在

須要注意的是,只是這些內置對象的屬性不可刪除,內置對象的方法是能夠刪除的,好比:

console.log(Array.forEach); // 內置函數
delete Array.forEach // 不用區分嚴格模式與否
console.log(Array.forEach); // undefined

Object.defineProperty()設置爲不可設置的屬性,不可刪除

var person = {};
Object.defineProperty(person, 'name', {
    value: '張三',
    configurable: false
})
delete person.name // 嚴格模式下,拋出異常
console.log(person.name); // 張三
console.log(delete person.name); // 非嚴格模式false

var, let以及const建立的不可設置的屬性不能被delete操做刪除

var a = 'abc'; // 屬於window 等同於window.a
var aVal = Object.getOwnPropertyDescriptor(window, 'a'); 
console.log(aVal);
//  aVal輸入以下   
//    {
//       value: 2,
//         writable: true, 
//         enumerable: true, 
//         configurable: false // 因爲是var聲明的屬性,因此爲false
//     }
var a = 'abc'; // 屬於window 等同於window.a
delete a // 嚴格模式下拋出異常
var aVal = Object.getOwnPropertyDescriptor(window, 'a'); 
console.log(aVal);
console.log(delete a); //false
//  非嚴格模式下,aVal輸入以下   
//    {
//       value: 2,
//         writable: true, 
//         enumerable: true, 
//         configurable: false // 因爲是var聲明的屬性,因此爲false
//     }

若是開始沒有閱讀,再去看看吧Object. defineProperty。若是瞭解,能夠直接略過。

6. 刪除數組

使用delete操做符刪除數組總某項元素時,被刪除的元素會從該數組中刪除,可是數組的length並不會改變

var arr = [1, 2, 3];
delete arr[1]
console.log(arr); // [1, undefined × 1, 2]
console.log(delete arr[1]) // true
console.log(arr[1]); // undefined

可是這裏存在一個問題

console.log(1 in arr) // false

因此若是想把數組中某一項賦值成undefined時,不該該使用delete操做符,而是直接使用下邊賦值

arr[1] = undefined;
// 這樣就能夠解決上面的問題 
console.log(1 in arr) // true

今天花了點時間,把關於delete的問題總結了一下, 方便本身查閱, 也但願能幫助須要的人, 歡迎大神指點與補充,若是你閱讀完,感受也還有收藏價值,那還等什麼,趕快收藏吧!

相關文章
相關標籤/搜索