当前位置: 首页 > 面试题库 >

在没有eval的情况下使用字符串键访问或创建嵌套的JavaScript对象

辛盛
2023-03-14
问题内容

我正在寻找一种通过字符串值访问属性的好的解决方案,但是如果该属性不存在,则应该创建它。如果根结构已经定义了结构的某些部分,则属性不应被覆盖,而应合并。

例如,如果您有一个空对象,test并且想要设置一个深层结构而不使用eval。例如

test = {}
test.foo.name = "Hallo" // <<- foo is an Object
test.foo[3] = "Test" // <<- foo should remain as Object, not as Array 
test.foo.data[3].bar = 100 // <<- should not overwrite test.foo.name

我写了一个切实可行的解决方案,但是我猜这是很糟糕的代码:

也可以作为jsfiddle使用:https
://jsfiddle.net/gvaLzqqf/4/

Object.setValue = function(node, flatKey, value) {
    flatKey = flatKey.replace("[", ".");
    flatKey = flatKey.replace("]", "");
    var parts = flatKey.split(".")
    var oldNode = node
    parts.forEach(function(key, index) {
      if (/^\+?(0|[1-9]\d*)$/.test(key)) {
        key = key * 1
        if (index > 0) {
          var oldValue = parts[index - 1]
          if (!Array.isArray(oldNode[oldValue])) {
            oldNode[oldValue] = []
            node = oldNode[oldValue]
          }
        }
      }
      if (node[key] == undefined) {
        node[key] = {}
      }
      oldNode = node
      node = node[key]
    }); // for each
    oldNode[parts[parts.length - 1]] = value
    return oldNode[parts[parts.length - 1]]
  } // function

var test = {}
Object.setValue(test, "foo.name", "Mr. Foo")
Object.setValue(test, "foo.data[0].bar", 100)
Object.setValue(test, "and.another[2].deep", 20)

console.log("test = " + JSON.stringify(test))
console.log("test.foo.data[0].bar = " + test.foo.data[0].bar)

但是,有没有更好的方法来实现这一目标?


问题答案:

您可以拆分路径并通过遍历给定的对象来缩小路径。如果不存在对象,请使用名称或数组创建一个新属性。稍后分配值。

function setValue(object, path, value) {

    var way = path.replace(/\[/g, '.').replace(/\]/g, '').split('.'),

        last = way.pop();



    way.reduce(function (o, k, i, kk) {

        return o[k] = o[k] || (isFinite(i + 1 in kk ? kk[i + 1] : last) ? [] : {});

    }, object)[last] = value;

}



var test = {};

setValue(test, "foo.name", "Mr. Foo");

setValue(test, "foo.data[0].bar", 100);

setValue(test, "and.another[2].deep", 20);

console.log(test);


 类似资料:
  • 问题内容: 我正在使用Hibernate 4.0.1.Final。如果该对象已通过org.hibernate.Session.load(Class clazz,Serializable id)方法加载并且没有活动的会话,是否可以访问该对象的字段? 我使用此代码通过id访问对象… 但是如果我的对象没有活动的会话,例如这段代码…… 我在“ System.out”行上收到此错误… 问题答案: 使用代替

  • 问题内容: 我有一个像这样的数据结构: 我想使用这些变量访问数据: part1name应该用的值(即“第1部分”)填充。part2quantity填充60。 无论如何,可以使用纯JavaScript或JQuery来实现这一目标? 问题答案: 我只是根据已经拥有的一些类似代码制作的,它似乎可以工作: 用法:: 编辑一些人已经注意到,如果传递的字符串最左边的索引与对象内正确嵌套的条目不对应,则此代码将

  • 问题内容: 我有一个模型,当从前端发送请求时,我可以在控制器中使用@Valid进行验证: 但是现在,我还使用不含控制器的Jackson的ObjectMapper创建了一个对象。有没有一种方法可以在ObjectMapper中注册此验证,还是应该只检查setter中的变量? 问题答案: 反序列化后,您可以扩展和验证对象。要注册此bean使用。 具有验证的简单bean反序列化器: 我们可以如下使用它:

  • 问题内容: 我试图将配置(例如URLs / etc)放入资源文件夹中,以供实用程序类使用。但是,我不想从任何地方的活动中传递上下文。我希望能够通过路径名(似乎使用assess /是为此用途设计的)来访问资源,而无需使用上下文来访问资源。 在这种特殊情况下,我希望单例实例化时在配置中使用某些东西。除了实例化期间的那一次之外,它不需要任何资源。因此,每次调用getInstance()时都必须传递Con

  • 问题内容: 我可以在没有jQuery的情况下访问数据属性吗? 使用jQuery很容易,但是如果没有jQuery,我在任何地方都看不到该怎么做。 如果我在Google上搜索“没有jQuery”,那么我得到的只是jQuery示例。 可能吗 问题答案: 在这里,我找到了这个例子: 因此,它看起来非常可行。

  • 问题内容: 我最近问了这个问题,答案使我加深了理解,但他们并没有解决我遇到的实际问题。因此,我将尝试如下提出类似但不同的问题。 假设我要访问的随机元素。一种方法是: 如果我想多次调用该函数怎么办?我猜我在寻找什么,就像是一个运算符/函数(返回),该函数将元素放在第-th个位置。为什么可以使用但不能通过例如这样的功能来访问此元素? 问题答案: Go中的值存储文本的UTF-8编码字节序列。这是已经做出