Javascript Javascript从对象“弹出”
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6630772/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Javascript "pop" from object
提问by Chris Dutrow
I wrote the following code to "pop" a property from an object as if it were an array. This looks like the kind of code that would get me slapped by more serious programmers, so I was wondering what is the proper way to do this:
我编写了以下代码来从对象中“弹出”一个属性,就好像它是一个数组一样。这看起来像是会让我被更认真的程序员打耳光的那种代码,所以我想知道这样做的正确方法是什么:
// wrong way to pop:
for( key in profiles ){
var profile = profiles[key]; // get first property
profiles[key] = 0; // Save over property just in case "delete" actually deletes the property contents instead of just removing it from the object
delete profiles[key]; // remove the property from the object
break; // "break" because this is a loop
}
I should have mentioned above, that unlike a true "pop", I don't need the objects to come out in any particular order. I just need to get one out and remove it from its parent object.
我应该在上面提到过,与真正的“流行”不同,我不需要对象以任何特定顺序出现。我只需要取出一个并将其从其父对象中删除。
采纳答案by Mike Samuel
for( key in profiles ){
You should really declare key
as a var
.
你真的应该声明key
为var
.
profiles[key] = 0; // Save over property just in case "delete" actually deletes the property contents instead of just removing it from the object
is unnecessary. Delete doesn't touch the value of the property (or in the case of a property that has a setter but no getter, even require that it have a value).
是不必要的。Delete 不会触及属性的值(或者对于具有 setter 但没有 getter 的属性,甚至要求它具有值)。
If the object has any enumerable properties on its prototype, then this will do something odd. Consider
如果对象在其原型上有任何可枚举的属性,那么这会做一些奇怪的事情。考虑
Object.prototype.foo = 42;
function take(obj) {
for (var key in obj) {
// Uncomment below to fix prototype problem.
// if (!Object.hasOwnProperty.call(obj, key)) continue;
var result = obj[key];
// If the property can't be deleted fail with an error.
if (!delete obj[key]) { throw new Error(); }
return result;
}
}
var o = {};
alert(take(o)); // alerts 42
alert(take(o)); // still alerts 42
回答by Noam Gal
Nowadays you can simply use the spread operator with its Rest way:
现在,您可以简单地使用扩展运算符及其 Rest 方式:
const { key, ...profilesWithoutKey } = profiles;
Credit to this blog post
归功于这篇博文
回答by Jamie Treworgy
Properties in an object are not stored in a stack so the basic concept won't work reliably (aside from the other issues mentioned in the comments above).
对象中的属性不存储在堆栈中,因此基本概念将无法可靠地工作(除了上面评论中提到的其他问题)。
If you really need such a construct try something like this.
如果您真的需要这样的构造,请尝试这样的操作。
var ObjectStack = function(obj) {
this.object = obj;
this.stack=[];
};
ObjectStack.prototype.push = function(key,value) {
this.object[key]=value;
this.stack.push(key);
};
ObjectStack.prototype.pop = function() {
var key = this.stack.pop();
var prop = this.object[key];
delete this.object[key];
return prop;
};
var my_obj = {};
var my_stack = new ObjectStack(my_obj);
my_stack.push("prop1",val1);
my_stack.push("prop2",val2);
var last_prop = my_stack.pop(); //val2
回答by xLegioner
Having studied all the comments and solutions above, I can offer a completely ready solution based on them:
研究了上面的所有评论和解决方案后,我可以基于它们提供一个完全准备好的解决方案:
Object.prototype.pop = function() {
for (var key in this) {
if (!Object.hasOwnProperty.call(this, key)) continue;
var result = this[key];
if (!delete this[key]) throw new Error();
return result;
}
};
var obj = {
a: '1',
b: '2',
c: '3'
};
console.log(obj.pop()); // 1
console.log(obj.pop()); // 2
console.log(obj.pop()); // 3
console.log(obj); // Object { }
Perhaps someone will come in handy ; )
也许有人会派上用场;)
PS. If you use the code I propose along with the jQuery library, you may encounter errors in the console. In this case, the option given below is appropriate:
附注。如果您将我建议的代码与 jQuery 库一起使用,您可能会在控制台中遇到错误。在这种情况下,下面给出的选项是合适的:
function _pop() {
for (var key in this) {
if (!Object.hasOwnProperty.call(this, key)) continue;
if (key === 'pop') continue;
var result = this[key];
if (!delete this[key]) throw new Error();
return result;
}
}
var obj = {
a: '1',
b: '2',
c: '3'
};
obj.pop = _pop;
console.log(obj.pop()); // 1
console.log(obj.pop()); // 2
console.log(obj.pop()); // 3
console.log(obj); // Object { pop: _pop() }
回答by qwertymk
There's no "correct" order across browsers in what they give for a for in
loop. Some do them in the order they are put in, other do it numerical indexes first. So there really is no way to do this without creating your own custom object
浏览器为for in
循环提供的内容没有“正确”的顺序。有些是按照放入的顺序执行的,有些则是先执行数字索引。因此,如果不创建您自己的自定义对象,真的没有办法做到这一点
回答by Mackraken
You are able to create the pop method like this: .
您可以像这样创建 pop 方法:
Object.defineProperty(Object.prototype, 'pop',{
writable: false
, configurable: false
, enumerable: false
, value: function (name) {
var value = this[name];
delete this[name];
return value;
}
});
for some reason using just Object.prototype.pop = function ... breaks JQuery
出于某种原因只使用 Object.prototype.pop = function ... 打破了 JQuery
回答by Devesh Chauhan
A better approach instead of directly modifying the input array. Eg.
一种更好的方法,而不是直接修改输入数组。例如。
let arr = [{label: "a"}, {label: "b"}, {label: "p"}, {label: "c"}]
let newArr = arr.filter(p => { return p.label !== "p";});