Featured image of post 【JavaScript 變數】Delete 刪除變數釋放記憶體

【JavaScript 變數】Delete 刪除變數釋放記憶體

【JavaScript 變數】Delete 刪除變數釋放記憶體

Photo by Mohammad Rahmani on Unsplash

delete 功能

刪除指定的屬性變數,當刪除後,Garbage Collection 會自動回收這個沒有在使用的記憶體

成功刪除的時候會回傳 true,否則回傳 false

delete object.property
delete object['property']
const Employee = {
    name: 'Kay',
    age: 17
};

// Kay
console.log(Employee.name);

// 刪除物件屬性值
delete Employee.name;

// undefined
console.log(Employee.name);
// { age: 17 }
console.log(Employee);

delete 刪除狀況

如果你試圖刪除的屬性不存在

delete 將不會起任何作用,但仍會 返回 true

const Employee = {
    name: 'Kay',
    age: 17
};

// 刪除物件屬性值
let deleteResult = delete Employee.job;

// true
console.log(deleteResult);
// { name: 'Kay', age: 17 }
console.log(Employee);

delete操作只會在 自身的屬性上起作用

如果對象的原型鏈上有一個與待刪除屬性同名的屬性,那麼刪除屬性之後,對象會使用原型鏈上的那個屬性

// 動物
let animal = {
    // 會吃
    eats: true,
    walk : () => {
        console.log(`[animal] walking`);
    }
};
// 兔子
let rabbit = {
    // 會跳
    jumps: true,
    walk : () => {
        console.log(`[rabbit] walking`);
    }
};

// 設定兔子原型是動物
Object.setPrototypeOf(rabbit, animal)

// [rabbit] walking
rabbit.walk();

let deleteResult = delete rabbit.walk;

// true
console.log(deleteResult);
// [animal] walking
rabbit.walk();

任何使用 var 聲明的屬性不能從全域函數的作用域中刪除。

這樣的話,delete操作不能刪除任何在全域中的函數(無論這個函數是來自於函數聲明或函數表達式)

除了在全域中的函數不能被刪除,在 物件(object) 中的函數是能夠用 delete 操作刪除的。

刪除物件中的函式成功

let Employee = {
    name : 'Kay',
    sayHi : function() {
        console.log(`Hi, I'm ${this.name}`);
    }
};

// Hi, I'm Kay
Employee.sayHi();

// { name: 'Kay', sayHi: [Function: sayHi] }
console.log(Employee);

let deleteResult = delete Employee.sayHi;
// true
console.log(deleteResult);

// { name: 'Kay' }
console.log(Employee);

刪除 var 全域變數失敗

var Employee = ['Kay', 'Jay', 'KJ'];

// [ 'Kay', 'Jay', 'KJ' ]
console.log(Employee);
let deleteResult = delete Employee;
// false
console.log(deleteResult);
// [ 'Kay', 'Jay', 'KJ' ]
console.log(Employee);

刪除 var 函數的作用域變數失敗

let testDeleteFunctionVariable = () => {
    var Employee = ['Kay', 'Jay', 'KJ'];

    // [ 'Kay', 'Jay', 'KJ' ]
    console.log(Employee);
    let deleteResult = delete Employee;
    // false
    console.log(deleteResult);
    // [ 'Kay', 'Jay', 'KJ' ]
    console.log(Employee);
};


testDeleteFunctionVariable();

刪除 var 函數變數失敗

var testDeleteFunction = () => {
    console.log('test delete function');
};

// [Function: testDeleteFunction]
console.log(testDeleteFunction)

let deleteResult = delete testDeleteFunction;
// false
console.log(deleteResult);

// [Function: testDeleteFunction]
console.log(testDeleteFunction);

刪除 var 函數作用域函式變數失敗

var testDeleteFunction = () => {
    console.log('test delete function');
    var testDeleteClosureFunction = () => {
        console.log('test closure delete function');
    }

    // [Function: testDeleteClosureFunction]
    console.log(testDeleteClosureFunction)

    let deleteResult = delete testDeleteClosureFunction;
    // false
    console.log(deleteResult);

    // [Function: testDeleteClosureFunction]
    console.log(testDeleteClosureFunction);
};

testDeleteFunction();

任何用 let 或 const 定義的屬性,不能夠從它被定義的作用域中刪除

刪除 let 全域變數失敗

let Employee = ['Kay', 'Jay', 'KJ'];

// [ 'Kay', 'Jay', 'KJ' ]
console.log(Employee);
let deleteResult = delete Employee;
// false
console.log(deleteResult);
// [ 'Kay', 'Jay', 'KJ' ]
console.log(Employee);

刪除 let 函數的作用域變數失敗

let testDeleteFunctionVariable = () => {
    let Employee = ['Kay', 'Jay', 'KJ'];

    // [ 'Kay', 'Jay', 'KJ' ]
    console.log(Employee);
    let deleteResult = delete Employee;
    // false
    console.log(deleteResult);
    // [ 'Kay', 'Jay', 'KJ' ]
    console.log(Employee);
};


testDeleteFunctionVariable();

刪除 let 函數變數失敗

let testDeleteFunction = () => {
    console.log('test delete function');
};

// [Function: testDeleteFunction]
console.log(testDeleteFunction)

let deleteResult = delete testDeleteFunction;
// false
console.log(deleteResult);

// [Function: testDeleteFunction]
console.log(testDeleteFunction);

刪除 const 全域變數失敗

const Employee = ['Kay', 'Jay', 'KJ'];

// [ 'Kay', 'Jay', 'KJ' ]
console.log(Employee);
let deleteResult = delete Employee;
// false
console.log(deleteResult);
// [ 'Kay', 'Jay', 'KJ' ]
console.log(Employee);

刪除 let 函數作用域函數變數失敗

let testDeleteFunction = () => {
    console.log('test delete function');
    let testDeleteClosureFunction = () => {
        console.log('test closure delete function');
    }

    // [Function: testDeleteClosureFunction]
    console.log(testDeleteClosureFunction)

    let deleteResult = delete testDeleteClosureFunction;
    // false
    console.log(deleteResult);

    // [Function: testDeleteClosureFunction]
    console.log(testDeleteClosureFunction);
};

testDeleteFunction();

刪除 const 函數的作用域變數失敗

const testDeleteFunctionVariable = () => {
    const Employee = ['Kay', 'Jay', 'KJ'];

    // [ 'Kay', 'Jay', 'KJ' ]
    console.log(Employee);
    let deleteResult = delete Employee;
    // false
    console.log(deleteResult);
    // [ 'Kay', 'Jay', 'KJ' ]
    console.log(Employee);
};


testDeleteFunctionVariable();

刪除 const 函數變數失敗

const testDeleteFunction = () => {
    console.log('test delete function');
};

// [Function: testDeleteFunction]
console.log(testDeleteFunction)

let deleteResult = delete testDeleteFunction;
// false
console.log(deleteResult);

// [Function: testDeleteFunction]
console.log(testDeleteFunction);

刪除 const 函數作用域函數變數失敗

const testDeleteFunction = () => {
    console.log('test delete function');
    const testDeleteClosureFunction = () => {
        console.log('test closure delete function');
    }

    // [Function: testDeleteClosureFunction]
    console.log(testDeleteClosureFunction)

    let deleteResult = delete testDeleteClosureFunction;
    // false
    console.log(deleteResult);

    // [Function: testDeleteClosureFunction]
    console.log(testDeleteClosureFunction);
};

testDeleteFunction();

不可設置的(Non-configurable)屬性不能被移除

MathArrayObject 內建物件的屬性,以及使用 Object.defineProperty() 方法設置為不可設置的屬性不能被刪除。

內建物件的屬性不可刪除

let deleteResult = delete Math.PI;
// false
console.log(deleteResult);
// 3.141592653589793
console.log(Math.PI);

使用 Object.defineProperty() 方法設置為不可設置的屬性不能被刪除

let Employee = {
    name : 'Kay',
    age : 17
};
Object.defineProperty(Employee, 'name', {configurable: false});

// { name: 'Kay', age: 17 }
console.log(Employee);
// false
console.log(delete Employee.name);
// true
console.log(delete Employee.age);
// { name: 'Kay' }
console.log(Employee);

使用 delete 刪除陣列元素

陣列元素刪除後,資料還是在,取得陣列筆數還是取得 3 筆

  • 使用 for in 輪詢陣列不會取得刪除的資料
  • 使用 forEach 輪詢陣列不會取得刪除的資料
let Employee = ['Kay', 'Jay', 'KJ'];

// [ 'Kay', 'Jay', 'KJ' ]
console.log(Employee);

let deleteResult = delete Employee[1];
// true
console.log(deleteResult);

// [ 'Kay', <1 empty item>, 'KJ' ]
console.log(Employee);

// 3:陣列資料還是 3 筆
console.log(Employee.length);

// 使用 for in 輪詢陣列不會取得刪除的資料
for (let index in Employee) {
    // index: 0: Kay
    // index: 2: KJ
    console.log(`index: ${index}: ${Employee[index]}`);
}

// 使用 forEach 輪詢陣列不會取得刪除的資料
Employee.forEach((currentValue, index) => {
    // index: 0: Kay
    // index: 2: KJ
    console.log(`index: ${index}: ${currentValue}`);
});

使用 Array.splice() 刪除陣列元素

使用 Array.splice() 刪除元素資料會真的不見,會影響到原本的變數

let Employee = ['Kay', 'Jay', 'KJ'];

// [ 'Kay', 'Jay', 'KJ' ]
console.log(Employee);

// 使用 Array.splice() 刪除陣列元素
Employee.splice(1, 1);

// [ 'Kay', 'KJ' ]
console.log(Employee);

// 2:陣列資料剩餘 2 筆
console.log(Employee.length);

參考資料

Donate KJ 贊助作者喝咖啡

如果這篇文章對你有幫助的話,可以透過下面支付方式贊助作者喝咖啡,如果有什麼建議或想說的話可以贊助並留言給我
If this article has been helpful to you, you can support the author by treating them to a coffee through the payment options below. If you have any suggestions or comments, feel free to sponsor and leave a message for me!
方式 Method 贊助 Donate
PayPal https://paypal.me/kejyun
綠界 ECPay https://p.ecpay.com.tw/AC218F1
歐付寶 OPay https://payment.opay.tw/Broadcaster/Donate/BD2BD896029F2155041C8C8FAED3A6F8
All rights reserved,未經允許不得隨意轉載
Built with Hugo
Theme Stack designed by Jimmy