如何在私有对象上设置特定属性

时间:2011-12-07 19:52:43

标签: javascript object

我希望能够通过给出值的非符号路径来在私有对象上设置属性。困难在于此对象在闭包内,因此我无法直接访问它以正常方式设置值(例如。dot.notation.path = 'new value')。这看起来很奇怪,但我想不出明显的方式。

示例:

// setter function   
function set(path, change){
    var privateObject = {
      a: 'a',
      b: 'b',
      c: {
          d: 'd',
          e: 'e'
      }
    }

    privateObject[path] = change;
    return privateObject;
}

// execution
var result = set('c.d', 'new value'); 

// desired result
//{
//  a: "a"
//  b: "b"
//  c: {
//    d: "new value",
//    e: 'e'
//  }
//}

// actual result
//{
//  a: "a"
//  b: "b"
//  c: {
//    d: 'd',
//    e: 'e'
//  }
//  c.d: "new value"
//}

工作示例:

Failing JSFiddle Example >>

[更新]替代示例:

Working JSFiddle Example >>

2 个答案:

答案 0 :(得分:5)

你真的很接近,但括号表示法不会为你处理点(它不能 - 点是属性名称的完全有效字符)。你必须自己做:

function set(path, change){
  var privateObject = {
        a: 'a',
        b: 'b',
        c: {
            d: 'd',
            e: 'e'
        }
      },
      index,
      parts,
      obj;

  parts = path.split(".");
  obj = privateObject;
  if (parts.length) {
    index = 0;
    while (index < parts.length - 1) {
      obj = obj[parts[index++]];
    }
    obj[parts[index]] = change;
  }
  return privateObject;
}

Live demo

我把它打破了,它在旧引擎上并不高效,而且我没有费心去探索失败模式,但你明白了:拆分你在点上给出的路径,然后使用每个组件的一部分页面。

答案 1 :(得分:2)

这与私有对象或闭包没有任何关系,而且与

这一事实有很大关系
someObject['c.d']

不等于

someObject['c']['d']

someObject.c.d

您可以创建一些将path字符串拆分的构造。分隔符并迭代地应用索引操作符以实现期望的效果。

然而,整个练习似乎毫无意义。如果您从其作用域外部对私有对象执行任意更改,为什么不只是添加一个获取私有对象的机制并直接改变它?