javascript解压缩对象?

时间:2011-08-22 02:07:47

标签: javascript

来自clojure我需要编写一些javascript函数

假设我有一个函数作用于某些spec对象..我想在本地范围内引用spec中的变量,而不必编写spec.container,spec.nrow,spec.ncol。似乎没有原生支持解构,这是正确的吗?如果是这样 我如何编写如下的解包(深度1)函数? - 我真的不想在其中使用eval。

var spec = {container: {width: 900, height: 600}, nrow: 4, ncol: 5, vgap: "5px"}

function grid(spec) {
   // bad..
   var width = spec.container.width;
   var height = spec.container.height;
   var nrow = spec.nrow;
   etc...

   // I would prefer to write this, then have local access to nrow, width, height, etc
   unpack(spec);
   unpack(container);
}

由于

4 个答案:

答案 0 :(得分:2)

您可以使用以下方法执行所需操作:

var spec = {container: {width: 900, height: 600}, nrow: 4, ncol: 5, vgap: "5px"}

function grid(obj) {
    // I would prefer to write this, then have local access to nrow, width, height, etc
    unpack(obj, this);
    unpack(container, this);

    //do stuff here...
}

function unpack(obj, dest) {
    for (var key in obj) {
        dest[key] = obj[key];
    }
}

以下是一个工作示例:http://jsfiddle.net/Dsaaw/

答案 1 :(得分:1)

with() { }构造是为此设计的,但它被广泛认为是危险的语言元素,因为范围冲突的规则没有明确定义。

我要么说要么使用完全限定的对象引用,要么使用逐一分配。

答案 2 :(得分:1)

我是Coffeescript的忠实粉丝,它具有“本机”解构分配,因为它编译为等效的JavaScript。我不认为有一个非常优雅的解决方案是严格纯粹的JS。 CS看起来像这样

{ nrow, container: { width, height } } = spec

编译时产生的JavaScript将是:

var height, nrow, width, _ref;
nrow = spec.nrow, _ref = spec.container, width = _ref.width, height = _ref.height;

aroth 的解决方案很简洁,实际上我会提出建议,但我认为你存在范围问题的风险。值得一试。

答案 3 :(得分:0)

如果你想用你的另一个对象扩展this,那么aroth的解决方案是非常好的,特别是对于RobG的评论,但只是确保你知道你正在扩展什么对象。对于深层嵌套的函数(其父级不是window),您必须说this.width而不是spec.width,因此在键入方面对您没有多大帮助。或者你无法传递this而只是在window上创建全局变量(这基本上是正在发生的事情),这可能证明了为什么这种方法可能是危险的。

如果你想在函数中使用本地范围的变量,那么我认为你几乎不得不使用eval。

function decomp(obj) {
    var result = []
    for(var i in obj) {
        switch(typeof(obj[i])) {
            case "number":
            case "boolean":
            case "string":
            result.push("var "+i+"="+obj[i].constructor.name+"(\""+obj[i].valueOf()+"\");")
        }
    }

    return result.join('');
}

var someObject = {
    worker: function(obj) {
        eval(decomp(obj));
        eval(decomp(obj.container));

        alert(width);
    }
}

var spec = {container: {width: 900, height: 600}, nrow: 4, ncol: 5, vgap: "5px", test: true }

someObject.worker(spec)

在这里玩here

我知道你说过你不想使用eval()但是我想不出任何其他方法来真正做你想做的事。它位于eval()之间,扩展this(可能是或不是window),或者编写一个为您展开它的js预处理器。