【问题标题】:Dynamically access object propertys (JS) [duplicate]动态访问对象属性(JS)[重复]
【发布时间】:2014-10-08 00:22:47
【问题描述】:

我正在尝试使用字符串动态访问对象的属性。 例如: ".id.public" -> anyObject["id"]["public"]

问题 - 我不知道我有多少参数(例如“.id”或“.id.public”或“.id.public.whatever”。

我做了一些解决方法:

var currentSplit = anyObject;
var splitted = "id.public".split("\.");
splitted.forEach(function(s) { currentSplit = currentSplit[s]; });

当我现在尝试覆盖对象属性时,我将覆盖引用而不是对象属性。

currentSplit = "test";

我已经尝试过anyObject["id.public"] = "test"; 之类的东西,但没有奏效。

【问题讨论】:

  • 您无法在 javascript 中使用字符串访问嵌套对象属性,您需要某种辅助函数来为您完成此操作,您可以查看 angulars $parse 接口以获得一些灵感。跨度>
  • 两个共享相同值的变量并不意味着您可以通过分配一个变量来更改这两个变量。您打算在“id.public”读取一个值,还是在“id.public”写入一个值? this answer 对你有用吗?

标签: javascript


【解决方案1】:

deep-get-set 库可以满足您的需求:

function get (obj, path) {
  var keys = path.split('.');
  for (var i = 0; i < keys.length; i++) {
    var key = keys[i];
    if (!obj || !hasOwnProperty.call(obj, key)) {
      obj = undefined;
      break;
    }
    obj = obj[key];
  }
  return obj;
}

function set (obj, path, value) {
  var keys = path.split('.');
  for (var i = 0; i < keys.length - 1; i++) {
    var key = keys[i];
    if (deep.p && !hasOwnProperty.call(obj, key)) obj[key] = {};
    obj = obj[key];
  }
  obj[keys[i]] = value;
  return value;
}

【讨论】:

  • 就我个人而言,我会避免使用getset 这两个名称,因为它们本身可以是运算符;但否则这看起来不错
  • 我也一样,我只是从库中复制了代码,其中setget 是本地定义的,没有公开。
  • 我认为我的解决方案更好,它在一个超快的函数中完成,而且功能更多,它甚至可以执行一个方法并遍历该方法返回的任何对象,一个小程序更智能盒子!
【解决方案2】:

另一种设置值的方法

function setVal(obj, path, val){
    var paths = path.split('.'),
        curProp = obj;

    for(var i=0;i<paths.length-1;i++){
        curProp = curProp[paths[i]];
    }
    curProp[paths[i]] = val;

}

并像使用它

setVal(anyObj, "id.public", 'newValue');

【讨论】:

    【解决方案3】:

    如果没有这样的小代码,您将无法做到这一点:

     var mapToProperty = function(obj, path, value) {
            if (!path) return obj;
    
            var parts = path.split("."),
               p = parts[0],
               v = (typeof obj[p] === "function") ? obj[p](value) : (parts.length !==1 || !value) ? obj[p] : (obj[p] = value), value ;
               if (parts.length == 1) return v;
                   return mapToProperty(v, parts.slice(1).join("."), value);
    }
    
    // use it like this
    
    var myvalue = mapToProperty(myObj, "address.street")
    
    // you can map into your objects as far as you want. obj1.obj2.obj3.prop
    
    // you can set as well :-)
    
    mapToProperty(myObj, "address.street", "This is great!")
    

    【讨论】:

    • ReferenceError: func is not defined,还有,它在哪里设置value
    • 这个函数也将执行方法——例如传递一个对象,该对象的方法计算结果为 obj1.method()
    • 抱歉,从我的库中复制错过了那个错误,已修复。
    • 按参数传入,obj, stringmap, value
    • 好的,对不起,这设置了方法,这是我想要修改的方式,以便在传递值时设置属性给我 5!
    猜你喜欢
    • 2011-08-10
    • 2014-10-11
    • 2013-07-21
    • 1970-01-01
    • 1970-01-01
    • 2011-06-15
    • 2019-01-29
    • 1970-01-01
    相关资源
    最近更新 更多