【问题标题】:Convert a JavaScript string in dot notation into an object reference将点表示法的 JavaScript 字符串转换为对象引用
【发布时间】:2011-09-17 15:31:57
【问题描述】:

给定一个 JavaScript 对象,

var obj = { a: { b: '1', c: '2' } }

还有一个字符串

"a.b"

如何将字符串转换为点表示法以便我可以去

var val = obj.a.b

如果字符串只是'a',我可以使用obj[a]。但这更复杂。我想有一些直截了当的方法,但目前我没有想到。

【问题讨论】:

  • @Andrey eval 是邪恶的;不要使用它
  • 仅供参考:以下是我刚刚进行的一些有趣的速度测试:jsperf.com/dereference-object-property-path-from-string
  • 如果 perf 是一个严肃的考虑因素,并且您经常重复使用相同的路径(例如,在数组过滤器函数中),请使用下面我的回答中描述的 Function 构造函数。当同一路径被使用数千次时,Function 方法的速度可以比每次取消引用时评估或拆分和减少路径的速度快 10 倍以上。
  • 在某些情况下,您必须使用 eval 或 new Function(),尤其是当您想从模板创建函数时,就像将 JSP 页面转换为 JAVA 一样,不是一种更有效的模板制作方法,这个 eval 是邪恶的教条,这只是一个教条,什么是邪恶的是评估你没有自己创建的脚本,当然在这种精确的情况下没有理由使用评估

标签: javascript


【解决方案1】:

如果您想以最快的方式执行此操作,同时处理路径解析或属性解析的任何问题,请查看path-value

const {resolveValue} = require('path-value');

const value = resolveValue(obj, 'a.b.c');

该库是 100% TypeScript,适用于 NodeJS + 所有 Web 浏览器。而且它是完全可扩展的,您可以使用较低级别的resolvePath,并根据需要以自己的方式处理错误。

const {resolvePath} = require('path-value');

const res = resolvePath(obj, 'a.b.c'); //=> low-level parsing result descriptor

【讨论】:

    【解决方案2】:

    想把这个放在那里:

    function propertyByPath(object, path = '') {
        if (/[,(){}&|;]/.test(path)) {
            throw 'forbidden characters in path';
        }
        return Function(
          ...Object.keys(window).filter(k => window[k] instanceof Window || window[k] instanceof Document),
          "obj",
          `return ((o) => o${!path.startsWith('[') ? '.' : ''}${path})(...arguments, obj);`)
        .bind(object)(object);
    }
    propertyByPath({ a: { b: 'hello1' } }, "a.b"); // prints 'hello1'
    propertyByPath({ a: { b: 'hello2' } }, "['a']?.b"); // returns 'hello2'
    propertyByPath({ a: { b: 'hello2' } }, "a.b;console.log()"); // throws exception
    

    上面的代码评估路径,同时努力阻止代码执行,同时进行路径评估并屏蔽 Window 和 Document 对象,如果以某种方式阻止执行没有成功。

    我并不是说它是 100% 安全的(尽管我希望看到 cmets 建议可能的绕过)也不是有效的,但它可能适用于路径的灵活性(可选链等)以及需要一些缓解措施。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-05
      • 2020-01-16
      • 1970-01-01
      相关资源
      最近更新 更多