javascript解包对象?
来自clojure,我需要编写一些javascript函数 假设我有一个作用于某个spec对象的函数。。我希望在本地范围内引用spec中的变量,而不必编写spec.container、spec.nrow、spec.ncol。似乎本机不支持解构,对吗?如果是的话 如何编写如下所示的解包(深度1)函数我也不想在其中使用evaljavascript解包对象?,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
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中