it-swarm-vi.com

Làm cách nào để xóa thuộc tính khỏi đối tượng JavaScript?

Nói rằng tôi tạo một đối tượng như sau:

var myObject = {
    "ircEvent": "PRIVMSG",
    "method": "newURI",
    "regex": "^http://.*"
};

Cách tốt nhất để xóa tài sản regex để kết thúc với myObject mới như sau là gì?

var myObject = {
    "ircEvent": "PRIVMSG",
    "method": "newURI"
};
5509
johnstok

Như thế này:

delete myObject.regex;
// or,
delete myObject['regex'];
// or,
var prop = "regex";
delete myObject[prop];

Bản giới thiệu

var myObject = {
    "ircEvent": "PRIVMSG",
    "method": "newURI",
    "regex": "^http://.*"
};
delete myObject.regex;

console.log(myObject);

Đối với bất kỳ ai muốn đọc thêm về nó, người dùng Stack Overflow kangax đã viết một bài đăng blog cực kỳ sâu sắc về câu lệnh delete trên blog của họ,Hiểu xóa. Nó rất được khuyến khích.

7568
nickf

Toán tử delete chậm một cách bất ngờ!

Nhìn vàođiểm chuẩn.

Xóa là cách thực sự duy nhất để xóa các thuộc tính của đối tượng mà không có bất kỳ phần thừa nào, nhưng nó hoạt động ~ chậm hơn 100 lần , so với "thay thế" của nó, đặt object[key] = undefined.

Sự thay thế này không phải là câu trả lời chính xác cho câu hỏi này! Nhưng, nếu bạn sử dụng nó một cách cẩn thận, bạn có thể tăng tốc đáng kể một số thuật toán. Nếu bạn đang sử dụng delete trong các vòng lặp và bạn gặp vấn đề với hiệu suất, hãy đọc phần giải thích dài dòng.

Khi nào nên sử dụng delete và khi nào đặt giá trị thành undefined?

Một đối tượng có thể được xem như một tập hợp các cặp khóa-giá trị. Cái mà tôi gọi là 'giá trị' là nguyên thủy hoặc tham chiếu đến đối tượng khác, được kết nối với 'khóa' đó.

Sử dụng delete, khi bạn chuyển đối tượng kết quả đến mã mà bạn không có quyền kiểm soát (hoặc khi bạn không chắc chắn về nhóm của mình hoặc chính mình).

xóa khóa khỏi hashmap .

 var obj = {
     field: 1     
 };
 delete obj.field;

Sử dụng cài đặt thành undefined, khi bạn quan tâm đến hiệu suất. Nó có thể cung cấp một sự gia tăng nghiêm trọng cho mã của bạn.

Khóa vẫn ở vị trí của nó trong hàm băm , chỉ giá trị được thay thế bằng undefined. Hãy hiểu, vòng lặp for..in đó sẽ vẫn lặp trên khóa đó.

 var obj = {
     field: 1     
 };
 obj.field = undefined;

Sử dụng phương pháp này, không phải tất cả cách xác định sự tồn tại của tài sản sẽ hoạt động như mong đợi.

Tuy nhiên, mã này:

object.field === undefined

sẽ hành xử tương đương cho cả hai phương pháp.

Xét nghiệm

Tóm lại, sự khác biệt là tất cả về các cách xác định sự tồn tại của thuộc tính và về vòng lặp for..in.

 console.log('* -> "Takes prototype inheritance into consideration, that means it lookups all over prototype chain too."');

 console.log(obj.field === undefined, 'obj.field === undefined', 'You get "undefined" value when querying for "field" in object-hashmap. *');

 console.log(obj["field"] === undefined, 'obj["field"] === undefined', 'Just another way to query (equivalent). *');

 console.log(typeof obj.field === "undefined", 'typeof obj.field === "undefined"', 'Get the value attached to "field" key, and check it\'s type is "undefined". *');

 console.log("field" in obj, '"field" in obj', 'This statement returns true if "field" key exists in the hashmap. False otherwise. *');

 console.log(obj.hasOwnProperty("field"), 'obj.hasOwnProperty("field")', 'This statement returns true if \'field\' key exists in the hashmap. The ONLY way NOT to lookup for property in the prototype chain!');
 //Object.keys().indexOf() is an overkill that runs much slower :)

 var counter = 0,
     key;
 for (key in obj) {
     counter++;
 }
 console.assert(counter === 0, 'counter === 0', '"field" is not iterated using "for .. in" loop. *');

Cẩn thận với rò rỉ bộ nhớ!

Mặc dù sử dụng obj[prop] = undefined nhanh hơn so với thực hiện delete obj[prop], một cân nhắc quan trọng khác là obj[prop] = undefined có thể không phải lúc nào cũng phù hợp. delete obj[prop] xóa prop khỏi obj và xóa nó khỏi bộ nhớ trong khi obj[prop] = undefined chỉ đơn giản đặt giá trị của prop thành undefined để lại prop trong bộ nhớ. Do đó, trong trường hợp có nhiều khóa được tạo và xóa, sử dụng obj[prop] = undefined có thể buộc đối chiếu bộ nhớ đắt tiền (khiến trang bị đóng băng) và có khả năng xảy ra lỗi hết bộ nhớ. Kiểm tra mã sau đây.

"use strict";
var theNodeList=[], i, current, numberOfNodes=65536, body=document.body, nodeRecords=[];
for (i = 0; i !== numberOfNodes; i++) {
    nodeRecords[i] = [];
    current = theNodeList[i] = document.createElement("div");
    current.textContent = i;
    document.body.appendChild( current );
}
var lastTime = -1;
requestAnimationFrame(function recordUpdates(){
    var currentTime = Math.round( performance.now()*1000 )
    for (i = 0; i !== numberOfNodes; i++) {
        if (lastTime !== -1) {
            // the previously collected data is no longer in use
            /*************************************************/
            /****/ nodeRecords[i][lastTime] = undefined; /****/
            /*************************************************/
        }
        nodeRecords[i][currentTime] = theNodeList[i].outerHTML;
    }
    lastTime = currentTime;
    requestAnimationFrame( recordUpdates );
});

Trong đoạn mã trên, chỉ cần thực hiện nodeRecords[i][lastTime] = undefined; sẽ gây rò rỉ bộ nhớ lớn vì mỗi khung hình động. Mỗi khung, tất cả 65536 phần tử DOM sẽ chiếm thêm 65536 vị trí riêng lẻ, nhưng các vị trí 65536 trước đó sẽ chỉ được đặt thành không xác định khiến chúng bị treo trong bộ nhớ. Hãy tiếp tục, thử chạy mã trên trong bảng điều khiển và tự mình xem. Sau khi buộc lỗi hết bộ nhớ, hãy thử chạy lại ngoại trừ phiên bản mã sau sử dụng toán tử delete thay thế.

"use strict";
var theNodeList=[], i, current, numberOfNodes=65536, body=document.body, nodeRecords=[];
for (i = 0; i !== numberOfNodes; i++) {
    nodeRecords[i] = [];
    current = theNodeList[i] = document.createElement("div");
    current.textContent = i;
    document.body.appendChild( current );
}
var lastTime = -1;
requestAnimationFrame(function recordUpdates(){
    var currentTime = Math.round( performance.now()*1000 )
    for (i = 0; i !== numberOfNodes; i++) {
        if (lastTime !== -1) {
            // the previously collected data is no longer in use
            /********************************************/
            /****/ delete nodeRecords[i][lastTime]; /****/
            /********************************************/
        }
        nodeRecords[i][currentTime] = theNodeList[i].outerHTML;
    }
    lastTime = currentTime;
    requestAnimationFrame( recordUpdates );
});

Như đã thấy trong đoạn mã trên, có một số trường hợp sử dụng thích hợp hiếm gặp cho toán tử delete. Tuy nhiên, đừng lo lắng về vấn đề này quá nhiều. Điều này sẽ chỉ trở thành một vấn đề với các đối tượng có tuổi thọ cao mà nhận được các khóa mới liên tục được thêm vào chúng. Trong mọi trường hợp khác (gần như mọi trường hợp trong lập trình trong thế giới thực), cách thích hợp nhất là sử dụng obj[prop] = undefined. Mục đích chính của phần này là để làm cho bạn chú ý để trong trường hợp hiếm khi điều này trở thành vấn đề trong mã của bạn, thì bạn có thể dễ dàng hiểu vấn đề hơn và do đó không phải lãng phí hàng giờ để phân tích mã của mình để xác định vị trí và hiểu vấn đề này.

Không phải lúc nào cũng được đặt thành undefined

Một khía cạnh của Javascript quan trọng cần xem xét là tính đa hình. Đa hình là khi gán các loại khác nhau của biến/slot-in-an-object khác nhau như được thấy dưới đây.

var foo = "str";
foo = 100;          // variable foo is now labeled polymorphic by the browser
var bar = ["Some", "example"];
bar[2] = "text";    // bar is a monomorphic array here because all its entries have the
                    // same type: string primitive
bar[1] = undefined; // bar is now a polymorphic array

Tuy nhiên, có hai vấn đề không thể giải quyết chính với mảng đa hình:

  1. Chúng chậm và bộ nhớ không hiệu quả. Khi truy cập một chỉ mục cụ thể, thay vì chỉ lấy loại toàn cầu cho mảng, trình duyệt thay vào đó phải lấy loại trên cơ sở mỗi chỉ mục, theo đó mỗi chỉ mục lưu trữ siêu dữ liệu bổ sung của loại.
  2. Một khi đa hình, luôn luôn đa hình. Khi một mảng được tạo thành đa hình, tính đa hình không thể được hoàn tác trong các trình duyệt Webkit. Vì vậy, ngay cả khi bạn khôi phục một mảng đa hình thành không đa hình, nó vẫn sẽ được trình duyệt lưu trữ dưới dạng một mảng đa hình.

Người ta có thể ví sự đa hình với nghiện ma túy. Thoạt nhìn, nó có vẻ rất sinh lợi: Mã đẹp khá đẹp. Sau đó, lập trình viên giới thiệu mảng của họ với thuốc đa hình. Ngay lập tức, mảng đa hình trở nên kém hiệu quả hơn và nó không bao giờ có thể trở nên hiệu quả như trước đây kể từ khi nó bị đánh thuốc mê. Để tương quan hoàn cảnh như vậy với cuộc sống thực, một người nào đó sử dụng cocaine thậm chí có thể không có khả năng vận hành một tay nắm cửa đơn giản, ít có khả năng tính toán các chữ số PI. Tương tự như vậy, một mảng trên thuốc đa hình không bao giờ có thể hiệu quả như một mảng đơn hình.

Nhưng, sự tương tự của chuyến đi ma túy liên quan đến hoạt động delete như thế nào? Câu trả lời kế thừa dòng mã cuối cùng trong đoạn trích trên. Vì vậy, hãy để nó được xem xét lại, lần này với một twist.

var bar = ["Some", "example"];
bar[2] = "text";    // bar is not a polymorphic array here because all its entries have the
                    // same type: string primitive
bar[1] = "";        // bar is still a monomorphic array
bar[1] = undefined; // bar is now a polymorphic array

Quan sát. bar[1] = "" không ép buộc đa hình trong khi bar[1] = undefined thì không. Do đó, người ta phải luôn luôn sử dụng loại tương ứng cho các đối tượng của mình để không vô tình gây ra đa hình. Một người như vậy có thể sử dụng danh sách sau đây làm tài liệu tham khảo chung để đưa họ đi. Tuy nhiên, xin vui lòng không sử dụng rõ ràng các ý tưởng dưới đây. Thay vào đó, sử dụng bất cứ điều gì hoạt động tốt cho mã của bạn.

  • Khi sử dụng một mảng/biến được nhập vào nguyên hàm boolean, hãy sử dụng false hoặc undefined làm giá trị trống. Mặc dù tránh đa hình không cần thiết là tốt, nhưng viết lại tất cả mã của bạn để cấm rõ ràng nó sẽ có khả năng thực sự dẫn đến giảm hiệu suất. Sử dụng phán đoán chung!
  • Khi sử dụng một mảng/biến được nhập vào số nguyên thủy, hãy sử dụng 0 làm giá trị trống. Lưu ý rằng trong nội bộ, có hai loại số: số nguyên nhanh (bao gồm 2147483647 đến -2147483648) và nhân đôi dấu phẩy động chậm (bất cứ thứ gì khác ngoài số đó bao gồm NaNInfinity). Khi một số nguyên được hạ cấp thành một số kép, nó không thể được thăng cấp trở lại thành một số nguyên.
  • Khi sử dụng một mảng/biến được nhập vào chuỗi nguyên thủy, hãy sử dụng "" làm giá trị trống.
  • Khi sử dụng Biểu tượng, hãy đợi, tại sao bạn lại sử dụng Biểu tượng?!?! Biểu tượng là juju xấu cho hiệu suất. Mọi thứ được lập trình để sử dụng Biểu tượng đều có thể được lập trình lại để không sử dụng Biểu tượng, dẫn đến mã nhanh hơn mà không có Biểu tượng. Biểu tượng thực sự chỉ là siêu đường không hiệu quả.
  • Khi sử dụng bất cứ thứ gì khác, hãy sử dụng null.

Tuy nhiên, hãy chú ý! Đừng đột nhiên bắt đầu làm điều này với tất cả các mã có sẵn của bạn ngay bây giờ vì nó có thể sẽ phá vỡ mã có sẵn như vậy và/hoặc giới thiệu các lỗi lạ. Thay vào đó, một cách thực hành hiệu quả như vậy cần được triển khai ngay từ đầu và khi chuyển đổi mã có sẵn, bạn nên kiểm tra gấp đôi, gấp ba, gấp bốn lần tất cả các dòng liên quan đến việc cố gắng nâng cấp mã cũ thành thực tiễn mới này có thể như rủi ro như nó là bổ ích.

812
Dan
var myObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};
    
delete myObject.regex;

console.log ( myObject.regex); // logs: undefined

Điều này hoạt động trong Firefox và Internet Explorer và tôi nghĩ rằng nó hoạt động trong tất cả những người khác.

221
redsquare

Cập nhật 2018-07-21: Trong một thời gian dài, tôi cảm thấy xấu hổ về câu trả lời này, vì vậy tôi nghĩ rằng đã đến lúc tôi chạm vào nó một chút. Chỉ cần một chút bình luận, làm rõ và định dạng để giúp đẩy nhanh việc đọc các phần dài và không cần thiết của câu trả lời này.


PHIÊN BẢN NGẮN

Câu trả lời thực tế cho câu hỏi

Như những người khác đã nói, bạn có thể sử dụng deletename__.

obj // {"foo": "bar"}
delete obj["foo"]
obj // {}
obj["foo"] // undefined

Mảng tương đương

Đừng deletetừ một mảng. Sử dụng Array.prototype.splice thay thế.

arr // [1,2,3,4,5]
arr.splice(3,1); // 4
arr // [1,2,3,5]

PHIÊN BẢN DÀI

JavaScript là một ngôn ngữ OOP, vì vậy mọi thứ đều là một đối tượng, bao gồm mảng. Vì vậy, tôi cảm thấy cần phải chỉ ra một cảnh báo cụ thể.

Trong các mảng, không giống như các đối tượng cũ đơn giản, sử dụng deleteđể lại rác dưới dạng nullname__, tạo ra một "lỗ hổng" trong mảng.

var array = [1, 2, 3, 4];
delete array[2];
/* Expected result --> [1, 2, 4]
 * Actual result   --> [1, 2, null, 4]
 */

Như bạn có thể thấy, deletekhông luôn hoạt động như người ta mong đợi. Giá trị được ghi đè, nhưng bộ nhớ không được phân bổ lại. Điều đó có nghĩa là, array[4] không được chuyển đến array[3]. Tương phản với Array.prototype.unshift, phần tử chèn một phần tử ở đầu mảng và dịch chuyển mọi thứ lên (array[0] trở thành array[1], v.v.)

Thành thật mà nói, ngoài việc đặt thành nullchứ không phải undefinedname __-- điều này thật kỳ lạ - hành vi này không nên đáng ngạc nhiên, vì deletelà một toán tử đơn phương, như typeofname và không cần phải quan tâm đến loại của đối tượng mà nó đang được sử dụng, trong khi Arraylà một lớp con của Objectvới các phương thức được thiết kế riêng cho làm việc với các mảng. Vì vậy, không có lý do chính đáng nào để deletecó một trường hợp đặc biệt được xử lý để dịch chuyển lại mảng, vì điều đó sẽ làm mọi thứ chậm lại với những công việc không cần thiết. Nhìn lại, kỳ vọng của tôi là không thực tế.

Tất nhiên, nó đã làm tôi ngạc nhiên. Bởi vì tôi đã viết điều này để biện minh cho cuộc thập tự chinh của tôi chống lại "rác null":

Bỏ qua những nguy hiểm và vấn đề cố hữu trong nullvà không gian bị lãng phí, điều này có thể gây ra vấn đề nếu mảng cần phải chính xác.

Đó là một lời biện minh khủng khiếp cho việc loại bỏ nullname__s --nullchỉ nguy hiểm nếu được sử dụng không đúng cách và không liên quan gì đến "độ chính xác". Lý do thực sự bạn không nên deletetừ một mảng là việc để các cấu trúc dữ liệu đầy rác và lộn xộn xung quanh là cẩu thả và dễ bị lỗi.

Điều tiếp theo là một kịch bản có thể xảy ra khá dài, vì vậy bạn có thể bỏ qua phần này, Giải pháp , nếu bạn muốn. Lý do duy nhất khiến tôi rời khỏi phần này là vì tôi nghĩ rằng một số người có thể nghĩ nó thật buồn cười và tôi không muốn trở thành "anh chàng" đó đăng câu trả lời "hài hước" và sau đó xóa tất cả "buồn cười" khỏi nó sau này .

... Thật là ngu ngốc, tôi biết.

Kịch bản PDP-11 đầy tranh cãi và dài dòng

Ví dụ: giả sử bạn đang tạo một ứng dụng web sử dụng tuần tự hóa JSON để lưu trữ một mảng được sử dụng cho 'tab' trong một chuỗi (trong trường hợp này là localStoragename__). Chúng ta cũng nói rằng mã sử dụng các chỉ số bằng số của các thành viên của mảng để "đặt tên" cho chúng khi vẽ lên màn hình. Tại sao bạn làm điều này thay vì chỉ lưu trữ "tiêu đề" là tốt? Bởi vì ... lý do.

Được rồi, hãy giả sử rằng bạn đang cố lưu bộ nhớ theo yêu cầu của người dùng một này chạy máy tính mini PDP-11 từ UNIX chạy năm 1960 và đã viết dựa trên Elinks, dựa trên JavaScript của riêng mình, trình duyệt thân thiện với máy in dòng vì X11 là ngoài câu hỏi.

Kịch bản trường hợp cạnh ngày càng ngu ngốc sang một bên, sử dụng deletetrên mảng đã nói sẽ dẫn đến nulllàm ô nhiễm mảng và có thể gây ra lỗi trong ứng dụng sau này. Và nếu bạn kiểm tra nullname__, nó sẽ bỏ qua các con số dẫn đến các tab được hiển thị như [1] [2] [4] [5] ....

if (array[index] == null)
    continue;
else
    title = (index + 1).toString();
/* 0 -> "1"
 * 1 -> "2"
 * 2 -> (nothing)
 * 3 -> "4"
 */

Vâng, đó chắc chắn không phải là những gì bạn muốn.

Bây giờ, bạn có thể giữ một trình lặp thứ hai, như jname__, chỉ tăng khi giá trị hợp lệ được đọc từ mảng. Nhưng điều đó sẽ không giải quyết chính xác vấn đề nullvà bạn vẫn phải làm hài lòng điều đó chơi khăm Người dùng PDP-11. Than ôi, máy tính của anh ta chỉ không có đủ bộ nhớ để giữ số nguyên cuối cùng đó (đừng hỏi làm thế nào anh ta quản lý để xử lý một mảng có chiều rộng thay đổi ...).

Vì vậy, anh ấy gửi cho bạn một email trong sự tức giận:

Hey, your webapp broke my browser! I checked my localStorage database after your stupid code made my browser segfault, and this is what I found:

>"tabs:['Hello World', 'foo bar baz', null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, ... ]"

After clearing my precious data, it segfaulted again, and I did a backtrace, and what do I find? WHAT DO I FIND!? YOU USE TOO MANY VARIABLES!

>var i = index;
>var j = 1;

Grr, I am angry now.
-Troll Davidson

Bây giờ, bạn đang ở cuối trí thông minh của bạn. Anh chàng này đã phàn nàn không ngừng về ứng dụng của bạn, và bạn muốn bảo anh ta im lặng và đi lấy một chiếc máy tính tốt hơn.

Giải pháp: Array.prototype.splice

May mắn thay, mảng do có một phương pháp chuyên dụng để xóa các chỉ mục và phân bổ lại bộ nhớ: Array.prototype.splice(). Bạn có thể viết một cái gì đó như thế này:

Array.prototype.remove = function(index){
  this.splice(index,1);
}
...
array = [1, 2, 3, 4];
array.remove(2);
// Result -> [1, 2, 4]

Và cứ như thế, bạn hài lòng ông PDP-11. Hoan hô! (Tôi vẫn sẽ nói với anh ấy, mặc dù ...)

Array.prototype.splice vs Array.prototype.slice

Tôi cảm thấy điều quan trọng là chỉ ra sự khác biệt giữa hai chức năng có cùng tên này, vì cả hai đều rất hữu ích.

Array.prototype.splice (bắt đầu, n)

.splice() làm thay đổi mảng và trả về các chỉ mục đã xóa. Mảng được cắt bắt đầu từ chỉ mục, các phần tử startnđược cắt ra. Nếu n không được chỉ định, toàn bộ mảng sau startsẽ bị cắt ra (n = array.length - start).

let a = [5,4,3,2,1];
let chunk = a.splice(2,2);

// a     [5,4,3,2,1]
// start  0 1 2 - -
// n      - - 1 2 -

chunk; // [3,2]
a;     // [5,4,1]

Array.prototype.slice (bắt đầu, kết thúc)

.slice() không phá hủy và trả về một mảng mới chứa các chỉ số được chỉ định từ startđến endname__. Nếu endkhông được chỉ định, hành vi sẽ giống như .splice() (end = array.length). Hành vi này hơi phức tạp vì, vì một số lý do, endlập chỉ mục từ 1 thay vì 0. Tôi không biết tại sao nó lại làm như vậy, nhưng đó là như thế. Ngoài ra, nếu end <= start, kết quả là một mảng trống.

let a = [5,4,3,2,1];
let chunks = [
    a.slice(2,0),
    a.slice(2,2),
    a.slice(2,3),
    a.slice(2,5) ];

// a             [5,4,3,2,1]
// start          0 1 2 - -
// end, for...    - - - - -
//   chunks[0]  0 - - - - -   
//   chunks[1]    1 2 - - -
//   chunks[2]    1 2 3 - -
//   chunks[3]    1 2 3 4 5

chunks; // [ [], [], [3], [3,2,1] ]
a;      // [5,4,3,2,1]

Đó thực sự không phải là những gì đang xảy ra, nhưng nó dễ dàng hơn để nghĩ theo cách đó. Theo MDN, đây là những gì thực sự xảy ra:

// a             [5,4,3,2,1]
// start          0 1 2 - - -
// end, for...    - - - - - -
//   chunks[0]    0 - - - - -
//   chunks[1]    0 1 2 - - -
//   chunks[2]    0 1(2)3 - -
//   chunks[3]    0 1(2 3 4)5

Chỉ mục được chỉ định bởi endđơn giản được loại trừ khỏi lát cắt. Các chỉ số được ngoặc đơn cho biết những gì được cắt lát. Dù bằng cách nào, hành vi đó không trực quan và bị ràng buộc gây ra lỗi chia sẻ công bằng của nó, vì vậy bạn có thể thấy hữu ích khi thực hiện chức năng trình bao bọc để mô phỏng chặt chẽ hơn hành vi của .splice():

function ez_slice(array, start = 0, n = null){
    if(!Array.isArray(array) || !is_number(start))
        return null;

    if(is_number(n))
        return array.slice(start, start + n);

    if(n === null)
        return array.slice(start);

    return null;
}

ez_slice([5,4,3,2,1], 2, 1) // [3]
ez_slice([5,4,3,2,1], 2)    // [3,2,1]

/* Fun fact: isNaN is unreliable.
 * [NaN, [], {}, 0, 1, Infinity, undefined, null, "Hi"].filter(isNaN)
 * [NaN, {}, undefined, "Hi"]
 *
 * What we want is...
 *
 * [NaN, [], {}, 0, 1, Infinity, undefined, null, "Hi"].filter(is_nan)
 * [NaN]
 */
function is_nan(num){
    return typeof num === "number"
        && num !== num;
}

function is_number(num){
    return !is_nan(num)
        && typeof num === "number"
        && isFinite(num);
}

Lưu ý rằng chức năng trình bao bọc được thiết kế rất nghiêm ngặt về các loại và sẽ trả về nullnếu có bất cứ điều gì tắt. Điều đó bao gồm việc đặt một chuỗi như "3". Nó được để lại cho các lập trình viên siêng năng về các loại của mình. Điều này là để khuyến khích thực hành lập trình tốt.

Cập nhật về is_array()

Điều này liên quan đến đoạn trích này (hiện đã bị xóa):

function is_array(array){
    return array !== null
        && typeof array === "object"
        && typeof array.length !== "undefined"
        && array.__proto__ === Array.prototype;
}

Vì vậy, khi nó bật ra, thực sự có IS một cách tích hợp để biết liệu một mảng có thực sự là một mảng hay không, và đó là Array.isArray(), được giới thiệu trong ECMAScript 5 (tháng 12 năm 2009). Tôi đã tìm thấy điều này trong khi tìm kiếm xem có câu hỏi nào về việc nói mảng từ các đối tượng hay không, để xem liệu có giải pháp nào tốt hơn của tôi không, hoặc thêm tôi nếu không có câu hỏi nào. Vì vậy, nếu bạn đang sử dụng phiên bản JavaScript sớm hơn ECMA 5, thì đó là polyfill của bạn. Tuy nhiên, tôi thực sự khuyên bạn không nên sử dụng chức năng is_array() của mình, vì tiếp tục hỗ trợ các phiên bản JavaScript cũ có nghĩa là tiếp tục hỗ trợ các trình duyệt cũ triển khai chúng, điều đó có nghĩa là khuyến khích sử dụng phần mềm không an toàn và khiến người dùng gặp rủi ro với phần mềm độc hại. Vì vậy, xin vui lòng, sử dụng Array.isArray(). Sử dụng letconstname__. Sử dụng các tính năng mới được thêm vào ngôn ngữ. Đừng sử dụng tiền tố của nhà cung cấp. Xóa that IE polyfill crap từ trang web của bạn. Xóa XHTML <!CDATA[[... cũng vậy - chúng tôi đã chuyển sang HTML5 vào năm 2014. Mọi người càng sớm rút hỗ trợ cho các trình duyệt cũ/bí truyền đó, các nhà cung cấp trình duyệt sẽ thực sự tuân theo tiêu chuẩn web và càng sớm nắm bắt công nghệ mới có thể chuyển sang một trang web an toàn hơn.

173
Braden Best

Câu hỏi cũ, câu trả lời hiện đại. Sử dụng tính năng hủy đối tượng, một tính năng ECMAScript 6 , nó đơn giản như:

const { a, ...rest } = { a: 1, b: 2, c: 3 };

Hoặc với mẫu câu hỏi:

const myObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};
const { regex, ...newObject } = myObject;
console.log(newObject);

Bạn có thể thấy nó hoạt động trong trình chỉnh sửa dùng thử Babel.


Chỉnh sửa:

Để gán lại cho cùng một biến, hãy sử dụng let:

let myObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};
({ regex, ...myObject } = myObject);
console.log(myObject);
143
Koen.

Một cách khác là sử dụng thư viện Underscore.js .

Lưu ý rằng cả _.pick()_.omit() đều trả về một bản sao của đối tượng và không trực tiếp sửa đổi đối tượng ban đầu. Gán kết quả cho đối tượng ban đầu nên thực hiện thủ thuật (không hiển thị).

Tham khảo: liên kết _.pick (đối tượng, * phím)

Trả về một bản sao của đối tượng, được lọc để chỉ có các giá trị cho các khóa được liệt kê trong danh sách trắng (hoặc mảng các khóa hợp lệ).

var myJSONObject = 
{"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};

_.pick(myJSONObject, "ircEvent", "method");
=> {"ircEvent": "PRIVMSG", "method": "newURI"};

Tham khảo: liên kết _.omit (đối tượng, * phím)

Trả về một bản sao của đối tượng, được lọc để bỏ qua các phím được liệt kê trong danh sách đen (hoặc mảng các phím).

var myJSONObject = 
{"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};

_.omit(myJSONObject, "regex");
=> {"ircEvent": "PRIVMSG", "method": "newURI"};

Đối với mảng, _.filter()_.reject() có thể được sử dụng theo cách tương tự.

87
Thaddeus Albers

Cú pháp lây lan (ES6)

Cho bất cứ ai cần nó ...

Để hoàn thành câu trả lời @Koen trong chuỗi này, trong trường hợp bạn muốn xóa biến động bằng cú pháp trải rộng, bạn có thể làm như vậy:

const key = 'a';

const { [key]: foo, ...rest } = { a: 1, b: 2, c: 3 };

console.log(rest); // { b: 2, c: 3 }

* foo sẽ là một biến mới có giá trị a (là 1).


[.__.]CẬP NHẬT:
[.__.] Có một số cách phổ biến để xóa thuộc tính khỏi đối tượng.
[.__.] Mỗi người đều có ưu và nhược điểm riêng ( kiểm tra so sánh hiệu suất này ):

Xóa toán tử
[.__.] Tuy nhiên, có thể đọc và ngắn, nó có thể không phải là lựa chọn tốt nhất nếu bạn đang hoạt động trên một số lượng lớn đối tượng vì hiệu suất của nó không được tối ưu hóa.

delete obj[key];


[.__.] Tái chỉ định
[.___.] Nhanh hơn 2 lần so với delete, tuy nhiên thuộc tính là không đã bị xóa và có thể được lặp lại.

obj[key] = null;
obj[key] = false;
obj[key] = undefined;


[.__.] Toán tử trải rộng
[.__.] Toán tử ES6 này cho phép chúng ta trả về một đối tượng hoàn toàn mới, không bao gồm bất kỳ thuộc tính nào, mà không làm thay đổi đối tượng hiện có. Nhược điểm là nó có hiệu suất kém hơn ở trên và không được đề xuất sử dụng khi bạn cần loại bỏ nhiều thuộc tính cùng một lúc.

{ [key]: val, ...rest } = obj;
53
Lior Elrom

Thuật ngữ bạn đã sử dụng trong tiêu đề câu hỏi của bạn Remove a property from a JavaScript object, có thể được hiểu theo một số cách khác nhau. Một là loại bỏ nó cho toàn bộ bộ nhớ và danh sách các khóa đối tượng hoặc cái còn lại chỉ là xóa nó khỏi đối tượng của bạn. Như đã được đề cập trong một số câu trả lời khác, từ khóa delete là phần chính. Giả sử bạn có đối tượng của mình như:

myJSONObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};

Nếu bạn làm:

console.log(Object.keys(myJSONObject));

kết quả sẽ là:

["ircEvent", "method", "regex"]

Bạn có thể xóa khóa cụ thể đó khỏi các khóa đối tượng của mình như:

delete myJSONObject["regex"];

Sau đó, khóa đối tượng của bạn bằng cách sử dụng Object.keys(myJSONObject) sẽ là:

["ircEvent", "method"]

Nhưng vấn đề là nếu bạn quan tâm đến bộ nhớ và bạn muốn xóa toàn bộ đối tượng khỏi bộ nhớ, bạn nên đặt nó thành null trước khi xóa khóa:

myJSONObject["regex"] = null;
delete myJSONObject["regex"];

Điểm quan trọng khác ở đây là cẩn thận về các tham chiếu khác của bạn đến cùng một đối tượng. Chẳng hạn, nếu bạn tạo một biến như:

var regex = myJSONObject["regex"];

Hoặc thêm nó dưới dạng một con trỏ mới vào một đối tượng khác như:

var myOtherObject = {};
myOtherObject["regex"] = myJSONObject["regex"];

Sau đó, ngay cả khi bạn xóa nó khỏi đối tượng myJSONObject, đối tượng cụ thể đó sẽ không bị xóa khỏi bộ nhớ, vì biến regexmyOtherObject["regex"] vẫn có giá trị của chúng. Vậy thì làm thế nào chúng ta có thể loại bỏ đối tượng khỏi bộ nhớ cho chắc chắn?

Câu trả lời sẽ là xóa tất cả các tham chiếu bạn có trong mã của mình, chỉ vào chính đối tượng đó và cũng không sử dụng các câu lệnh var để tạo tham chiếu mới cho đối tượng đó . Điểm cuối cùng này liên quan đến các câu lệnh var, là một trong những vấn đề quan trọng nhất mà chúng ta thường gặp phải, bởi vì sử dụng các câu lệnh var sẽ ngăn không cho đối tượng được tạo ra bị xóa.

Điều đó có nghĩa là trong trường hợp này, bạn sẽ không thể xóa đối tượng đó vì bạn đã tạo biến regex thông qua câu lệnh var và nếu bạn thực hiện:

delete regex; //False

Kết quả sẽ là false, có nghĩa là câu lệnh xóa của bạn không được thực thi như bạn mong đợi. Nhưng nếu bạn chưa tạo biến đó trước đó và bạn chỉ có myOtherObject["regex"] làm tham chiếu hiện tại cuối cùng của mình, bạn có thể đã thực hiện việc này chỉ bằng cách xóa nó như sau:

myOtherObject["regex"] = null;
delete myOtherObject["regex"];

Nói cách khác, một đối tượng JavaScript sẽ bị giết ngay khi không còn tham chiếu nào trong mã của bạn được trỏ đến đối tượng đó.


Cập nhật: Cảm ơn @AgentME:

Đặt thuộc tính thành null trước khi xóa nó sẽ không thực hiện được bất cứ điều gì (trừ khi đối tượng đã bị Object.seal niêm phong và việc xóa không thành công. Đó thường không phải là trường hợp trừ khi bạn cố gắng cụ thể).

Để có thêm thông tin về Object.seal: Object.seal ()

45
Mehran Hatami

ECMAScript 2015 (hoặc ES6) đi kèm với Reflect object tích hợp. Có thể xóa thuộc tính đối tượng bằng cách gọi Reflect.deleteProperty () function với đối tượng đích và khóa thuộc tính làm tham số:

Reflect.deleteProperty(myJSONObject, 'regex');

tương đương với:

delete myJSONObject['regex'];

Nhưng nếu thuộc tính của đối tượng không thể cấu hình được thì không thể xóa cả chức năng erProperty cũng như xóa toán tử:

let obj = Object.freeze({ prop: "value" });
let success = Reflect.deleteProperty(obj, "prop");
console.log(success); // false
console.log(obj.prop); // value

Object.freeze () làm cho tất cả các thuộc tính của đối tượng không thể cấu hình (bên cạnh những thứ khác). Hàm deleteProperty (cũng như toán tử xóa ) trả về false khi cố gắng xóa bất kỳ thuộc tính nào của nó. Nếu thuộc tính có thể định cấu hình, nó trả về true, ngay cả khi thuộc tính không tồn tại.

Sự khác biệt giữa deletedeleteProperty là khi sử dụng chế độ nghiêm ngặt:

"use strict";

let obj = Object.freeze({ prop: "value" });
Reflect.deleteProperty(obj, "prop"); // false
delete obj["prop"];
// TypeError: property "prop" is non-configurable and can't be deleted
38
madox2

Giả sử bạn có một đối tượng trông như thế này:

var Hogwarts = {
    staff : [
        'Argus Filch',
        'Filius Flitwick',
        'Gilderoy Lockhart',
        'Minerva McGonagall',
        'Poppy Pomfrey',
        ...
    ],
    students : [
        'Hannah Abbott',
        'Katie Bell',
        'Susan Bones',
        'Terry Boot',
        'Lavender Brown',
        ...
    ]
};

Xóa một thuộc tính đối tượng

Nếu bạn muốn sử dụng toàn bộ mảng staff, cách thích hợp để làm điều này, sẽ là làm điều này:

delete Hogwarts.staff;

Ngoài ra, bạn cũng có thể làm điều này:

delete Hogwarts['staff'];

Tương tự, loại bỏ toàn bộ mảng sinh viên sẽ được thực hiện bằng cách gọi delete Hogwarts.students; hoặc delete Hogwarts['students'];.

Xóa một chỉ mục mảng

Bây giờ, nếu bạn muốn loại bỏ một nhân viên hoặc học sinh, quy trình này hơi khác một chút, vì cả hai thuộc tính đều là mảng.

Nếu bạn biết chỉ số của nhân viên của mình, bạn chỉ cần làm điều này:

Hogwarts.staff.splice(3, 1);

Nếu bạn không biết chỉ mục, bạn cũng sẽ phải thực hiện tìm kiếm chỉ mục:

Hogwarts.staff.splice(Hogwarts.staff.indexOf('Minerva McGonnagall') - 1, 1);

Chú thích

Mặc dù về mặt kỹ thuật bạn có thể sử dụng delete cho một mảng, sử dụng nó sẽ dẫn đến kết quả không chính xác khi gọi ví dụ Hogwarts.staff.length sau này. Nói cách khác, delete sẽ xóa phần tử, nhưng nó sẽ không cập nhật giá trị của thuộc tính length. Sử dụng delete cũng sẽ làm rối chỉ mục của bạn.

Vì vậy, khi xóa các giá trị khỏi một đối tượng, trước tiên, luôn luôn xem xét liệu bạn đang xử lý các thuộc tính đối tượng hay liệu bạn đang xử lý các giá trị mảng và chọn chiến lược phù hợp dựa trên đó.

Nếu bạn muốn thử nghiệm điều này, bạn có thể sử dụng this Fiddle làm điểm bắt đầu.

37
John Slegers

Toán tử xóa là cách tốt nhất để làm như vậy.

Một ví dụ trực tiếp để hiển thị:

var foo = {bar: 'bar'};
delete foo.bar;
console.log('bar' in foo); // Logs false, because bar was deleted from foo.
27
Tarun Nagpal

Cá nhân tôi sử dụng Underscore.js hoặc Lodash cho thao tác đối tượng và mảng:

myObject = _.omit(myObject, 'regex');
27
emil

Sử dụng xóa phương thức là cách tốt nhất để làm điều đó, theo mô tả MDN, toán tử xóa sẽ xóa một thuộc tính khỏi một đối tượng. Vì vậy, bạn có thể chỉ cần viết:

delete myObject.regex;
// OR
delete myObject['regex'];

Toán tử xóa sẽ xóa một thuộc tính đã cho khỏi một đối tượng. Khi xóa thành công, nó sẽ trả về true, false khác sẽ được trả về. Tuy nhiên, điều quan trọng là phải xem xét các tình huống sau:

  • Nếu thuộc tính mà bạn đang cố xóa không tồn tại, xóa sẽ không có hiệu lực và sẽ trả về đúng

  • Nếu một thuộc tính có cùng tên tồn tại trên chuỗi nguyên mẫu của đối tượng, thì sau khi xóa, đối tượng sẽ sử dụng thuộc tính từ chuỗi nguyên mẫu (nói cách khác, xóa chỉ có ảnh hưởng đến các thuộc tính riêng).

  • Bất kỳ thuộc tính nào được khai báo với var không thể bị xóa khỏi phạm vi toàn cục hoặc từ phạm vi của hàm.

  • Như vậy, xóa không thể xóa bất kỳ chức năng nào trong phạm vi toàn cầu (cho dù đây là một phần từ định nghĩa hàm hoặc hàm (biểu thức).

  • Các chức năng là một phần của một đối tượng (ngoài
    [.__.] phạm vi toàn cầu) có thể bị xóa bằng xóa.

  • Bất kỳ thuộc tính nào được khai báo với let hoặc const không thể bị xóa khỏi phạm vi mà chúng được xác định. Thuộc tính không cấu hình có thể được gỡ bỏ. Điều này bao gồm các thuộc tính của các đối tượng tích hợp như Math, Array, Object và các thuộc tính được tạo là không thể cấu hình với các phương thức như Object.defineProperty ().

Đoạn mã sau đây cho một ví dụ đơn giản khác:

var Employee = {
      age: 28,
      name: 'Alireza',
      designation: 'developer'
    }
    
    console.log(delete Employee.name);   // returns true
    console.log(delete Employee.age);    // returns true
    
    // When trying to delete a property that does 
    // not exist, true is returned 
    console.log(delete Employee.salary); // returns true

Để biết thêm thông tin về và xem thêm ví dụ, hãy truy cập liên kết dưới đây:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/delete

22
Alireza

Một giải pháp khác, sử dụngArray#reduce.

var myObject = {
  "ircEvent": "PRIVMSG",
  "method": "newURI",
  "regex": "^http://.*"
};

myObject = Object.keys(myObject).reduce(function(obj, key) {
  if (key != "regex") {           //key you want to remove
    obj[key] = myObject[key];
  }
  return obj;
}, {});

console.log(myObject);

Tuy nhiên, nó sẽ biến đổi đối tượng ban đầu. Nếu bạn muốn tạo một đối tượng mới không có khóa được chỉ định, chỉ cần gán hàm giảm cho một biến mới, ví dụ:

(ES6)

const myObject = {
  ircEvent: 'PRIVMSG',
  method: 'newURI',
  regex: '^http://.*',
};

const myNewObject = Object.keys(myObject).reduce((obj, key) => {
  key !== 'regex' ? obj[key] = myObject[key] : null;
  return obj;
}, {});

console.log(myNewObject);
20
kind user

Bài đăng này rất cũ và tôi thấy nó rất hữu ích vì vậy tôi đã quyết định chia sẻ chức năng unset mà tôi đã viết trong trường hợp người khác thấy bài đăng này và nghĩ tại sao nó không đơn giản như trong hàm PHP unset.

Lý do để viết hàm unset mới này là để giữ chỉ mục của tất cả các biến khác trong hàm hash_map này. Xem ví dụ sau và xem chỉ số của "test2" không thay đổi như thế nào sau khi xóa giá trị khỏi hàm hash_map.

function unset(unsetKey, unsetArr, resort){
  var tempArr = unsetArr;
  var unsetArr = {};
  delete tempArr[unsetKey];
  if(resort){
    j = -1;
  }
  for(i in tempArr){
    if(typeof(tempArr[i]) !== 'undefined'){
      if(resort){
        j++;
      }else{
        j = i;
      }
      unsetArr[j] = tempArr[i];
    }
  }
  return unsetArr;
}

var unsetArr = ['test','deletedString','test2'];

console.log(unset('1',unsetArr,true)); // output Object {0: "test", 1: "test2"}
console.log(unset('1',unsetArr,false)); // output Object {0: "test", 2: "test2"}
19
talsibony

Có rất nhiều câu trả lời hay ở đây nhưng tôi chỉ muốn nói rằng khi sử dụng xóa để xóa một thuộc tính trong JavaScript, trước tiên, nên kiểm tra xem liệu thuộc tính đó có tồn tại để ngăn ngừa lỗi hay không.

Ví dụ

var obj = {"property":"value", "property2":"value"};

if (obj && obj.hasOwnProperty("property2")) {
  delete obj.property2;
} else {
  //error handling
}

Do tính chất động của JavaScript, thường có những trường hợp bạn đơn giản không biết liệu tài sản có tồn tại hay không. Kiểm tra xem obj có tồn tại trước && cũng đảm bảo bạn không gặp lỗi do gọi hàm hasOwnProperty () trên một đối tượng không xác định.

Xin lỗi nếu điều này không thêm vào trường hợp sử dụng cụ thể của bạn nhưng tôi tin rằng đây là một thiết kế tốt để thích ứng khi quản lý các đối tượng và thuộc tính của chúng.

18
Willem

Sử dụng ramda # dissoc bạn sẽ nhận được một đối tượng mới mà không có thuộc tính regex:

const newObject = R.dissoc('regex', myObject);
// newObject !== myObject

Bạn cũng có thể sử dụng các chức năng khác để đạt được hiệu quả tương tự - bỏ qua, chọn, ...

14
Amio.io

Hãy thử phương pháp sau. Gán giá trị thuộc tính Object cho undefined. Sau đó stringify đối tượng và parse.

 var myObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};

myObject.regex = undefined;
myObject = JSON.parse(JSON.stringify(myObject));

console.log(myObject);
13
Mohammed Safeer

Sử dụng ES6:

(Hủy cấu trúc + Toán tử trải)

    const myObject = {
      regex: "^http://.*",
      b: 2,
      c: 3
    };
    const { regex, ...noRegex } = myObject;
    console.log(noRegex); // => { b: 2, c: 3 }
11
Srinivas

Nếu bạn muốn xóa một thuộc tính được lồng sâu vào đối tượng thì bạn có thể sử dụng hàm đệ quy sau với đường dẫn đến thuộc tính làm đối số thứ hai:

var deepObjectRemove = function(obj, path_to_key){
    if(path_to_key.length === 1){
        delete obj[path_to_key[0]];
        return true;
    }else{
        if(obj[path_to_key[0]])
            return deepObjectRemove(obj[path_to_key[0]], path_to_key.slice(1));
        else
            return false;
    }
};

Thí dụ:

var a = {
    level1:{
        level2:{
            level3: {
                level4: "yolo"
            }
        }
    }
};

deepObjectRemove(a, ["level1", "level2", "level3"]);
console.log(a);

//Prints {level1: {level2: {}}}
11
ayushgp

Bạn chỉ có thể xóa bất kỳ thuộc tính nào của một đối tượng bằng từ khóa delete.

Ví dụ:

var obj = {key1:"val1",key2:"val2",key3:"val3"}

Để xóa bất kỳ thuộc tính nào, giả sử key1, sử dụng từ khóa delete như thế này:

delete obj.key1

Hoặc bạn cũng có thể sử dụng ký hiệu giống như mảng:

delete obj[key1]

Tham chiếu: MD .

7
Kalpesh Patel

Xem xét việc tạo một đối tượng mới mà không có thuộc tính "regex" vì đối tượng ban đầu luôn có thể được tham chiếu bởi các phần khác trong chương trình của bạn. Vì vậy, bạn nên tránh thao tác nó.

const myObject = {
    "ircEvent": "PRIVMSG",
    "method": "newURI",
    "regex": "^http://.*"
};

const { regex, ...newMyObject } = myObject;

console.log(newMyObject);
6
ideaboxer

Dan khẳng định rằng 'xóa' là rất chậm và điểm chuẩn mà anh ta đăng tải bị nghi ngờ. Vì vậy, tôi đã tự mình thực hiện thử nghiệm trong Chrome 59. Có vẻ như 'xóa' chậm hơn khoảng 30 lần:

var iterationsTotal = 10000000;  // 10 million
var o;
var t1 = Date.now(),t2;
for (let i=0; i<iterationsTotal; i++) {
   o = {a:1,b:2,c:3,d:4,e:5};
   delete o.a; delete o.b; delete o.c; delete o.d; delete o.e;
}
console.log ((t2=Date.now())-t1);  // 6135
for (let i=0; i<iterationsTotal; i++) {
   o = {a:1,b:2,c:3,d:4,e:5};
   o.a = o.b = o.c = o.d = o.e = undefined;
}
console.log (Date.now()-t2);  // 205

Lưu ý rằng tôi cố tình thực hiện nhiều hơn một thao tác 'xóa' trong một chu kỳ vòng lặp để giảm thiểu ảnh hưởng do các hoạt động khác gây ra.

6
Chong Lip Phang

Object.assign () & Object.keys () & Array.map ()

const obj = {
    "Filters":[
        {
            "FilterType":"between",
            "Field":"BasicInformationRow.A0",
            "MaxValue":"2017-10-01",
            "MinValue":"2017-09-01",
            "Value":"Filters value"
        }
    ]
};

let new_obj1 = Object.assign({}, obj.Filters[0]);
let new_obj2 = Object.assign({}, obj.Filters[0]);

/*

// old version

let shaped_obj1 = Object.keys(new_obj1).map(
    (key, index) => {
        switch (key) {
            case "MaxValue":
                delete new_obj1["MaxValue"];
                break;
            case "MinValue":
                delete new_obj1["MinValue"];
                break;
        }
        return new_obj1;
    }
)[0];


let shaped_obj2 = Object.keys(new_obj2).map(
    (key, index) => {
        if(key === "Value"){
            delete new_obj2["Value"];
        }
        return new_obj2;
    }
)[0];


*/


// new version!

let shaped_obj1 = Object.keys(new_obj1).forEach(
    (key, index) => {
        switch (key) {
            case "MaxValue":
                delete new_obj1["MaxValue"];
                break;
            case "MinValue":
                delete new_obj1["MinValue"];
                break;
            default:
                break;
        }
    }
);

let shaped_obj2 = Object.keys(new_obj2).forEach(
    (key, index) => {
        if(key === "Value"){
            delete new_obj2["Value"];
        }
    }
);
6
xgqfrms-gildata
const myObject = {
        "ircEvent": "PRIVMSG",
        "method": "newURI",
        "regex": "^http://.*"
    };

const { regex, ...other } = myObject;

console.log(myObject)
console.log(regex)
console.log(other)
5
xiang

Thử đi

delete myObject['key'];
5
codemirror

Xin chào, bạn có thể thử cách đơn giản này

var obj = [];

obj.key1 = {name: "John", room: 1234};
obj.key2 = {name: "Jim", room: 1234};

delete(obj.key1);
5
Dhaval Gohel

Xóa tài sản trong JavaScript

Có rất nhiều tùy chọn khác nhau được trình bày trên trang này, không phải vì hầu hết các tùy chọn đều sai, hay vì các câu trả lời trùng lặp với nhau mà vì kỹ thuật phù hợp phụ thuộc vào tình huống bạn thực hiện và mục tiêu của các nhiệm vụ bạn và/hoặc bạn nhóm đang cố gắng thực hiện. Để trả lời câu hỏi của bạn một cách dứt khoát, người ta cần biết:

  1. Phiên bản ECMAScript bạn đang nhắm mục tiêu
  2. Phạm vi của các loại đối tượng bạn muốn xóa thuộc tính và loại tên thuộc tính bạn cần có thể bỏ qua (Chỉ chuỗi? Biểu tượng? Tham chiếu yếu được ánh xạ từ các đối tượng tùy ý? Đây đều là các loại con trỏ thuộc tính trong JavaScript trong nhiều năm nay )
  3. Các ethos lập trình/mẫu bạn và nhóm của bạn sử dụng. Bạn có thích cách tiếp cận chức năng và đột biến là verboten trong nhóm của bạn, hoặc bạn sử dụng các kỹ thuật hướng đối tượng đột biến ở phía tây hoang dã?
  4. Bạn đang muốn đạt được điều này trong JavaScript thuần túy hay bạn có sẵn sàng & có thể sử dụng thư viện của bên thứ 3 không?

Khi bốn câu hỏi đó đã được trả lời, về cơ bản có bốn loại "loại bỏ thuộc tính" trong JavaScript để đáp ứng mục tiêu của bạn. Họ đang:

Xóa tài sản đối tượng đột biến, không an toàn

Danh mục này dành cho hoạt động trên các đối tượng bằng chữ hoặc đối tượng khi bạn muốn giữ lại/tiếp tục sử dụng tham chiếu ban đầu và không sử dụng các nguyên tắc chức năng không trạng thái trong mã của bạn. Một ví dụ về cú pháp trong thể loại này:

'use strict'
const iLikeMutatingStuffDontI = { myNameIs: 'KIDDDDD!', [Symbol.for('amICool')]: true }
delete iLikeMutatingStuffDontI[Symbol.for('amICool')] // true
Object.defineProperty({ myNameIs: 'KIDDDDD!', 'amICool', { value: true, configurable: false })
delete iLikeMutatingStuffDontI['amICool'] // throws

Danh mục này là danh mục loại bỏ tài sản lâu đời nhất, đơn giản nhất và được hỗ trợ rộng rãi nhất. Nó hỗ trợ Symbol & các chỉ mục mảng ngoài các chuỗi và hoạt động trong mọi phiên bản JavaScript ngoại trừ bản phát hành đầu tiên. Tuy nhiên, đó là đột biến vi phạm một số nguyên tắc lập trình và có ý nghĩa về hiệu suất. Nó cũng có thể dẫn đến các ngoại lệ chưa được phát hiện khi được sử dụng trên các thuộc tính không thể định cấu hình ở chế độ nghiêm ngặt .

Bỏ sót thuộc tính chuỗi dựa trên phần còn lại

Danh mục này dành cho hoạt động trên các đối tượng hoặc đối tượng mảng đơn giản trong các hương vị ECMAScript mới hơn khi muốn có một cách tiếp cận không đột biến và bạn không cần phải tính đến các khóa Biểu tượng:

const foo = { name: 'KIDDDDD!', [Symbol.for('isCool')]: true }
const { name, ...coolio } = foo // coolio doesn't have "name"
const { isCool, ...coolio2 } = foo // coolio2 has everything from `foo` because `isCool` doesn't account for Symbols :(

Xóa tài sản đối tượng đột biến, an toàn

Danh mục này dành cho hoạt động trên các đối tượng bằng chữ hoặc đối tượng khi bạn muốn giữ lại/tiếp tục sử dụng tham chiếu ban đầu trong khi bảo vệ chống lại các ngoại lệ bị ném vào các thuộc tính không thể định cấu hình:

'use strict'
const iLikeMutatingStuffDontI = { myNameIs: 'KIDDDDD!', [Symbol.for('amICool')]: true }
Reflect.deleteProperty(iLikeMutatingStuffDontI, Symbol.for('amICool')) // true
Object.defineProperty({ myNameIs: 'KIDDDDD!', 'amICool', { value: true, configurable: false })
Reflect.deleteProperty(iLikeMutatingStuffDontI, 'amICool') // false

Ngoài ra, trong khi việc thay đổi các đối tượng tại chỗ không phải là không trạng thái, bạn có thể sử dụng tính chất chức năng của Reflect.deleteProperty để thực hiện một phần ứng dụng và các kỹ thuật chức năng khác không thể thực hiện được với các câu lệnh delete.

Bỏ sót thuộc tính chuỗi dựa trên cú pháp

Danh mục này dành cho hoạt động trên các đối tượng hoặc đối tượng mảng đơn giản trong các hương vị ECMAScript mới hơn khi muốn có một cách tiếp cận không đột biến và bạn không cần phải tính đến các khóa Biểu tượng:

const foo = { name: 'KIDDDDD!', [Symbol.for('isCool')]: true }
const { name, ...coolio } = foo // coolio doesn't have "name"
const { isCool, ...coolio2 } = foo // coolio2 has everything from `foo` because `isCool` doesn't account for Symbols :(

Bỏ sót tài sản dựa trên thư viện

Danh mục này thường cho phép linh hoạt hơn về chức năng, bao gồm cả việc hạch toán các Biểu tượng & bỏ sót nhiều hơn một thuộc tính trong một tuyên bố:

const o = require("lodash.omit")
const foo = { [Symbol.for('a')]: 'abc', b: 'b', c: 'c' }
const bar = o(foo, 'a') // "'a' undefined"
const baz = o(foo, [ Symbol.for('a'), 'b' ]) // Symbol supported, more than one prop at a time, "Symbol.for('a') undefined"
4
james_womack

Sử dụng lodash

import omit from 'lodash/omit';

const prevObject = {test: false, test2: true};
// Removes test2 key from previous object
const nextObject = omit(prevObject, 'test2');

Sử dụng Ramda

R.omit(['a', 'd'], {a: 1, b: 2, c: 3, d: 4}); //=> {b: 2, c: 3}
4
johndavedecano

Bạn có thể sử dụng ES6 phá hủy với toán tử nghỉ.

Các thuộc tính có thể được loại bỏ bằng cách sử dụng phá hủy kết hợp với toán tử rest . Trong ví dụ của bạn regex bị phá hủy (bỏ qua) và phần còn lại của các thuộc tính được trả về dưới dạng phần còn lại.

const noRegex = ({ regex, ...rest }) => rest;
const myObject = {
  "ircEvent": "PRIVMSG",
  "method": "newURI",
  "regex": "^http://.*"
};

console.log(noRegex(myObjext)) //=> {  "ircEvent": "PRIVMSG","method": "newURI" }

Hoặc bạn có thể tự động loại trừ các thuộc tính như thế này,

const myObject = {
  "ircEvent": "PRIVMSG",
  "method": "newURI",
  "regex": "^http://.*"
};
const removeProperty = prop => ({ [prop]: _, ...rest }) => rest

const removeRegex = removeProperty('regex') //=> {  "ircEvent": "PRIVMSG","method":"newURI" }
const removeMethod = removeProperty('method') //=> {  "ircEvent": "PRIVMSG", "regex":"^http://.*" }
3
Bhargav Patel

@johnstock , chúng ta cũng có thể sử dụng khái niệm tạo mẫu của JavaScript để thêm phương thức vào các đối tượng để xóa bất kỳ khóa đã qua nào có sẵn trong đối tượng gọi.

Câu trả lời trên được đánh giá cao.

var myObject = {
    "ircEvent": "PRIVMSG",
    "method": "newURI",
    "regex": "^http://.*"
};

// 1st and direct way 
delete myObject.regex;  // delete myObject["regex"]
console.log(myObject); // { ircEvent: 'PRIVMSG', method: 'newURI' }

 // 2 way -  by using the concept of JavaScript's prototyping concept
Object.prototype.removeFromObjectByKey = function(key) {
     // If key exists, remove it and return true
     if(this[key] !== undefined) {
           delete this[key]
           return true;
     }
     // Else return false
     return false;
}

var isRemoved = myObject.removeFromObjectByKey('method')
console.log(myObject)  // { ircEvent: 'PRIVMSG' }

// More examples
var obj = { a: 45, b: 56, c: 67}
console.log(obj) // { a: 45, b: 56, c: 67 }

// Remove key 'a' from obj
isRemoved = obj.removeFromObjectByKey('a')
console.log(isRemoved); //true
console.log(obj); // { b: 56, c: 67 }

// Remove key 'd' from obj which doesn't exist
var isRemoved = obj.removeFromObjectByKey('d')
console.log(isRemoved); // false
console.log(obj); // { b: 56, c: 67 }
3
hygull

Rất đơn giản:

var myObject = {
    "ircEvent": "PRIVMSG",
    "method": "newURI",
    "regex": "^http://.*"
};

delete myObject.regex;
2
Behnam Mohammadi

bạn có thể sử dụng toán tử delete như bên dưới.

 var multiverse = {
        earth1: "Silver Age",
        earth2: "Golden Age"
    };

delete multiverse.earth2;//will return true if it finds 

// Outputs: { earth1: "Silver Age" }
console.log(multiverse);

Toán tử xóa cũng có return value. Nếu thành công trong việc xóa một thuộc tính, nó sẽ trả về đúng. Nếu không xóa được một thuộc tính vì thuộc tính không thể ghi được, nó sẽ return false hoặc nếu ở chế độ nghiêm ngặt, nó sẽ báo lỗi.

1
MANISH MOHAN

Như nhiều người đã nói, bạn có thể sử dụng "xóa" (thuộc tính javascript) hoặc "hủy đặt" (sử dụng lodash).

Bạn cũng có thể sử dụng thuộc tính lodash "pick" để chỉ chọn các thuộc tính đối tượng cần thiết. Nó sẽ giúp ích khi bạn xóa nhiều thuộc tính khỏi đối tượng.

Cách sử dụng như sau:

var _   = require("lodash");
var obj = {"a":1, "b":2, "c":3};
obj = _.pick(obj,["a","b"]);    
//Now obj contains only 2 props {"a":1, "b":2}
1
Mythili

Tôi đã sử dụng lodash "unset" để thực hiện điều đó cho đối tượng lồng nhau .. chỉ cần điều này để viết logic nhỏ để có được đường dẫn của khóa thuộc tính mà phương thức bỏ qua dự kiến.

  1. Phương thức trả về đường dẫn thuộc tính dưới dạng mảng
var a = {"bool":{"must":[{"range":{"price_index.final_price":{"gt":"450","lt":"500"}}},{"bool":{"should":[{"term":{"color_value.keyword":"Black"}}]}}]}};

function getPathOfKey(object,key,currentPath, t){
     var currentPath = currentPath || [];

    for(var i in object){
                if(i == key){
        t = currentPath;
      }
      else if(typeof object[i] == "object"){
        currentPath.Push(i)
       return getPathOfKey(object[i], key,currentPath)
      }
    }
        t.Push(key);
    return t;
}
document.getElementById("output").innerHTML =JSON.stringify(getPathOfKey(a,"price_index.final_price"))
<div id="output"> 

</div>
  1. Sau đó, chỉ cần sử dụng lodash unset phương thức xóa thuộc tính khỏi đối tượng.
var unset = require('lodash.unset');
unset(a,getPathOfKey(a,"price_index.final_price"));
1
BEJGAM SHIVA PRASAD
function removeProperty(obj, prop) {
    if(prop in obj){

    Reflect.deleteProperty(obj, prop);
    return true;
   } else {
    return false;
  }
}
1
diayn geogiev

For

var myObject = {
    "ircEvent": "PRIVMSG",
    "method": "newURI",
    "regex": "^http://.*"
};

xóa myObject ["regex"]; Ngoài ra, bạn biết chỉ số của khóa, ví dụ. Bạn cần xóa khóa thứ 2 (regex) rồi

var key =  Object.keys(myObject)[2]
delete myObject[key];

Nhiều lần chúng tôi yêu cầu xóa chỉ mục dựa trên đối tượng Nhưng các phím Ghi nhớ trong đối tượng có thể ở vị trí hướng xuống, vì vậy hãy cẩn thận trong quá trình sử dụng

1
RITESH ARORA

Để sao chép đối tượng không có thuộc tính:

Ví dụ:

let object = { a: 1, b: 2, c: 3 };   

Và chúng ta cần xóa 'a'.

1.Với khóa prop rõ ràng:

const { a, ...rest } = object;
object = rest;

2.Với khóa prop biến:

const propKey = 'a';
const { [propKey]: propValue, ...rest } = object;
object = rest;

3.Cool mũi tên chức năng ????:

const removePropery = (propKey, { [propKey]: propValue, ...rest }) => rest;

object = removePropery('a', object);
0
YairTawil