簡體   English   中英

如何從 JavaScript object 中刪除屬性?

[英]How do I remove a property from a JavaScript object?

給定一個 object:

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

如何刪除屬性regex以結束以下myObject

let myObject = {
  "ircEvent": "PRIVMSG",
  "method": "newURI"
};

要從對象中刪除屬性(改變對象),您可以這樣做:

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

演示

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

對於任何有興趣閱讀更多相關信息的人,Stack Overflow 用戶kangax在他們的博客上寫了一篇關於delete語句的非常深入的博文, Understanding delete 強烈推薦。

如果你想要一個對象,除了一些之外,所有的鍵都是原始的,你可以使用destructuring

演示

 let myObject = { "ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*" }; const {regex, ...newObj} = myObject; console.log(newObj); // has no 'regex' key console.log(myObject); // remains unchanged

JavaScript 中的對象可以被認為是鍵和值之間的映射。 delete運算符用於刪除這些鍵,通常稱為對象屬性,一次刪除一個。

 var obj = { myProperty: 1 } console.log(obj.hasOwnProperty('myProperty')) // true delete obj.myProperty console.log(obj.hasOwnProperty('myProperty')) // false

delete操作符不直接釋放內存,它不同於簡單地將nullundefined的值分配給屬性,因為屬性本身從對象中刪除。 請注意,如果被刪除的屬性的是一個引用類型(一個對象),並且程序的另一部分仍然持有對該對象的引用,那么該對象當然不會被垃圾收集,直到對它的所有引用都有消失了。

delete僅適用於描述符將其標記為可配置的屬性。

 var myObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"}; delete myObject.regex; console.log ( myObject.regex); // logs: undefined

這適用於 Firefox 和 Internet Explorer,我認為它適用於所有其他人。

delete運算符用於從對象中刪除屬性。

const obj = { foo: "bar" }
delete obj.foo
obj.hasOwnProperty("foo") // false

請注意,對於數組,這與刪除元素不同 要從數組中刪除元素,請使用Array#spliceArray#pop 例如:

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

細節

JavaScript 中的delete與 C 和 C++ 中的關鍵字的功能不同:它不直接釋放內存。 相反,它的唯一目的是從對象中刪除屬性。

對於數組,刪除與索引對應的屬性,會創建一個稀疏數組(即其中有一個“洞”的數組)。 大多數瀏覽器將這些缺失的數組索引表示為“空”。

var array = [0, 1, 2, 3]
delete array[2] // [0, 1, empty, 3]

請注意, delete不會將array[3]定位到array[2]

JavaScript 中不同的內置函數處理稀疏數組的方式不同。

  • for...in將完全跳過空索引。

  • 傳統的for循環將為索引處的值返回undefined

  • 任何使用Symbol.iterator方法都會為索引處的值返回undefined

  • forEachmapreduce將簡單地跳過丟失的索引。

因此, delete運算符不應用於從數組中刪除元素的常見用例。 數組有專門的方法來刪除元素和重新分配內存: Array#splice()Array#pop

數組#splice(start[, deleteCount[, item1[, item2[, ...]]]])

Array#splice改變數組,並返回任何刪除的索引。 從索引start中刪除deleteCount元素,並將item1, item2... itemN從索引start插入到數組中。 如果省略了deleteCount則從 startIndex 開始的元素將被移除到數組的末尾。

let a = [0,1,2,3,4]
a.splice(2,2) // returns the removed elements [2,3]
// ...and `a` is now [0,1,4]

Array.prototype上還有一個名稱相似但不同的函數: Array#slice

數組#slice([begin[, end]])

Array#slice是非破壞性的,並返回一個新數組,其中包含從startend的指示索引。 如果未指定end ,則默認為數組的末尾。 如果end為正數,則指定要停止的從零開始的非包含索引。 如果end為負數,則它通過從數組末尾開始倒數來指定要停止的索引(例如,-1 將省略最終索引)。 如果end <= start ,結果是一個空數組。

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

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

數組#pop

Array#pop從數組中刪除最后一個元素,並返回該元素。 此操作更改數組的長度。

老問題,現代答案。 使用對象解構( ECMAScript 6 的一項特性),它非常簡單:

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

或者使用問題示例:

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

您可以在 Babel 試用版編輯器中看到它的運行情況。


編輯:

要重新分配給同一個變量,請使用let

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

展開語法(ES6)

要完成Koen 的回答,如果您想使用傳播語法刪除動態變量,您可以這樣做:

 const key = 'a'; const { [key]: foo, ...rest } = { a: 1, b: 2, c: 3 }; console.log(foo); // 1 console.log(rest); // { b: 2, c: 3 }

* foo將是一個值為a (即 1)的新變量。

擴展答案😇

有幾種常見的方法可以從對象中刪除屬性。
每個都有自己的優點和缺點(檢查這個性能比較):

刪除運算符

它可讀且簡短,但是,如果您正在對大量對象進行操作,它可能不是最佳選擇,因為它的性能未優化。

delete obj[key];

重新分配

它比delete快兩倍多,但是該屬性不會被刪除並且可以迭代。

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

展開運算符

這個ES6運算符允許我們返回一個全新的對象,不包括任何屬性,而不改變現有對象。 缺點是它的性能比上述更差,當您需要一次刪除許多屬性時,不建議使用它。

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

另一種選擇是使用Underscore.js庫。

請注意_.pick()_.omit()都返回對象的副本並且不直接修改原始對象。 將結果分配給原始對象應該可以解決問題(未顯示)。

參考:鏈接_.pick(object, *keys)

返回對象的副本,過濾后僅包含白名單鍵(或有效鍵數組)的值。

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

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

參考:鏈接_.omit(object, *keys)

返回對象的副本,過濾以省略列入黑名單的鍵(或鍵數組)。

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

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

對於數組,可以以類似的方式使用_.filter()_.reject()

克隆一個沒有屬性的對象:

例如:

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

我們需要刪除a .

  1. 使用明確的道具鍵

     const { a, ...rest } = object; object = rest;
  2. 使用可變道具鍵

     const propKey = 'a'; const { [propKey]: propValue, ...rest } = object; object = rest;
  3. 一個很酷的箭頭函數😎:

     const removeProperty = (propKey, { [propKey]: propValue, ...rest }) => rest; object = removeProperty('a', object);
  4. 對於多個屬性

    const removeProperties = (object, ...keys) => Object.entries(object).reduce((prev, [key, value]) => ({...prev, ...(!keys.includes(key) && { [key]: value }) }), {})

用法

object = removeProperties(object, 'a', 'b') // result => { c: 3 }

要么

    const propsToRemove = ['a', 'b']
    object = removeProperties(object, ...propsToRemove) // result => { c: 3 }

您在問題標題中使用的術語Remove a property from a JavaScript object可以用一些不同的方式解釋。 一種是在整個內存和對象鍵列表中刪除它,另一種是將它從您的對象中刪除。 正如在其他一些答案中提到的那樣, delete關鍵字是主要部分。 假設您有這樣的對象:

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

如果你這樣做:

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

結果將是:

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

您可以從對象鍵中刪除該特定鍵,例如:

delete myJSONObject["regex"];

然后使用Object.keys(myJSONObject)對象鍵將是:

["ircEvent", "method"]

但關鍵是如果您關心內存並且想要將整個對象從內存中刪除,建議在刪除鍵之前將其設置為 null:

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

這里的另一個重點是注意對同一對象的其他引用。 例如,如果您創建一個變量,如:

var regex = myJSONObject["regex"];

或者將其添加為指向另一個對象的新指針,例如:

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

然后,即使您從對象myJSONObject刪除它,該特定對象也不會從內存中刪除,因為regex變量和myOtherObject["regex"]仍然具有它們的值。 那么我們如何才能確定地從內存中刪除該對象呢?

答案是刪除代碼中所有指向該對象的引用,並且不使用var語句創建對該對象的新引用 關於var語句的最后一點,是我們通常面臨的最關鍵的問題之一,因為使用var語句會阻止創建的對象被刪除。

這意味着在這種情況下,您將無法刪除該對象,因為您已經通過var語句創建了regex變量,如果您這樣做:

delete regex; //False

結果將為false ,這意味着您的 delete 語句未按預期執行。 但是,如果您之前沒有創建該變量,並且您只有myOtherObject["regex"]作為您最后一個現有引用,您可以通過刪除它來完成此操作,例如:

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

換句話說,只要您的代碼中沒有指向該對象的引用,JavaScript 對象就會被殺死。


更新:

感謝@AgentME:

在刪除之前將屬性設置為 null 不會完成任何操作(除非對象已被 Object.seal 密封並且刪除失敗。除非您特別嘗試,否則通常不會出現這種情況)。

獲取更多關於Object.seal信息: Object.seal()

ECMAScript 2015(或 ES6)帶有內置的Reflect對象。 可以通過使用目標對象和屬性鍵作為參數調用Reflect.deleteProperty()函數來刪除對象屬性:

Reflect.deleteProperty(myJSONObject, 'regex');

這相當於:

delete myJSONObject['regex'];

但是,如果對象的屬性不可配置,則無法使用 deleteProperty 函數或 delete 運算符刪除它:

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

Object.freeze()使對象的所有屬性都不可配置(除其他外)。 deleteProperty函數(以及delete operator )在嘗試刪除它的任何屬性時返回false 如果屬性是可配置的,它返回true ,即使屬性不存在。

deletedeleteProperty的區別在於使用嚴格模式時:

"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

假設您有一個如下所示的對象:

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

刪除對象屬性

如果你想使用整個staff數組,正確的方法是這樣做:

delete Hogwarts.staff;

或者,您也可以這樣做:

delete Hogwarts['staff'];

同樣,通過調用delete Hogwarts.students;delete Hogwarts.students;整個學生數組delete Hogwarts.students; delete Hogwarts['students']; .

刪除數組索引

現在,如果您想刪除單個教職員工或學生,過程有點不同,因為這兩個屬性本身都是數組。

如果你知道你的員工的索引,你可以簡單地這樣做:

Hogwarts.staff.splice(3, 1);

如果您不知道索引,則還必須進行索引搜索:

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

筆記

雖然您在技術上可以對數組使用delete ,但在稍后調用例如Hogwarts.staff.length時,使用它會導致得到錯誤的結果。 換句話說, delete會刪除元素,但不會更新length屬性的值。 使用delete也會弄亂你的索引。

因此,從對象中刪除值時,請始終首先考慮您是在處理對象屬性還是在處理數組值,然后根據此選擇適當的策略。

如果你想嘗試這個,你可以使用這個 Fiddle作為起點。

我個人使用Underscore.jsLodash的對象和數組操作:

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

使用delete方法是最好的方法,根據 MDN 描述,delete 操作符從對象中刪除一個屬性。 所以你可以簡單地寫:

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

delete 運算符從對象中刪除給定的屬性。 刪除成功返回true,否則返回false。 但是,重要的是要考慮以下情況:

  • 如果您嘗試刪除的屬性不存在,則刪除不會有任何效果並返回 true

  • 如果對象的原型鏈上存在同名的屬性,那么刪除后,對象將使用原型鏈中的屬性(換句話說,刪除只對自己的屬性有影響)。

  • 任何用 var 聲明的屬性都不能從全局作用域或函數作用域中刪除。

  • 因此,delete 不能刪除全局范圍內的任何函數(無論這是函數定義的一部分還是函數(表達式)的一部分)。

  • 作為對象一部分的函數(除了
    全局范圍)可以用 delete 刪除。

  • 任何用 let 或 const 聲明的屬性都不能從定義它們的范圍中刪除。 無法刪除不可配置的屬性。 這包括內置對象的屬性,如 Math、Array、Object 和使用 Object.defineProperty() 等方法創建為不可配置的屬性。

下面的代碼片段給出了另一個簡單的例子:

 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

有關更多信息和查看更多示例,請訪問以下鏈接:

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

使用ES6:

(解構+傳播運算符)

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

刪除運算符是最好的方法。

一個實時示例顯示:

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

另一個解決方案,使用Array#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);

但是,它會改變原始對象。 如果你想在沒有指定鍵的情況下創建一個新對象,只需將 reduce 函數分配給一個新變量,例如:

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

這里有很多很好的答案,但我只想補充一點,當使用 delete 刪除 JavaScript 中的屬性時,首先檢查該屬性是否存在以防止錯誤通常是明智的。

例如

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

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

由於 JavaScript 的動態特性,通常情況下您根本不知道該屬性是否存在。 在 && 之前檢查 obj 是否存在還可以確保您不會因為在未定義的對象上調用 hasOwnProperty() 函數而引發錯誤。

抱歉,如果這沒有添加到您的特定用例中,但我相信這是一個很好的設計,可以在管理對象及其屬性時進行調整。

這篇文章很老了,我覺得它很有幫助,所以我決定分享我寫的 unset 函數,以防其他人看到這篇文章並思考為什么它不像 PHP 的 unset 函數那么簡單。

編寫這個新的unset函數的原因是在這個 hash_map 中保留所有其他變量的索引。 看下面的例子,看看從 hash_map 中刪除一個值后,“test2”的索引是如何沒有改變的。

 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"}

使用ramda#dissoc您將獲得一個沒有屬性regex的新對象:

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

您還可以使用其他功能來實現相同的效果 - 省略、選擇、...

試試下面的方法。 Object屬性值分配給undefined 然后將對象stringifyparse .

 var myObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"}; myObject.regex = undefined; myObject = JSON.parse(JSON.stringify(myObject)); console.log(myObject);

如果要刪除深度嵌套在對象中的屬性,則可以使用以下遞歸函數,並將該屬性的路徑作為第二個參數:

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

例子:

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

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

//Prints {level1: {level2: {}}}

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"]; } } );

這是一種輕松刪除條目的 ES6 方法:

 let myObject = { "ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*" }; const removeItem = 'regex'; const { [removeItem]: remove, ...rest } = myObject; console.log(remove); // "^http://.*" console.log(rest); // Object { ircEvent: "PRIVMSG", method: "newURI" }

Dan 斷言“刪除”非常慢,他發布的基准受到質疑。 所以我自己在 Chrome 59 中進行了測試。看起來“刪除”確實慢了大約 30 倍:

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

請注意,我特意在一個循環周期中執行了多個“刪除”操作,以盡量減少其他操作造成的影響。

JavaScript 中的屬性刪除

此頁面上提供了許多不同的選項,不是因為大多數選項是錯誤的——或者因為答案是重復的——而是因為適當的技術取決於你所處的情況以及你和/或你的任務目標團隊正在努力實現。 要明確回答您的問題,您需要知道:

  1. 您定位的 ECMAScript 版本
  2. 要刪除屬性的對象類型范圍以及需要能夠省略的屬性名稱類型(僅字符串?符號?從任意對象映射的弱引用?多年來,這些都是 JavaScript 中的屬性指針類型)
  3. 您和您的團隊使用的編程精神/模式。 你喜歡函數式方法並且你的團隊禁止變異,還是采用狂野西部變異的面向對象技術?
  4. 您是想用純 JavaScript 實現這一點,還是願意並能夠使用 3rd-party 庫?

一旦回答了這四個查詢,JavaScript 中基本上就有四類“屬性刪除”可供選擇,以滿足您的目標。 他們是:

可變對象屬性刪除,不安全

當您想要保留/繼續使用原始引用並且不在代碼中使用無狀態功能原則時,此類別用於對對象文字或對象實例進行操作。 此類別中的示例語法:

'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

此類別是最古老、最直接和最廣泛支持的財產移除類別。 除了字符串之外,它還支持Symbol和數組索引,並且適用於除第一個版本之外的所有 JavaScript 版本。 但是,它是可變的,它違反了一些編程原則並具有性能影響。 在嚴格模式下用於不可配置的屬性時,它也可能導致未捕獲的異常。

基於休息的字符串屬性省略

當需要非可變方法並且您不需要考慮符號鍵時,此類別用於在較新的 ECMAScript 風格中對普通對象或數組實例進行操作:

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 :(

可變對象屬性刪除,安全

當您想要保留/繼續使用原始引用同時防止在不可配置的屬性上引發異常時,此類別用於對對象文字或對象實例進行操作:

'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

此外,雖然就地改變對象不是無狀態的,但您可以使用Reflect.deleteProperty的功能特性來執行部分應用和其他delete語句無法實現的功能技術。

基於語法的字符串屬性省略

當需要非可變方法並且您不需要考慮符號鍵時,此類別用於在較新的 ECMAScript 風格中對普通對象或數組實例進行操作:

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 :(

基於圖書館的財產遺漏

此類別通常允許更大的功能靈活性,包括考慮符號和在一個語句中省略多個屬性:

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"

@johnstock ,我們還可以使用 JavaScript 的原型概念向對象添加方法,以刪除調用對象中可用的任何傳遞鍵。

以上答案表示贊賞。

 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 }

使用Lodash

import omit from 'lodash/omit';

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

使用 Ramda

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

您可以簡單地使用delete關鍵字delete對象的任何屬性。

例如:

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

要刪除任何屬性,例如key1 ,請使用delete關鍵字,如下所示:

delete obj.key1

或者,您也可以使用類似數組的符號:

delete obj[key1]

參考: MDN

您可以使用如下過濾器

 var myObject = { "ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*" }; // Way 1 let filter1 = {} Object.keys({...myObject}).filter(d => { if(d !== 'regex'){ filter1[d] = myObject[d]; } }) console.log(filter1) // Way 2 let filter2 = Object.fromEntries(Object.entries({...myObject}).filter(d => d[0] !== 'regex' )) console.log(filter2)

我已經使用Lodash "unset"使其也適用於嵌套對象......只需要編寫小邏輯來獲取omit方法預期的屬性鍵的路徑。

  1. 將屬性路徑作為數組返回的方法

 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. 然后只需使用Lodash unset方法從對象中刪除屬性。

 var unset = require('lodash.unset'); unset(a, getPathOfKey(a, "price_index.final_price"));

考慮創建沒有"regex"屬性的新對象,因為原始對象始終可以被程序的其他部分引用。 因此,您應該避免對其進行操作。

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

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

您可以將ES6解構與rest運算符一起使用。

可以通過與rest運算符結合使用分解來刪除屬性。 在您的示例中,正則表達式被解構(忽略),其余屬性作為其余部分返回。

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

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

或者您可以動態排除此類屬性,

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://.*" }

嘗試這個

delete myObject['key'];

您好,您可以嘗試這種簡單的排序

var obj = [];

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

delete(obj.key1);

 let myObject = { "ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*" }; obj = Object.fromEntries( Object.entries(myObject).filter(function (m){ return m[0] != "regex"/*or whatever key to delete*/ } )) console.log(obj)

您也可以使用Object.entries將對象視為a2d數組,並像在普通數組中一樣使用 splice 刪除元素,或者像數組一樣簡單地過濾對象,然后將重建的對象分配回原始變量

如果不想修改原始對象。

刪除屬性而不改變對象

如果可變性是一個問題,您可以通過復制舊的所有屬性來創建一個全新的對象,除了要刪除的屬性。

 let myObject = { "ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*" }; let prop = 'regex'; const updatedObject = Object.keys(myObject).reduce((object, key) => { if (key !== prop) { object[key] = myObject[key] } return object }, {}) console.log(updatedObject);

刪除對象的兩種方法

  1. 使用for ... in

     function deleteUser(key) { const newUsers = {}; for (const uid in users) { if (uid !== key) { newUsers[uid] = users[uid]; } return newUsers }

要么

delete users[key]

說我創建一個對象,如下所示:

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

我應該如何刪除屬性regex以新的myObject結尾,如下所示?

let myObject = {
  "ircEvent": "PRIVMSG",
  "method": "newURI"
};

讓我們保持簡單,重點:

只需將該特定屬性/字段設置為 = undefined

var myObject = {
    'i': "How are you?",
    'am': "Dear",
    'fine': "Hello"
};

myObject.am = undefined;

console.log(myObject);

> {i: "How are you?", am: undefined, fine: "Hello"}

有幾個選項:

  1. 使用點屬性訪問器刪除

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

  1. 使用方形剎車屬性訪問器刪除

 const myObject = { "ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*", }; delete myObject['regex']; console.log(myObject); // or const name = 'ircEvent'; delete myObject[name]; console.log(myObject);

  1. 另一種選擇,但以不改變原始對象的不可變方式,使用對象解構和休息語法。

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

我們可以刪除使用

  1. 使用刪除 object.property
  2. 使用刪除對象['property']
  3. 使用休息,刪除多個屬性

 let myObject = { "ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*", "regex1": "^http://.*", "regex2": "^http://.*", "regex3": "^http://.*", "regex4": "^http://.*" }; delete myObject.regex; // using delete object.property // Or delete myObject['regex1']; // using delete object['property'] const { regex2, regex3, regex4, ...newMyObject } = myObject; console.log(newMyObject);

您可以使用 Delete property[key] 從對象中刪除屬性

在 JavaScript 中,有兩種常用方法可以從對象中刪除屬性。

第一種可變方法是使用delete object.property運算符。

第二種方法是不可變的,因為它不會修改原始對象,它是調用對象解構和擴展語法: const {property, ...rest} = object

簡短的回答

var obj = {
  data: 1,
  anotherData: 'sample'    
}
delete obj.data //this removes data from the obj

你只剩下

var obj = {
  anotherData: 'sample'    
}

 const object = { prop1: 10, prop2: 20, prop3: 30, "test prop": "This is test props" } console.log(object); // will print all 4 props delete object.prop1; delete object["test prop"]; console.log(object); // will print only prop2 and prop3

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM