Javascript, который зацикливает и сохраняет ключи как переменные и выводит дополнительные поля из сохраненных ключей?

#javascript #underscore.js

#javascript #underscore.js

Вопрос:

Я новичок в JS и кодировании в целом, поэтому я не уверен, как эффективно написать функцию для этого. Я хочу написать функцию, которая принимает объект в качестве аргумента и возвращает другой объект.

 OrderFormContents = {
    servicesSelected: {
        hdrPhotos: "selected",
        panos: "selected",
        twilightPhotos: "selected"
    }
}
 

hdrPhotos , panos , и twilightPhotos все артикулы / уникальные идентификаторы.

Я хочу вернуть объект, подобный подобному:

 CompletedOrderFormContents = {
    servicesSelected: {
        hdrPhotos: {
            sku: "hdrPhotos",
            calculatedPrice: 100, // returned from an object stored as a Session variable called calculatedPrices
            title: "HDR Photography" //returned from looking up the sku from a Services collection.
        },
        panos: {
            sku: "panos",
            calculatedPrice: 125,
            title: "Panoramas"
        },
        twilightPhotos: {
            sku: "twilightPhotos",
            calculatedPrice: 200,
            title: "Twilight Photography"
        }
    }
}
 

До сих пор я грубо форсировал это, явно определяя все артикулы, и это глупо:

 var myFunction = function(OrderFormContents) {

    CompletedOrderFormContents = {
        servicesSelected: ""
    };

    CompletedOrderFormContents.servicesSelected.hdrPhotos = {
        sku: "hdrPhotos",
        calculatedPrice: Session.get("calculatedPrices").hdrPhotos,
        title: Services.find({"sku" : "hdrPhotos"}).fetch()[0].title
    };

    CompletedOrderFormContents.servicesSelected.panos = {
        sku: "panos",
        calculatedPrice: Session.get("calculatedPrices").panos,
        title: Services.find({"sku" : "panos"}).fetch()[0].title
    };

    CompletedOrderFormContents.servicesSelected.twilightPhotos = {
        sku: "twilightPhotos",
        calculatedPrice: Session.get("calculatedPrices").twilightPhotos,
        title: Services.find({"sku" : "twilightPhotos"}).fetch()[0].title
    };

};
 

Как бы я реорганизовал этот код, чтобы я, по крайней мере, явно не определял SKU для каждого оператора и явно определял каждый оператор для каждого SKU? У меня установлен UnderscoreJS.

РЕДАКТИРОВАНИЕ Заставило его работать.

 completedOrderFormContents = {
  servicesSelected: {}
};

for (sku in OrderFormContents.servicesSelected) {
  if (OrderFormContents.servicesSelected.hasOwnProperty(sku)) {
    completedOrderFormContents.servicesSelected[sku] = {
      sku: sku,
      price: Session.get("calculatedPrices")[sku],
      title: Services.find( { "sku" : sku }).fetch()[0].title
    }
  }
}
 

Комментарии:

1. Вы хотите узнать о базовом for in цикле . Не используйте подчеркивание, пока не узнаете это.

2. @Bergi, я добавил свою попытку, используя for... in , но одна часть не работает.

3. Мой совет — провести рефакторинг с использованием массивов вместо объектов. ИМХО, с ними (в большинстве случаев) намного проще обращаться и они поставляются с порядком (ключи объектов не имеют определенного порядка), что иногда может быть весьма удобно. Вместо этого у меня было бы это { servicesSelected : ['hdrPhotos','panos', 'twilightPhotos'] } . Мое правило таково: если что-то представляет собой список / перечисление / коллекцию вещей, всегда используйте массив. Объект предназначен для чего-то, описывающего одну вещь (например, что-то, что находится В списке). И когда у вас есть массив, в который входит сила подчеркивания, и вы можете очень легко выбирать из него что-то.

4. Мммм … массив не подойдет servicesSelected , потому что в корзине покупок нет заказа, а услуги в корзине все равно не перечислены. Например, в одном случае servicesSelected это было бы { servicesSelected: {'hdrPhotos','panos','twilightPhotos'} } , тогда как в другом случае это было бы { servicesSelected: {'twilightPhotos','panos'} }

Ответ №1:

У меня это работает.

 //servicesSelected does not currently exist in completedOrderFormContents, 
//so gotta create it - ie. simply doing completedOrderFormContents = {} would not work 
//because the for loop is going to try and assign something to .servicesSelected
//later on and it needs that .servicesSelected key to already be there 

completedOrderFormContents = {
  servicesSelected: {}
};

for (sku in OrderFormContents.servicesSelected) {
  if (OrderFormContents.servicesSelected.hasOwnProperty(sku)) {
    completedOrderFormContents.servicesSelected[sku] = {
      sku: sku,
      price: Session.get("calculatedPrices")[sku],
      title: Services.find( { "sku" : sku }).fetch()[0].title
    }
  }
}
 

Комментарии:

1. Хорошо! Хотя оператор if .hasOwnProperty() тестом обычно не требуется.

2. @Bergi Правда? Разве не нужно гарантировать, что дополнительные хэши не будут добавлены из прототипа объекта или что-то в этом роде?

3. Поскольку your OrderFormContents.servicesSelected является простым объектом (без пользовательского прототипа), он не унаследует никаких перечислимых свойств.