2009-12-22 15 views
61

thể trùng lặp:
Deleting Objects in JavaScriptKhi nào tôi nên sử dụng các yếu tố xóa so với cài đặt thành null trong JavaScript?

Tôi có một đối tượng JS có một số lượng lớn tài sản. Nếu tôi muốn buộc trình duyệt thu thập rác đối tượng này, tôi có cần thiết lập từng thuộc tính này là null hoặc tôi có cần sử dụng toán tử delete không? Sự khác nhau giữa hai cái là gì?

+4

Xem http://stackoverflow.com/questions/742623/deleting-objects-in-javascript và http://stackoverflow.com/questions/1596782/how-to-unset-a -javascript-variable –

+0

@jeffreyveon: câu trả lời có thể được tìm thấy trong câu trả lời cho câu hỏi đầu tiên Crescent Fresh liên kết đến, nhưng tôi sẽ tóm tắt ở đây trước khi bạn đọc rằng: bạn không thể "ép buộc" trình duyệt thu gom rác ; 'delete' chỉ loại bỏ một thuộc tính khỏi một đối tượng (so với việc gán một thuộc tính giá trị null).Giả sử bạn không có tham chiếu bên ngoài đối tượng của bạn, nó sẽ được thu thập rác * bất kể * có hay không bạn trống hoặc xóa các thuộc tính trước. – Shog9

Trả lời

134

Không có cách nào để bắt buộc thu thập rác trong JavaScript và bạn không thực sự cần. x.y = null;delete x.y; cả hai loại bỏ x tham chiếu đến giá trị cũ của y. Giá trị sẽ được thu gom rác khi cần thiết.

Nếu bạn vô hiệu hóa thuộc tính, nó vẫn được coi là 'đặt' trên đối tượng và sẽ được liệt kê. Thời gian duy nhất tôi có thể nghĩ đến nơi bạn thích delete là nếu bạn định liệt kê các thuộc tính của x.

xem xét như sau:

var foo = { 'a': 1, 'b': 2, 'c': 3 }; 

console.log('Deleted a.'); 
delete foo.a 
for (var key in foo) 
    console.log(key + ': ' + foo[key]); 

console.log('Nulled out b.'); 
foo['b'] = null; 
for (var key in foo) 
    console.log(key + ': ' + foo[key]); 

Mã này sẽ cho kết quả sau:

Deleted a. 
b: 2 
c: 3 
Nulled out b. 
b: null 
c: 3 
+12

Câu trả lời hay. 1 để 'null'ify downvote khó hiểu. – undefined

+0

JavaScript là một ngôn ngữ đặc biệt. Một điều tôi thấy lạ là làm thế nào biến trong vòng lặp không đi ra khỏi phạm vi sau khi vòng lặp. Trong mã của bạn, bạn không cần phải xác định lại "khóa", bởi vì "khóa" đã được xác định. Rất lạ tôi nói với bạn. Thật bực bội khi có toàn quyền kiểm soát. Tôi thực sự chưa bao giờ nghe nói về từ khóa xóa này trước đây. Tôi luôn luôn vô hiệu hóa các biến vì lý do mà tôi có thể đã vô tình xác định nó ở một nơi khác và tôi không biết những gì các phân tích cú pháp (hoặc một người dùng bằng cách sử dụng IE!). Cảm ơn bạn đã chia sẻ kiến ​​thức của mình. – pqsk

+0

@pqsk Những gì bạn đang đề cập đến cho vòng lặp là một ví dụ của cẩu nâng. Nó thực sự khá mát mẻ một khi bạn quấn đầu của bạn xung quanh nó! http://jsfiddle.net/a4awzxd7/1/ – catalyst294

1

Không có cách nào để buộc thu thập rác tại một thời điểm cụ thể trong JavaScript. Mỗi công cụ JavaScript có cách xử lý riêng của nó.

Điều bạn có thể làm là đảm bảo các đối tượng của bạn không được tham chiếu ở bất kỳ đâu. Đặt chúng thành null hoặc xóa chúng thực sự làm điều tương tự (xóa không bao giờ xóa đối tượng - nó chỉ loại bỏ một tham chiếu đến nó). Khi bộ sưu tập rác chạy, nó sẽ kiểm tra xem có bất kỳ tham chiếu nào đến một đối tượng cụ thể không, nếu không, nó sẽ loại bỏ nó khỏi bộ nhớ. Đây là nơi rò rỉ bộ nhớ xảy ra (một đối tượng JavaScript đang tham chiếu một đối tượng DOM và ngược lại).

Đảm bảo bạn xóa tất cả các tham chiếu và bạn sẽ ổn.

+0

"Mỗi công cụ JavaScript có cách xử lý riêng" - Không hoàn toàn chính xác, theo điều này, tất cả các trình duyệt hiện đại đều sử dụng biến thể thuật toán "Đánh dấu và quét" kể từ năm 2012: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management – NoBugs

+0

@NoBugs Tôi nghĩ đó là ý của anh ấy. "cách xử lý riêng của họ" === "một biến thể của" ... – dudewad

12

Javascript đối tượng thuộc tính thường được thực hiện với một Hashtable. Thiết lập để null để lại chìa khóa trong hashtable trỏ đến một giá trị null, trong khi xóa loại bỏ cả khóa và giá trị.

Sự khác biệt quan sát chính giữa hai là nếu bạn lặp qua các khóa bằng vòng lặp for..in, việc xóa các khóa sẽ dẫn đến ít mục hơn được lặp lại.

Tôi muốn đề nghị xóa nói chung, trừ khi bạn sẽ được lặp lại thiết lập và thanh toán bù trừ cùng một khóa, điều này sẽ cho phép để lại cấu trúc bảng băm tại chỗ. Tuy nhiên, bất kỳ sự khác biệt về hiệu năng nào giữa hai kỹ thuật sẽ là vô cùng nhỏ trong bất kỳ trường hợp điển hình nào.

-m @

+0

Độ rõ nét tuyệt vời, cảm ơn – Undefined

Các vấn đề liên quan