【问题标题】:Accessing a field by variable in array of JavaScript objects通过 JavaScript 对象数组中的变量访问字段
【发布时间】:2018-11-14 04:50:20
【问题描述】:

我在尝试访问存储在数组中的对象的各个字段时遇到了问题。

我有一个非统一对象数组,我们将调用 cache

var cache = new Array();

put 函数允许将项目添加到数组中。

function put(item, value) {
  cache[item] = value;
}

使用示例:

var item_abc = { item_a: 'some value', item_b: 'another value' };

put('ITEM_ABC',item_abc);

有问题的函数称为 update,它使用新的 更新数组中 itemfield >.

function update(item, field, value) {
  cache[item][field] = value;
}

麻烦的代码如下:

update('ITEM_ABC','item_a','a new value');

在浏览器中,这似乎可以正常工作,但在“--use_strict”Node.js 环境中,它会遇到问题。我假设这与优先级以及评估多维数组与对象字段的方式有关。

当对象本身存在于数组中时,如何在不知道字段名称的情况下在运行时引用对象字段?

从相关字段读取总是返回undefined

function check(item, field) {
  console.log(cache[item][field]);
  if (typeof cache[item][field] !== 'undefined')
    console.log('field exists');
  else
    console.log('field undefined');
}

跑步:

check('ITEM_ABC','item_a');

输出:

undefined
'field undefined'

【问题讨论】:

  • 您能告诉我们您在使用use strict 时遇到的错误吗?
  • 我在这个问题中没有看到任何 JSON。 JSON 是一种数据序列化格式。听起来您在谈论 JavaScript 对象。
  • 没有错误,但typeof cache[item][field]总是undefined
  • var cache = {}; 开头(JavaScript 没有关联数组。)
  • 如果你使用严格模式你不能有一个名为包的变量。

标签: javascript arrays node.js javascript-objects


【解决方案1】:

我建议简化 getput 函数。如果你想实现一个专门的update,它应该使用getput

const cache =
  {}

const get = (key) =>
  cache[key]

const put = (key, value) =>
  cache[key] = value

const update = (key, field, value) =>
  put ( key
      , { ... get (key) || {}, [field]: value }
      )

put ('foo', { a: 1 })

console.log (get ('foo')) // { a: 1 }

update ('foo', 'a', 2)

console.log (get ('foo')) // { a: 2 }

在上面,我们尽可能简单地编写函数。但也许更灵活的编写update 的方式是Object.assign,您可以在其中使用另一个对象更新一个对象

const cache =
  {}

const get = (key) =>
  cache[key]

const put = (key, value) =>
  cache[key] = value

const update = (key, obj) =>
  put ( key
      , Object.assign (get (key) || {}, obj)
      )
      
put ('foo', { a: 1, b: 2 })

console.log (get ('foo')) // { a: 1, b: 2 }

update ('foo', { a: 2, c: 2 })

console.log (get ('foo')) // { a: 2, b: 2, c: 2 }

如果要支持多个缓存,可以将getputupdate接口包装在另一个函数中。下面我们演示了与两个单独的缓存交互的能力,c1c2

const makeCache = () =>
{ const cache =
    {}

  const get = (key) =>
    cache[key]

  const put = (key, value) =>
    cache[key] = value

  const update = (key, obj) =>
    put ( key
        , Object.assign (get (key) || {}, obj)
        )
        
  return { get, put, update }
}
 
const c1 = makeCache ()
const c2 = makeCache ()

c1.put ('foo', { a: 1 })
c2.put ('foo', { a: 2 })

console.log (c1.get ('foo')) // { a: 1 }
console.log (c2.get ('foo')) // { a: 2 }

c1.update ('foo', { z: 3 })

console.log (c1.get ('foo')) // { a: 1, z: 3 }
console.log (c2.get ('foo')) // { a: 2 }

最后,为cache 使用对象{} 并不理想,因为key 总是在值关联之前转换为字符串。当我们像在原始代码中那样使用数组[] 时,也会出现同样的问题。观察当我们使用非原始值作为键时会发生什么......

const cache =
  {}

const get = (key) =>
  cache[key]

const put = (key, value) =>
  cache[key] = value

const update = (key, obj) =>
  put ( key
      , Object.assign (get (key) || {}, obj)
      )

const k1 = { foo: "bar" }
const k2 = { hello: "world" }

put (k1, 1)

console.log (get (k1)) // 1
console.log (get (k2)) // 1 ???

上面,即使我们从来没有为k2 提供put 的值,我们仍然可以get 一个值,因为k1k2 的字符串表示是相同的——每个都转换为[object Object]在存储值之前。下面,我们使用Map来避免这个问题

const cache =
  new Map

const get = (key) =>
  cache .get (key)

const put = (key, value) =>
  cache .set (key, value)

const update = (key, obj) =>
  put ( key
      , Object.assign (get (key) || {}, obj)
      )

const k1 = { foo: "bar" }
const k2 = { hello: "world" }

put (k1, 1)

console.log (get (k1)) // 1
console.log (get (k2)) // undefined

put (k2, 2)
   
console.log (get (k1)) // 1
console.log (get (k2)) // 2

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-01-26
    • 1970-01-01
    • 2016-05-18
    • 2013-10-11
    • 2019-09-07
    • 1970-01-01
    • 1970-01-01
    • 2017-07-27
    相关资源
    最近更新 更多