Использовать свойство объекта для итерации

можно ли использовать свойство объекта для итерации «для in» в JavaScript?

Я хочу написать Bag-Class следующим образом:

var Bag = function () {
  this.elements = {};
}

Bag.prototype.add = function (key, value) {
  this.elements[key] = value;
};

// other methods ...

Теперь я хочу использовать объекты этого класса в for в итерации:

for (var key in myBag) {
  console.log(myBag[key]); // or myBag.get(key);
}

Можно ли сделать это без вспомогательного метода, такого как ключ var в myBag.getAll()?


person Shutterfly    schedule 12.07.2014    source источник
comment
Как насчет for (var key in myBag.elements)?   -  person elclanrs    schedule 13.07.2014
comment
блин, слишком просто. Но я предпочитаю решение без .elements, если это возможно.   -  person Shutterfly    schedule 13.07.2014
comment
this.elements[key] будет эквивалентно this.elements.key (если ключ существует), потому что вы определяете элементы как объект... поэтому, если elements является массивом. Назначьте его так: this.elements = []; в вашем добавлении используйте this.elements.push({key:key,val:value});   -  person Brett Caswell    schedule 13.07.2014
comment
подождите .. вы пытаетесь раскрыть, назначить и перебрать свойства/члены экземпляра объекта myBag?   -  person Brett Caswell    schedule 13.07.2014
comment
Я хочу перебрать все свойства только одного свойства объекта myBag. Вдохновленный интерфейсом перечисления таких языков, как java.   -  person Shutterfly    schedule 13.07.2014
comment
Вы можете попробовать итератор (только для Firefox) или итератор ES6, но в настоящее время лучше всего перечислять myBag.elements.   -  person Bergi    schedule 13.07.2014


Ответы (2)


Вы можете добавить пары ключ/значение в сам экземпляр и создать метод как неперечислимый, например:

function Bag() {
}

Object.defineProperty(Bag.prototype, 'add', {
  enumerable: false,
  value: function(k, v) {
    this[k] = v
  }
})

var bag = new Bag
bag.add('a',1)
bag.add('b',2)
bag.add('c',3)

for (var k in bag)
  console.log(k)
//^ a
//  b
//  c

Обратите внимание, что вы также можете объявить метод как обычно и всегда зацикливаться с проверкой hasOwnProperty:

for (var k in bag)
  if (bag.hasOwnProperty(k))
    console.log(k)

Или другой вариант:

Object.keys(bag).forEach(function(k) {
  console.log(k)
})
person elclanrs    schedule 12.07.2014
comment
это интересно .. возможно, вы могли бы объединить этот ответ с jsfiddle.net/KooiInc/hg6dU, который упоминается в этом SO Q&A... stackoverflow.com/questions/5432967/ - person Brett Caswell; 13.07.2014
comment
хорошая идея, к сожалению, добавить нельзя;) если ни у кого нет лучшей идеи, я хочу использовать этот шаблон. - person Shutterfly; 13.07.2014

Как насчет чего-то вроде этого, пример forEach, но вы можете сделать map или filter или что-то еще.

Javascript

(function () {
    'use strict';

    function Bag() {
        this.elements = {};
    }

    Bag.prototype = {
        add: function (key, value) {
            this.elements[key] = value;
        },

        forEach: function (fn, thisArg) {
            Object.keys(this.elements).forEach(function (key) {
                fn.call(thisArg, this[key], key, this);
            }, this.elements);
        }
    };


    var myBag = new Bag();

    myBag.add('one', 1);
    myBag.add('two', 2);
    myBag.add('three', 3);

    myBag.forEach(function (item, key, object) {
        console.log(this, item, key, object);
    }, 'hello');
}());

Выход

hello 1 one Object {one: 1, two: 2, three: 3}
hello 2 two Object {one: 1, two: 2, three: 3}
hello 3 three Object {one: 1, two: 2, three: 3}

На jsFiddle

person Xotic750    schedule 12.07.2014