Javascript 中对象文字的动态键[重复]

问题描述 投票:0回答:8

好吧,我正在 Nodes 中的一个项目上工作,我遇到了对象文本中键的一个小问题,我有以下设置:

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
和连接之类的动态变量将不可用 :( :(

克服此类障碍而无需重写大量代码的最佳方法是什么。

javascript object-literal
8个回答
222
投票

ECMAScript2015 支持计算属性名称:

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

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


112
投票

在 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(第 6 版)开始,对象初始值设定项可以使用以下方法计算键:

[expression]: value

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

请参阅 MDN:对象初始化程序ECMAScript 对象初始化程序


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
}

8
投票

受到 babel 如何将新的 ES6 语法 (

{[expression]: value}
) 转换为旧的 Javascript 的启发,我了解到你可以用一行代码来完成它:

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 上测试)


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;
    }()
}

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


3
投票

一个老问题,当时的答案是正确的,但时代在变。如果有人在谷歌搜索中找到它,新的 JavaScript 版本(ES6)允许使用表达式作为对象文字的键,如果它们被方括号括起来的话:

var obj={["a"+Math.PI]:42}


2
投票

对于对象文字,Javascript/ECMAScript 脚本指定的键可以是有效的 IdentifierName、字符串文字或数字 credit RobG(甚至是十六进制)。不是一个表达式,这就是

required.applicationPath + "/configs"


0
投票

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

需要变量={
    “applicationPath”:“someWhereOverTheRainboW”
};

然后使用

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

动态填充它

编辑; 我急于提出第一个想法,但没有成功。上面的内容现在可以工作了 - 对此感到抱歉!

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

© www.soinside.com 2019 - 2024. All rights reserved.