javascript解包对象?

javascript解包对象?,javascript,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"} funct

来自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);
}
感谢带(){}的
构造就是为此而设计的,但是它被广泛认为是一个危险的语言元素,因为范围冲突的规则没有很好的定义

我会说要么使用完全限定的对象引用,要么使用逐个赋值。

带(){}
构造就是为此而设计的,但它被广泛认为是一个危险的语言元素,因为范围冲突的规则没有很好的定义


我会说,要么使用完全限定对象引用,要么接受一个接一个的赋值。

您可以使用以下命令执行您想要的操作:

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];
    }
}

下面是一个工作示例:

您可以使用以下方法执行您想要的操作:

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];
    }
}
下面是一个工作示例:

我非常喜欢它,它有“本机”的解构任务,因为它编译成等效的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的解决方案很简洁,实际上,我打算提出建议,但我认为您可能会遇到范围问题。不过值得一试。

我非常喜欢它,它有“本机”的解构任务,因为它可以编译成等价的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的解决方案很简洁,实际上,我打算提出建议,但我认为您可能会遇到范围问题。不过值得一试。

如果你想用你的另一个对象扩展
这个
,那么aroth的解决方案是很好的,特别是RobG的评论,但是只要确保你知道你要扩展的对象就行了。对于深度嵌套的函数(其父函数不是
window
),您必须说
this.width
,而不是
spec.width
,这样在键入方面对您帮助不大。或者,您不能传入
这个
,而只是在
窗口中生成全局变量(这基本上就是正在发生的事情),这可能会说明为什么这种方法可能是危险的

如果您希望函数使用局部作用域变量,那么我认为您几乎必须使用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)
在这里玩吧


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

如果您想用其他对象扩展
this
,那么aroth的解决方案是很好的,特别是在RobG的评论中,但只要确保您知道要扩展的对象。对于深度嵌套的函数(其父函数不是
window
),您必须说
this.width
,而不是
spec.width
,这样在键入方面对您帮助不大。或者,您不能传入
这个
,而只是在
窗口中生成全局变量(这基本上就是正在发生的事情),这可能会说明为什么这种方法可能是危险的

如果您希望函数使用局部作用域变量,那么我认为您几乎必须使用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)
在这里玩吧


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

您必须使用hasOwnProperty。不必,可以。如果要从解包步骤中排除继承的属性,可以使用
hasOwnProperty
。这取决于具体的用例,可能需要也可能不需要。类似地,您可能还需要检查目标上下文,以确保您没有覆盖以前在那里定义的任何内容。如果
==
窗口
要知道您正在设置什么,则可能需要担心它。您必须使用hasOwnProperty。不必,may。如果要从解包步骤中排除继承的属性,可以使用
hasOwnProperty
。这取决于具体的用例,可能需要也可能不需要。类似地,您可能还需要检查目标上下文,以确保您没有覆盖以前在那里定义的任何内容。如果
==
窗口了解您正在设置的内容,则最好对此有所担心。此外,在ES5严格模式下,with不可用。这一点很好。和ES5=EcmaScript v5(JavaScript的正确名称),用于那些不符合该首字母缩略词的用户。此外,在ES5严格模式下,with不可用。这一点很好。和ES5=EcmaScript v5(JavaScript的正确名称)的缩写。谢谢,我会研究coffeescript-但我要针对google闭包编译器,这意味着纯js@ChrisR为什么不编译成JS然后运行闭包编译器呢?谢谢,我会研究coffeescript,但我会针对google闭包编译器,这意味着纯js@ChrisR为什么不编译到JS,然后通过闭包编译器运行呢?销毁分配在ECMAScript 6草稿中,目前仅在Firefox和Safari中支持:销毁分配在EC中