通过JavaScript对象数组中的变量访问字段

时间:2018-06-04 19:31:31

标签: javascript arrays node.js javascript-objects

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

我有一系列非统一对象,我们将调用 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 ,它使用新的值项字段 >

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'

1 个答案:

答案 0 :(得分: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 ???

上面,即使我们put没有k2值,我们仍然可以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