#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
является простым объектом (без пользовательского прототипа), он не унаследует никаких перечислимых свойств.