Javascript";“流行音乐”;从对象
我编写了以下代码,从对象中“弹出”属性,就像它是数组一样。这类代码似乎会让我被更严肃的程序员打耳光,所以我想知道什么是正确的方法:Javascript";“流行音乐”;从对象,javascript,object,iterator,Javascript,Object,Iterator,我编写了以下代码,从对象中“弹出”属性,就像它是数组一样。这类代码似乎会让我被更严肃的程序员打耳光,所以我想知道什么是正确的方法: // 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" actua
// 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
}
我应该在上面提到,与真正的“流行音乐”不同,我不需要对象以任何特定的顺序出现。我只需要从其父对象中取出一个,并将其删除。对于for in
循环,浏览器之间没有“正确”的顺序。有些是按照它们被放入的顺序来做的,另一些则是先做数字索引。因此,如果不创建自己的自定义对象,就无法实现这一点
for( key in profiles ){
您应该将键
声明为var
profiles[key] = 0; // Save over property just in case "delete" actually deletes the property contents instead of just removing it from the object
这是不必要的。Delete不涉及属性的值(或者对于具有setter但没有getter的属性,甚至要求它具有值)
如果对象在其原型上有任何可枚举属性,那么这将做一些奇怪的事情。
考虑
对象中的属性不存储在堆栈中,因此基本概念无法可靠地工作(除了上面注释中提到的其他问题) 如果你真的需要这样的构造,试试这样的东西
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
演示:您可以创建如下pop方法:
Object.defineProperty(Object.prototype, 'pop',{
writable: false
, configurable: false
, enumerable: false
, value: function (name) {
var value = this[name];
delete this[name];
return value;
}
});
出于某种原因,只使用Object.prototype.pop=函数。。。中断JQuery是一种更好的方法,而不是直接修改输入数组。 例如
现在,您可以简单地使用spread运算符及其Rest方式:
const { key, ...profilesWithoutKey } = profiles;
要归功于在研究了上述所有评论和解决方案后,我可以基于它们提供一个完全准备就绪的解决方案:
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 { }
也许有人会派上用场;)
另外,如果您将我建议的代码与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() }
用
if(profiles.hasOwnProperty(key)包装正文{..
并松开=0
您到底想做什么?删除添加到对象中的第一个属性?这不一定有效,因为在for..in
循环中检索属性的顺序不能保证。除此之外,您应该使用hasOwnProperty
确保它不是o的一部分对于原型,您不需要执行任何操作,只需delete
即可从对象中删除属性。我认为您的意思是模拟数组方法,该方法删除(并返回)数组中的第一个元素。删除最后一个元素,因为push/pop数组方法充当FILO。此实现的一个问题是我们有一个堆栈,但内部数组是公共的。任何人都可以在任何情况下更改它,甚至用其他根本不是数组的东西替换它。Javascript基本上是动态的。我可以更改geArray.prototype.length
如果我愿意的话。虽然可以使用闭包来隐藏内部堆栈来创建更复杂的实现,但这是一个学习示例,在实践中,这需要大量额外的代码来保护您免受本机语言的影响。这实际上应该称为shift代码>,因为它删除了第一个元素而不是最后一个。我理解OP错误地命名了他的请求-也许你可以在回答中注意到。@jbyrd per“不需要对象以任何特定的顺序出现”可能是“take”?Doh!我想我应该更仔细地阅读该部分。有道理。在这种情况下,“take”不是个坏主意!
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 { }
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() }