JavaScript / Toán tử delete
Mở đầu
Trong lập trình, hẳn là chúng ta đã phải xử lý rất nhiều vấn đề về mảng hay các object. Sẽ có nhiều cách khác nhau để có thể xóa một phần tử trong mảng hoặc là mảng các object dựa trên một hoặc nhiều thuộc tính của phần tử đó.
Trong bài viết này, chúng ta cùng tìm hiểu về cách xóa hoặc lọc một phần tử từ một mảng hoặc object dựa trên các thuộc tính của nó. Đó là toán tử delete (delete operator) trong Javascript.
Toán tử delete
Không giống như C / C ++, toán tử delete trong JavaScript không liên quan gì đến việc phân bổ bộ nhớ. Những gì nó thực sự làm là xóa một thuộc tính khỏi đối tượng cha của nó.
Cú pháp:
delete object.property
delete object['property']
Thông số:
- object: Tên của một đối tượng hoặc một biểu thức đánh giá một đối tượng.
- property: Thuộc tính cần xóa.
Trong ví dụ sau, sau khi xóa thuộc tính foo.b
, chuỗi "yolo" sẽ được loại bỏ khỏi đối tượng foo
:
let foo = {
a: 12,
b: "yolo"
};
delete foo.b;
// foo = { a: 12 }
Khi có hai đối tượng cùng sử dụng một tham chiếu, toán tử delete chỉ loại bỏ đi thuộc tính tại đối tượng mà chúng ta đã gọi:
let boo = { c: true };
let foo = {
a: 12,
b: boo
};
let bar = {
b: boo
};
// foo = { a: 12, b: { c: true } }
// bar = { b: { c: true } }
delete foo.b;
// foo = { a: 12 }
// bar = { b: { c: true } }
Chuỗi boo
được chia sẻ giữa foo
và bar
dưới dạng thuộc tính b
, khi bạn xóa tham chiếu foo.b
, chuỗi boo
vẫn đang được tham chiếu trong bar.b
sẽ không bị ảnh hưởng.
Trong chế độ nghiêm ngặt (strict mode), khi lệnh delete được gọi và không thể xóa mục tiêu, sẽ xảy ra lỗi cú pháp. Nếu đang chạy ở chế độ không nghiêm ngặt (non-strict mode - sloopy mode), giá trị false
sẽ được trả về thay thế.
Khi một thuộc tính được tạo dưới dạng không thể định cấu hình (non-configurable), nó sẽ không thể bị xóa và thay vào đó, một TypeError sẽ xuất hiện:
'use strict';
var bar = {};
Object.defineProperty(bar, 'hello', { configurable: false });
delete bar.hello; // TypeError
var foo = {};
Object.defineProperty(foo, 'goodbye', { configurable: true });
delete foo.goodbye; // this works fine
Ngoài ra, ở chế độ nghiêm ngặt (strict mode), lệnh delete không thể sử dụng trên một tham chiếu trực tiếp đến một biến, đối số hàm hoặc tên hàm.
'use strict';
var b = 'xyz';
delete b; // Syntax Error
let c = "hello";
delete c; // SyntaxError:
const d = 15;
delete d; // SyntaxError
function hello(x) {
delete x; // Syntax Error
}
function hello() {}
delete hello; // Syntax Error
Xóa một biến được xác định bằng var
bên trong một hàm cũng sẽ không hoạt động:
'use strict';
function hello() {
var x = "what's up?";
delete x; // Syntax Error
}
Trong chế độ không nghiêm ngặt (non-strict mode), nếu bạn xác định một biến mà không có từ khóa var
, nó sẽ được thêm vào đối tượng toàn cục dưới dạng có thể định cấu hình { configurable: true }
:
awesome = true;
delete awesome; // true
Và nếu bạn xóa một cái gì đó không tồn tại, nó cũng trả về true!
delete somethingDoesNotExist; // true!!!
Nếu bạn xóa một phần tử khỏi một mảng, phần tử đó sẽ biến mất, nhưng độ dài của mảng không thay đổi:
let arr = ['a', 'b', 'c', 'd', 'e', 'f'];
// kết quả của mảng = {
0: 'a', 1: 'b', 2: 'c',
3: 'd', 4: 'e', 5: 'f',
length: 6
}
delete arr[3];
// kết quả của mảng sau khi delete = {
0: 'a', 1: 'b', 2: 'c',
4: 'e', 5: 'f',
length: 6
}
Nếu độ dài của mảng không thay đổi, các logic sẽ bị ảnh hưởng và kết quả sẽ không được như mong đợi. Vì vậy, cách phù hợp để xóa một phần tử khỏi một mảng là đặt nó thành undefined
hoặc sử dụng Array.prototype.splice
:
let arr[3] = undefined;
// kết quả của mảng = {
0: 'a', 1: 'b', 2: 'c',
3: undefined, 4: 'e', 5: 'f',
length: 6
}
arr.splice(3, 1);
// kết quả của mảng = {
0: 'a', 1: 'b', 2: 'c',
3: 'e', 4: 'f',
length: 5
}
Kết thúc
Hy vọng, bài viết này sẽ có những thông tin hữu ích, giúp anh chị em trong công việc hằng ngày của mình.
Cảm ơn và hẹn gặp lại!