[英]Removing all properties from a object
我有這個 Javascript object。
req.session
在我的代碼中,我向這個 object 添加了屬性。 這些屬性可以是其他對象,arrays,或者只是簡單的字符串。
req.session.savedDoc = someObject;
req.session.errors = ['someThing', 'anotherThing', 'thirdThing'];
req.session.message = 'someString'
如果我以后想刪除這個 object 的所有添加屬性,最簡單/最好的方法是什么?
一定有比這更好的方法嗎?
// Delete all session values
delete req.session.savedDoc;
delete req.session.errors;
delete req.session.message;
如果您想清除該特定引用,@VisioN 的答案有效,但如果您確實想清除一個對象,我發現這有效:
for (var variableKey in vartoClear){
if (vartoClear.hasOwnProperty(variableKey)){
delete vartoClear[variableKey];
}
}
只需分配一個空對象:
req.session = {};
...垃圾收集器會自動完成剩下的工作。
更新:由於這個答案是有爭議的,我想提供一些關於這一點的更多細節。
上面給出的解決方案將在當前情況下為作者完成工作,以及此問題中提供的任何其他有效解決方案。 這主要取決於開發人員希望如何操作已棄用的數據。
Session 對象可能包含由不同變量鏈接的數據,將新的空對象設置為req.session
不會破壞對舊數據的引用,因此舊數據將在仍然需要的地方可用。 盡管保留舊數據的正確方法是克隆初始對象,但現實生活場景可能會有所不同。 讓我們看看下面的例子:
req.session.user = { name: 'Alexander' }; // we store an object in the session
var session = req.session; // save reference to the session in a variable
console.log( req.session, session ); // {user: Object}, {user: Object}
req.session = {}; // let's replace session with a new object
console.log( req.session, session ); // {}, {user: Object}
我們仍然可以從session
變量中獲取舊數據,但req.session
是空的:這里設置一個新對象可以作為深度克隆的替代方法。 垃圾收集器不會從舊的req.session
對象中刪除數據,因為它仍然被session
變量引用。
使用@Dave提供的方法或通過Object.keys
更短的方法深度清理對象(忽略原型鏈中的屬性並且不需要node.js 的任何墊片):
Object.keys(object).forEach(function(key) { delete object[key]; });
...將從req.session
對象中明確刪除所有值,並且由於session
變量鏈接到同一個對象, session
也將變為空。 讓我們看看它是如何工作的:
req.session.user = { name: 'Alexander' }; // we store an object in the session
var session = req.session; // save reference to the session in a variable
console.log( req.session, session ); // {user: Object}, {user: Object}
Object.keys(req.session).forEach(function(key) { delete req.session[key]; });
console.log( req.session, session ); // {}, {}
正如你現在看到的,在這兩種情況下,我們都得到了空對象。
從速度和內存的角度來看,設置新的空對象比按屬性清理舊對象要快得多,但是如果舊數據仍然在某處引用,新對象方法不會釋放舊數據消耗的內存。
很明顯,選擇采用的方法主要取決於您的編碼場景,但在大多數情況下req.session = {};
將完成這項工作:它又快又短。 但是,如果在其他變量中保留對原始對象的引用,則可以考慮使用深層隱式對象屬性刪除。
我只能看到從對象中刪除自己的屬性的一種正確解決方案:
for (var x in objectToClean) if (objectToClean.hasOwnProperty(x)) delete objectToClean[x];
如果你想多次使用它,你應該創建一個清潔功能:
function deleteProperties(objectToClean) {
for (var x in objectToClean) if (objectToClean.hasOwnProperty(x)) delete objectToClean[x];
}
對於您的情況,用法是:
deleteProperties(req.session);
此解決方案從引用對象的任何地方刪除屬性並保留舊引用。
示例:
使用空對象賦值:
var x = {a: 5};
var y = x;
x = {}; // x will be empty but y is still {a: 5}, also now reference is gone: x !== y
使用清洗方法:
var x = {a: 5};
var y = x;
deleteProperties(x); // x and y are both empty and x === y
如果您想刪除所有屬性而不觸及方法,您可以使用:
for(var k in req.session) if(!req.session[k].constructor.toString().match(/^function Function\(/)) delete req.session[k];
我已經這樣做了
var
i,
keys = Object.keys(obj);
for(i = 0; i < keys.length; i++){
delete obj[keys[i]];
}
您可以將它添加到 Object (原型在這里並不理想) - 將是靜態的。
Object.defineproperties(Object, {
'clear': function(target){
var
i,
keys = Object.keys(target);
for(i = 0; i < keys.length; i++){
delete target[keys[i]];
}
}
});
然后你可以清除隨機對象
Object.clear(yourObj);
yourObj = {}
替換對新對象的引用,上面刪除了它的屬性 - 引用是相同的。
除了向量中報告的數據外,此腳本以遞歸方式刪除屬性。
你需要lodash 庫
-- 功能:
function removeKeysExcept(object, keysExcept = [], isFirstLevel = true) {
let arrayKeysExcept = [],
arrayNextKeysExcept = {};
_.forEach(keysExcept, (value, i) => {
let j = value.split('.');
let keyExcept = j[0];
arrayKeysExcept.push(keyExcept);
j.shift();
if (j.length) {
j = j.join('.');
if (!arrayNextKeysExcept[keyExcept]) {
arrayNextKeysExcept[keyExcept] = [];
}
arrayNextKeysExcept[keyExcept].push(j);
}
})
_.forEach(arrayNextKeysExcept, (value, key) => {
removeKeysExcept(object[key], value, false);
});
if (isFirstLevel) {
return;
}
Object.keys(object).forEach(function (key) {
if (arrayKeysExcept.indexOf(key) == -1) {
delete object[key];
}
});
}
運行:
-- 刪除除第一級之外的所有屬性並在向量中報告:
removeKeysExcept(obj, ['department.id','user.id']);
-- 刪除所有屬性
removeKeysExcept(obj, ['department.id','user.id'], false);
-- 例子:
let obj = {
a: {
aa: 1,
ab: {
aba: 21
}
},
b: 10,
c: {
ca: 100,
cb: 200
}
};
removeKeysExcept(obj, ['a.ab.aba','c.ca']);
/*OUTPUT: {
a: {
ab: {
aba: 21
}
},
b: 10,
c: {
ca: 100,
}
};*/
removeKeysExcept(obj, ['a.ab.aba','c.ca'], false); //Remove too firt level
/*OUTPUT: {
a: {
ab: {
aba: 21
}
},
c: {
ca: 100,
}
};*/
removeKeysExcept(obj);
/*OUTPUT: {b:10};*/
removeKeysExcept(obj, [], false); //Remove too firt level
/*OUTPUT: {};*/
naive object = {}
方法適用於 vanilla Object,但它刪除了自定義對象的原型。
此方法使用Object.getPrototypeOf()和Object.create()生成一個保留原型的空對象:
emptyObj = Object.create(Object.getPrototypeOf(obj), {});
示例:
class Custom extends Object { custom() {} } let custom = new Custom(); custom.foo = "bar"; console.log(custom.constructor.name, custom); // Custom {"foo": "bar"} // naive method: let objVanilla = {} console.log(objVanilla.constructor.name, objVanilla); // Object {} // safe method: objSafe = Object.create(Object.getPrototypeOf(custom), {}); console.log(objSafe.constructor.name, objSafe); // Custom {}
如果您關心這樣的性能,您可以使用 map
const map = new Map()
map.set("first", 1)
map.set("second", 1)
map.clear()
這是一個O(1)
操作,所以即使你有一個巨大的 object 你也不需要迭代 x 次來刪除條目。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.