Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/372.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript";“流行音乐”;从对象_Javascript_Object_Iterator - Fatal编程技术网

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基本上是动态的。我可以更改ge
Array.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() }