108

好的,所以我正在处理节点中的一个项目,并且我遇到了对象文字中的键的一个小问题,我有以下设置:

var required = {
    directories : {
        this.applicationPath                    : "Application " + this.application + " does not exists",
        this.applicationPath + "/configs"       : "Application config folder does not exists",
        this.applicationPath + "/controllers"   : "Application controllers folder does not exists",
        this.applicationPath + "/public"        : "Application public folder does not exists",
        this.applicationPath + "/views"         : "Application views folder does not exists"
    },
    files : {
        this.applicationPath + "/init.js"               : "Application init.js file does not exists",
        this.applicationPath + "/controllers/index.js"  : "Application index.js controller file does not exists",
        this.applicationPath + "/configs/application.js": "Application configs/application.js file does not exists",
        this.applicationPath + "/configs/server.js"     : "Application configs/server.js file does not exists"
    }
}

好吧,你们中的很多人会看到这个并认为它看起来不错,但是编译器一直告诉我我缺少一个:(冒号),我没有,看起来+or 和 the.都影响了编译器。

现在我相信(不确定),对象文字是在编译时创建的,而不是在运行时创建的,这意味着动态变量(如this.applicationPath和连接)将不可用:( :(

在不必重写大量代码的情况下克服这样的障碍的最佳方法是什么。

4

8 回答 8

194

ECMAScript2015 支持计算属性名称:

var name = 'key';
var value = 'value';
var o = {
  [name]: value
};
alert("o as json : " + JSON.stringify(o));

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer

于 2016-08-04T18:01:36.450 回答
109

在 ECMAScript 2015(第 6 版)之前,对象字面量(ECMAScript 将其称为“对象初始化器”)键必须是以下之一:

  1. 标识符名称
  2. 字符串字面量
  3. 数字字面量

因此,您不能使用表达式作为初始化程序中的键。自 ECMAScript 2015 起,这已更改(见下文)。您可以使用带有方括号符号的表达式来访问属性,因此要使用您必须执行的表达式来设置属性:

var required = { directories : {}};
required.directories[this.applicationPath] = "Application " + this.application + " does not exists";
required.directories[this.applicationPath + "/configs"] = "Application config folder does not exists";
...

等等。由于this.applicationPath被重用了很多,最好存储一个引用以帮助提高性能并减少代码量:

var a = this.applicationPath;
var required = { directories : {}};
var rd = required.directories;
rd[a] = "Application " + this.application + " does not exists";
rd[a + "/configs"] = "Application config folder does not exists";
...

编辑

从 ECMAScript 2015(ed 6)开始,对象初始化器可以使用以下计算键:

[expression]: value

还有属性和方法名称的简写语法。

请参阅MDN:对象初始化器ECMAScript 对象初始化器

于 2011-06-28T01:29:22.777 回答
46

您可以使用括号表示法设置动态键:

required.directories[this.applicationPath + "/configs"] = "Application config folder does not exists";

(当然无论你在哪里做这个定义,都this.applicationPath必须存在)

但是你需要this.applicationPath钥匙吗?您如何访问这些值?也许您可以this.applicationPath从用于访问属性的任何值中删除。


但如果你需要它:

如果要避免重复大量代码,可以使用数组来初始化键:

var dirs = ['configs', 'controllers', ...];
var files = ['init.js', 'controllers/index.js', ...];

var required = { directories: {}, files: {} };
required.directories[this.applicationPath] = "Application " + this.application + " does not exists";

for(var i = dirs.length; i--;) {
    required.directories[this.applicationPath + '/' + dirs[i]] = "Application " + dirs[i] + " folder does not exists";
}

for(var i = files.length; i--;) {
    // same here
}
于 2011-06-28T01:27:07.990 回答
8

babel{[expression]: value}如何将新的 ES6 语法(

var obj = (_obj = {}, _obj[expression] = value, _obj);

例子:

var dynamic_key = "hello";
var value = "world";
var obj = (_obj = {}, _obj[dynamic_key] = value, _obj);

console.log(obj);
// Object {hello: "world"}

(在最新的 Chrome 上测试)

于 2016-02-28T16:40:08.157 回答
3

如果你有一个很深的对象结构(例如 Grunt 配置),有时可以很方便地使用Felix概述的括号表示法返回动态生成的对象键,但内联在对象结构中。这可以通过使用函数在深层对象的上下文中动态返回对象来实现;在这个问题中的代码的情况下,是这样的:

var required = {
    directories : function() {
        var o = {};
        o[this.applicationPath] = "Application " + this.application + " does not exists";
        o[this.applicationPath + "/configs"] = "Application config folder does not exists";
        o[this.applicationPath + "/controllers"] = "Application controllers folder does not exists";
        o[this.applicationPath + "/public"] = "Application public folder does not exists";
        o[this.applicationPath + "/views"] = "Application views folder does not exists";
        return o;
    }(),
    files : function() {
        var o = {};
        o[this.applicationPath + "/init.js"] = "Application init.js file does not exists";
        o[this.applicationPath + "/controllers/index.js"]  = "Application index.js controller file does not exists";
        o[this.applicationPath + "/configs/application.js"] ="Application configs/application.js file does not exists";
        o[this.applicationPath + "/configs/server.js"]     ="Application configs/server.js file does not exists";
        return o;
    }()
}

这个小提琴验证了这种方法。

于 2014-12-18T13:53:07.723 回答
3

一个老问题,当时的答案是正确的,但时代变了。如果有人在谷歌搜索中挖掘它,新的 javascript 版本 (ES6) 允许使用表达式作为对象文字的键,如果它们被方括号括起来: var obj={["a"+Math.PI]:42}

于 2016-06-10T19:52:22.450 回答
2

对于对象文字,Javascript/ECMAScript 脚本将键指定为有效的 IdentifierName、字符串文字或数字信用 RobG(甚至是十六进制)。不是一个表达,这是什么required.applicationPath + "/configs"

于 2011-06-28T01:22:22.417 回答
0

问题出在使用“this”,因为它没有指任何智能*。在其中创建带有 applicationPath 的静态文字。

需要变量={
    "applicationPath":"someWhereOverTheRainboW"
};

然后使用

required.directories={};
required.directories[required.applicationPath + "/configs"]="应用配置文件夹不存在";
……

动态填充

编辑; 我急于提出我的第一个想法,它没有奏效。以上工作现在 - 抱歉!

* 关键字“this”非常聪明:)但它通常指的是窗口对象或元素、已触发事件或调用的“活动”对象。因此,造成了很多混乱;)

于 2011-06-28T01:15:50.993 回答