Delete 刪除變數釋放記憶體

Node.js Delete 刪除變數釋放記憶體

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);

參考資料