簡體   English   中英

從 object 中刪除所有屬性

[英]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.

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