Bản dịch này chưa hoàn thành. Xin hãy giúp dịch bài viết này từ tiếng Anh.

Toán tử delete của JavaScript loại bỏ một thuộc tính khỏi object; nếu không tồn tại tham chiếu tới thuộc tính, nó sẽ tự động giải phóng.

Cú pháp

delete expression 

với expression thực thi thành tham chiếu đến thuộc tính nào đó, tức là:

delete object.property
delete object['property']

Tham số

object
Tên object, hoặc biểu thức thực thi tới object.
property
Thuộc tính muốn xoá.

Giá trị trả về

true cho mọi trường hợp trừ khi thuộc tính là own non-configurable, trong trường hợp đó, trả về false trong chế độ non-strict.

Ngoại lệ

Quăng TypeError trong chế độ strict nếu thuộc tính là own non-configurable.

Mô tả

Khác với suy nghĩ của nhiều người, toán tử delete không trực tiếp giải phóng bộ nhớ. Quản lý bộ nhớ được thực hiện trung gian qua việc bẻ tham chiếu. Xem trang quản lý bộ nhớ để biết thêm chi tiết.

Toán tử delete loại bỏ thuộc tính xác định trong object. Nếu xoá thành công, nó sẽ trả về true, ngoài ra thì false. Tuy nhiên, hãy lưu ý những kịch bản có thể xảy đến sau đây:

  • Nếu thuộc tính muốn xoá không tồn tại, delete sẽ không có tác dụng và sẽ trả về true
  • Nếu tồn tại thuộc tính có cùng tên trong prototype nối với object, thì sau khi xoá xong, object sẽ dùng thuộc tính từ prototype đó (nói cách khác, delete chỉ có tác dụng với những thuộc tính của riêng object).
  • Bất cứ thuộc tính nào được khởi tạo bằng var không thể bị xoá khỏi phạm vi toàn cục hoặc phạm vi hàm.
    • Vì thế, delete không thể xoá bất cứ hàm nào trong phạm vi toàn cục (cho dù là một phần của định nghĩa hàm hay biểu thức hàm).
    • Các hàm là một phần của object (tách biệt với phạm vi toàn cục) có thể bị xoá với delete.
  • Bất cứ thuộc tính nào được khởi tạo bởi let hoặc const không thể bị xoá khỏi phạm vi mà chúng được khai báo.
  • Thuộc tính không-thể-cấu-hình không thể bị loại bỏ. Các thuộc tính này bao gồm các object dựng sẵn như Math, Array, Object và thuộc tính được tạo ra như thuộc tính không-thể-cấu-hình bằng phương thức như là Object.defineProperty().

Snippet sau đưa ra ví dụ đơn giản:

var Employee = {
  age: 28,
  name: 'abc',
  designation: 'developer'
}

console.log(delete Employee.name);   // trả về true
console.log(delete Employee.age);    // trả về true

// Khi cố xoá một thuộc tính không tồn tại
// sẽ trả về giá trị true
console.log(delete Employee.salary); // trả về true

Thuộc tính không-thể-cấu-hình

Khi một thuộc tính được đánh dấu không-thể-cấu-hình, delete không có tác dụng nào, và sẽ trả về false. Trong chế độ strict, lỗi TypeError sẽ nhảy ra.

var Employee = {};
Object.defineProperty(Employee, 'name', {configurable: false});

console.log(delete Employee.name);  // trả về false

var, letconst tạo ra thuộc tính không-thể-cấu-hình mà không thể xoá bằng toán tử delete:

var nameOther = 'XYZ';

// Ta có thể truy cập vào thuộc tính toàn cục này thông qua:
Object.getOwnPropertyDescriptor(window, 'nameOther');  

// output: Object {value: "XYZ", 
//                  writable: true, 
//                  enumerable: true,
//                  configurable: false}

// Bởi vì "nameOther" được thêm vào nhờ dùng
// từ khoá var, nên nó được đánh dấu là "không-thể-cấu-hình"

delete nameOther;   // trả về false

Trong chế độ strict, ngoại lệ sẽ quăng ra.

Chế độ strict và non-strict

Khi ở trong chế độ strict, nếu delete được dùng để tham chiếu trực tiếp tới một biến, một đối số của hàm hoặc tên hàm, nó sẽ quăng ra SyntaxError.

Bất cứ biến nào được định nghĩa với var đều được đánh dấu là không-thể-cấu-hình. Trong ví dụ sau đây, salary là không-thể-cấu-hình và không thể xoá. Trong chế độ non-strict, phép toán delete sẽ trả về false.

function Employee() { 
  delete salary;
  var salary;
}

Employee();

Cùng xem mã nguồn tương tự hoạt động ra sao trong chế độ strict nhé. Thay vì trả về false, SyntaxError được quăng ra.

"use strict";

function Employee() {
  delete salary;  // SyntaxError
  var salary;        
}

// Tương tự, bất cứ truy nhập trực tiếp nào vào hàm
// dùng delete đều quăng ra SyntaxError

function DemoFunction() {
  //vài đoạn code
}

delete DemoFunction; // SyntaxError

Ví dụ

// Tạo thuộc tính adminName trên phạm vi toàn cục.
adminName = 'xyz';            

// Tạo thuộc tính empCount trên phạm vi toàn cục =.
// Vì dùng var, thuộc tính này được đánh dấu là không-thể-cấu-hình. 
// Điều tương tự xảy đến với let và const.
var empCount = 43;

EmployeeDetails = {
  name: 'xyz',
  age: 5,
  designation: 'Developer'
};

// adminName là thuộc tính trên phạm vi toàn cục.
// Nó có thể bị xoá bởi được khởi tạo mà không dùng var,
// và vì thế khả cấu.
delete adminName;       // trả về true

// Ngược lại, empCount không khả cấu
// bởi dùng var.
delete empCount;       // trả về false 

// Có thể dùng delete để loại bỏ thuộc tính khỏi object.
delete EmployeeDetails.name; // trả về true 

// Thậm chí thuộc tính không tồn tại, delete vẫn trả về "true".
delete EmployeeDetails.salary; // trả về true 

// delete không có tác dụng với thuộc tính dựng sẵn.
delete Math.PI; // trả về false 

// EmployeeDetails là thuộc tính trong phạm vi toàn cục.
// Vì được khởi tạo mà không dùng "var", nó được đánh dấu là khả cấu.
delete EmployeeDetails;   // trả về true

function f() {
  var z = 44;

  // delete không có tác dụng với tên biến cục bộ
  delete z;     // trả về false
}

delete và prototype chain

Trong ví dụ sau, ta sẽ xoá một thuộc tính riêng của object mà vẫn tồn tại thuộc tính cùng tên trong prototype chain:

function Foo() {
  this.bar = 10;
}

Foo.prototype.bar = 42;

var foo = new Foo();

// foo.bar liên kết với
// thuộc tính riêng. 
console.log(foo.bar); // 10 

// Xoá thuộc tính riêng trên
// foo object. 
delete foo.bar; // trả về true 

// foo.bar vẫn sẵn sàng trên
// prototype chain. 
console.log(foo.bar); // 42 

// Xoá thuộc tính trên prototype.
delete Foo.prototype.bar; // trả về true 

// Thuộc tính "bar" không còn có thể
// kể thừa từ Foo bởi nó đã bị xoá
console.log(foo.bar); // undefined

Xoá phần tử mảng

Khi bạn xoá phần tử mảng, độ dài mảng không bị ảnh hưởng. Thậm chí khi bạn xoá phần tử cuối của mảng cũng không thay đổi được điều này.

Khi toán tử delete loại bỏ một phần tử mảng, phần tử đó không còn trong mảng. Trong ví dụ sau, trees[3] bị xoá bởi delete.

var trees = ['redwood', 'bay', 'cedar', 'oak', 'maple'];
delete trees[3];
if (3 in trees) {
    // không thực thi đoạn code này
}

Nếu bạn muốn giữ lại phần tử mảng và gán giá trị undefined cho nó, hãy dùng undefined thay vì toán tử delete. Trong ví dụ sau, trees[3] được gán giá trị undefined, nhưng phần tử mảng vẫn tồn tại:

var trees = ['redwood', 'bay', 'cedar', 'oak', 'maple'];
trees[3] = undefined;
if (3 in trees) {
    // đoạn code trong này sẽ chạy
}

Thay vì thế, nếu muốn loại bỏ phần tử mảng bằng cách thay đổi nội dung của mảng, hãy dùng phương thức splice. Trong ví dụ sau, trees[3] bị xoá bỏ hoàn toàn khỏi mảng thông qua splice:

var trees = ['redwood', 'bay', 'cedar', 'oak', 'maple'];
trees.splice(3,1);
console.log(trees); // ["redwood", "bay", "cedar", "maple"]

Đặc Đặc tả

Specification Status Comment
ECMAScript Latest Draft (ECMA-262)
The definition of 'The delete Operator' in that specification.
Draft  
ECMAScript 2015 (6th Edition, ECMA-262)
The definition of 'The delete Operator' in that specification.
Standard  
ECMAScript 5.1 (ECMA-262)
The definition of 'The delete Operator' in that specification.
Standard  
ECMAScript 1st Edition (ECMA-262)
The definition of 'The delete Operator' in that specification.
Standard Định nghĩa lần đầu. Cài đặt trong JavaScript 1.2.

Trình duyệt hỗ trợ

Update compatibility data on GitHub
DesktopMobileServer
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewChrome for AndroidEdge MobileFirefox for AndroidOpera for AndroidSafari on iOSSamsung InternetNode.js
Basic supportChrome Full support YesEdge Full support YesFirefox Full support 1IE Full support YesOpera Full support YesSafari Full support YesWebView Android Full support YesChrome Android Full support YesEdge Mobile Full support YesFirefox Android Full support 4Opera Android Full support YesSafari iOS Full support YesSamsung Internet Android Full support Yesnodejs Full support Yes
Temporal dead zoneChrome ? Edge ? Firefox Full support 36IE ? Opera ? Safari ? WebView Android ? Chrome Android ? Edge Mobile ? Firefox Android Full support 36Opera Android ? Safari iOS ? Samsung Internet Android ? nodejs ?

Legend

Full support  
Full support
Compatibility unknown  
Compatibility unknown

Ghi chú Cross-browser

Although ECMAScript makes iteration order of objects implementation-dependent, it may appear that all major browsers support an iteration order based on the earliest added property coming first (at least for properties not on the prototype). However, in the case of Internet Explorer, when one uses delete on a property, some confusing behavior results, preventing other browsers from using simple objects like object literals as ordered associative arrays. In Explorer, while the property value is indeed set to undefined, if one later adds back a property with the same name, the property will be iterated in its old position--not at the end of the iteration sequence as one might expect after having deleted the property and then added it back.

If you want to use an ordered associative array in a cross-browser environment, use a Map object if available, or simulate this structure with two separate arrays (one for the keys and the other for the values), or build an array of single-property objects, etc.

Xem thêm

Document Tags and Contributors

Những người đóng góp cho trang này: PurpleLover
Cập nhật lần cuối bởi: PurpleLover,