Javascript中对象文本的动态键

Javascript中对象文本的动态键,javascript,object-literal,Javascript,Object Literal,好的,我正在节点中进行一个项目,我遇到了一个关于对象文本中的键的小问题,我有以下设置: var required = { directories : { this.applicationPath : "Application " + this.application + " does not exists", this.applicationPath + "/configs" : "Application

好的,我正在节点中进行一个项目,我遇到了一个关于对象文本中的键的小问题,我有以下设置:

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"
    }
}
好的,你们中的很多人会看到这个,认为它看起来没问题,但是编译器一直告诉我我缺少了一个
(冒号),我没有,看起来
+
或和
都在影响编译器

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


克服这样的障碍而不必重写大块代码的最佳方法是什么。

问题在于使用“this”,因为它不涉及任何智能*。 创建包含applicationPath的静态文本

var required={ "applicationPath":"someWhereOverTheRainboW" }; 所需风险值={ “应用程序路径”:“Somewhere在下面” }; 然后使用

required.directories={}; required.directories[required.applicationPath + "/configs"]="Application config folder does not exists"; .... 必需。目录={}; 必需的.directories[required.applicationPath+“/configs”]=“应用程序配置文件夹不存在”; .... 动态填充

编辑; 我匆忙地提出了我的第一个想法,但没有成功。上面的想法现在起作用了——很抱歉


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

对于对象文本,Javascript/ECMAScript脚本指定键为有效的标识符名称、字符串文本或数字(偶数十六进制)。不是表达式,这是
必需的。applicationPath+“/configs”
是表达式。

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

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
}
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(第6版)之前,对象文字(ECMAScript称之为“对象初始值设定项”)键必须是以下项之一:

  • 识别名
  • StringLiteral
  • 数字文字
  • 因此,您不能将表达式用作初始值设定器中的键。这在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";
    ...
    
    依此类推。由于此.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
    }
    
    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(第6版)起,对象初始值设定项可以使用以下方法计算密钥:

    [expression]: value
    
    属性和方法名也有速记语法


    如果有深层对象结构(如Grunt配置),请参阅或。

    ,有时可以方便地使用括号表示法返回动态生成的对象键,但在对象结构中内联。这可以通过使用函数在深层对象的上下文中动态返回对象来实现;对于本问题中的代码,类似以下内容:

    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;
        }()
    }
    
    验证此方法。

    受如何将新ES6语法(
    {[expression]:value}
    )转换为旧Javascript的启发,我了解到您可以使用一行代码来实现:

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

    var dynamic\u key=“hello”;
    var value=“世界”;
    var obj=(_obj={},_obj[dynamic_key]=value,_obj);
    控制台日志(obj);
    
    //Object{hello:“world”}
    一个老问题,当时答案是正确的,但时代变了。如果有人在谷歌搜索中找到它,新的javascript版本(ES6)允许使用表达式作为对象文本的键,如果它们被方括号包围:
    var obj={[“a”+Math.PI]:42}

    ECMAScript 2015中支持计算属性名称:

    var name='key';
    var值='值';
    变量o={
    [名称]:值
    };
    
    警报(“o作为json:+json.stringify(o))
    你能提供一个你所说的构造类型的例子吗?我刚才尝试的方式仍然会抛出错误?添加了你想要的缺少的行感谢更新,这就是我假设你的意思,但是当涉及到键时,我仍然会出错,抛出的错误是SyntaxError:Unexpected token。是否
    this.applicationonPath
    不算作有效标识符?也是一个表达式,因为
    的值在运行时之前是未知的。RobertPitt-否,它是一个表达式。请注意,键可以是一个标识符名称,这与作为标识符不同。如果使用与标识符同名的键(例如变量名),它将创建一个具有该名称的属性,它不会解析标识符并创建一个具有标识符值的属性(否则它将被视为一个表达式,但它不能).我不需要在密钥中使用它们,但这只是一种偏好,我会改变它,您的方法似乎最合理。谢谢Felix,我选择了“/config”方法作为键,并连接到for循环中,我没有理由在索引中使用变量,但现在已经晚了,再次感谢巴德。我认为这个答案需要更新。尽管您可以使用:
    {…Object.defineProperty({},key,{value,enumerable:true})}
    ,其中键和值是通过定义具有该键和值的对象以文字对象表示法扩展到的变量在支持的地方会简洁。您可能会发现我在这方面的兴趣有点关联。现在可能重复?请投票,因为您引用了标准,以及可以用作键的内容。ECMA b