在对象中按名称查找嵌套 属性 的最佳方法

Best way to find nested property by name in object

我有一个对象 (dataLayer),它的长度可以增加和减少,具体取决于您访问了多少页。

我想:

显然,我可以 dataLayer['4'].ecommerce.information. product。但是,我遇到的问题是这个 key/value 位置可以是任意数字。 EG数据层[0]、[1]、[2]、[12]等

无论它在对象中的索引如何,遍历此对象并查找此 key/value 对的最佳方法是什么?

const dataLayer = 
  { 0: { a: 123, event: 'pageload', productId: 1 } 
  , 1: { b: 456, event: 'pageload', productId: 3 } 
  , 2: {         event: 'gtm.load', productId: 3 } 
  , 3: {         event: 'gtm.load', productId: 4 } 
  , 4: 
    { pagetitle: 'Login Page'
    , ecommerce: 
      { information: 
        { product: 
          [ { brandCode: 'car', productColor: 'red' } 
          , { brandCode: 'car', productColor: 'green' } 
          , { brandCode: 'car', productColor: 'yello' } 
          ]   
  } } } };

谢谢,

这种方式 for( of ) 和 for( in )

const dataLayer = 
  { 0: { a: 123, event: 'pageload', productId: 1 } 
  , 1: { b: 456, event: 'pageload', productId: 3 } 
  , 2: {         event: 'gtm.load', productId: 3 } 
  , 3: {         event: 'gtm.load', productId: 4 } 
  , 4: 
    { pagetitle: 'Login Page' , fx:false, trduc: { madchin: 'bidule'}
    , ecommerce: 
      { information: 
        { product: 
          [ { brandCode: 'car', productColor: 'red'   } 
          , { brandCode: 'car', productColor: 'green' } 
          , { brandCode: 'car', productColor: 'yello' } 
          ]   
  } } } }
  ;
for (let key in dataLayer) // key value are '0','1',...,'4'
  {
  if ( 'ecommerce' in dataLayer[key]
    && dataLayer[key]?.pagetitle==='Login Page'
    ) {
    for (let prod of dataLayer[key].ecommerce.information.product)
      {
      console.log( prod.brandCode, prod.productColor )
  } } }
.as-console-wrapper { max-height: 100% !important; top: 0; }

[编辑]

我在 pagetitle==='Login Page' 上添加了验证,请参阅 Optional chaining (?.)
并更正了 ecommerce 属性 是否存在的测试 参见 in operator

要从 "Login Page"

中检索一组品牌代码

const dataLayer = {
  0: {event: 'pageload', productId: 1, a: 123},
  1: {event: 'pageload', productId: 3, b: 456},
  2: {event: 'gtm.load', productId: 3},
  3: {event: 'gtm.load', productId: 4},
  4: {
    pagetitle: 'Login Page',
    ecommerce: {
      information: {
        product: [
          {brandCode: 'car', productColor: 'red'},
          {brandCode: 'truck', productColor: 'green'},
          {brandCode: 'bike', productColor: 'yello'},
        ]
      }
    }
  },
  17: {
    pagetitle: 'Login Page',
    ecommerce: {
      information: {
        product: [
          {brandCode: 'cow', productColor: 'lila'},
        ]
      }
    }
  }
};


function getEcommerceBrandCodes(pagetitle, data) {
  return Object.entries(data).reduce((a, [k, ob]) => {
    const isPagetitle = ob.hasOwnProperty("pagetitle") && ob.pagetitle === pagetitle;
    const isEcommerce = ob.hasOwnProperty("ecommerce");
    if (isPagetitle && isEcommerce) {
      a.push(ob.ecommerce.information?.product?.map(item => item.brandCode));
    }
    return a;
  }, []).flat();
}

console.log(getEcommerceBrandCodes("Login Page", dataLayer));

谢谢大家,非常感谢帮助!看到这两个选项非常有帮助,并且会同时使用它们:)

我也试图找到自己的解决方案。仅供参考,如果这对将来的任何人都有帮助:

(我不得不去掉 ES6,因为我使用的工具只允许 ES5)。但是有了这个解决方案,我可以将 ecommerce.information 的最后一个 entry/update 添加到数据层,方法是将它添加到一个新数组中,然后对最后一个条目进行切片。

var productArray = [];

for (var i = 0; i < dataLayer.length; i++) {
    if (dataLayer[i].ecommerce) {
        for (var line in dataLayer[i].ecommerce.information) {
            var itemProducts = dataLayer[i].ecommerce.information;
            productArray.push(itemProducts);
        };
    };
};

var lastItem = productArray.slice(-1);

if (lastItem[0].product[0].brandCode === "car") {
    //do something
} else {
    //do something
}

Roko C. Buljan 的解决方案也很有帮助,因为它独立于 pagetitle,我也将使用它。

谢谢大家!