直接设置deep 属性的方法

Way to set deep property directly

我想设置一个变量 user.Whosebug.name,这正是我想要用来创建它的。我可以用完整变量创建一个深度 属性 吗?我知道一个 npm module dotty 允许你用这样的字符串设置一个深度 属性。

dotty.put(user, "Whosebug.name", "thomas")

我真的很想能够像这样设置一个深度 属性。

user.Whosebug.name = "thomas"

createDeep(user.Whosebug.name, "thomas")

并在必要时创建嵌套对象。

这可能吗?

这适用于全局变量:

function createDeep(name, value) {
  var current = window;
  var fields = name.split('.');
  var suffix = fields[fields.length-1];
  for (var i = 0; i < fields.length-1; i++) {
    var curfield = fields[i];
    if (!(curfield in current)) {
      current[curfield] = {};
    }
    current = current[curfield];
  }
  current[suffix] = value;
  }

createDeep('user.Whosebug.name', 'thomas');
alert(user.Whosebug.name);

如果 user 是局部变量,则无法执行此操作,因为无法通过名称访问局部变量。全局变量是 window 对象的属性。

我稍微编辑了@Barmar 的代码。这将适用于局部变量:

function setPropertyValue(object, propertyPath, value) {  
  var properties = propertyPath.split('.');
  var currentObject = object;
  var length = properties.length;
  var lastProperty = properties[length-1];

  for (var i = 0; i < length-1; i++)
  {
    var property = properties[i];
    if(!(property in currentObject))
    {
      currentObject[property] = {};
    }
    
    currentObject = currentObject[property];
  }

  currentObject[lastProperty] = value;
}


(function(){
  var user = {};
  setPropertyValue(user, "Whosebug.name", "thomas");

  alert(user.Whosebug.name);

})();

您可以使用几乎与使用 ES6 的语法相同的语法Proxy像这样的东西应该可以解决问题。

function deep(obj) {
  const has = ({}).hasOwnProperty.bind(obj);

  return Proxy.create({
    get: function(_, name) {
      return deep(has(name) ? obj[name]: (obj[name] = {}));
    },
    set: function(_, name, value) {
      obj[name] = value;
    }
  })
}

var user = {};

deep(user).Whosebug.name = 'test';

deep(user).Whosebug.site.url = 'http';

console.log(user);

但您需要 --harmony-proxies 标志才能打开。

node --harmony-proxies index.js