好的,所以我正在研究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"
}
}
好的,你们很多人都会看这个并认为它看起来没问题,但编译器一直告诉我,我错过了:
(冒号),我不是,它似乎是{{1} }或+
都影响编译器。
现在我相信(不确定),对象文字在编译时创建,而不是在运行时创建,这意味着.
和连接等动态变量不可用:(:(< / p>
在不必重写大块代码的情况下,克服这类障碍的最佳方法是什么。
答案 0 :(得分:85)
在对象文字中(ECMA-262§11.1.5将其称为“对象初始化程序”),密钥必须是以下之一:
因此,您无法将表达式用作初始化器中的键。您可以使用带方括号表示法的表达式来访问属性。因此,要使用您必须执行的表达式设置属性:
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 ed 6开始,对象初始值设定项可以使用以下方法计算密钥:
[expression]: value
属性和方法名称也有简写语法。
答案 1 :(得分:78)
ECMAScript2015支持计算属性名称:
<?php
//database connection variables
$hostname = "";
$username = "";
$password = "";
$dbName = "";
//files to capture json
$incomingJson = 'json.txt';
// initialize the string with a blank value
$string = "";
function insertNewRowIntoStatistics($db,
$rowName,
$charactersName,
$highscoreFeet,
$charactersFitnessLevel,
$worstJump,
$totalTrainingTime,
$startingDate) {
$sqlInsertNewRow = <<<'EOT'
INSERT INTO Statistics(
charactersName,
highscoreFeet,
charactersFitnessLevel,
worstJump,
totalTrainingTime,
startingDate
) VALUES ( ?, ?, ?, ?, ?, ? )
ON DUPLICATE KEY UPDATE
highscoreFeet = VALUES(highscoreFeet),
charactersFitnessLevel = VALUES(charactersFitnessLevel),
worstJump = VALUES(worstJump),
totalTrainingTime = VALUES(totalTrainingTime)
EOT;
$stmt1 = $db->prepare($sqlInsertNewRow);
$stmt1->bind_param("siiiis",
$charactersName,
$highscoreFeet,
$charactersFitnessLevel,
$worstJump,
$totalTrainingTime,
$startingDate);
$stmt1->execute();
$stmt1->bind_result($result);
$stmt1->fetch();
$stmt1->close();
if(!$result){
trigger_error("Error inserting into Statistics, $result", E_USER_ERROR);
}
}
//Create function for deleting rows that have been in queuedRows for more then 5 minutes.
function deleteExpiredRowsInQueuedRows($db) {
$sqlDeleteQueuedRow = "DELETE FROM queuedRows WHERE timeOfCreation < ?";
$stmt4 = $db->prepare($sqlDeleteQueuedRow);
$stmt4->bind_param($stmt4, 'i', DateAdd(mi, -5, GetDate()));
$stmt4->execute();
$stmt4->bind_result($result);
$stmt4->fetch();
$stmt4->close();
// catch any errors
if(!$result){
trigger_error("Error deleting from queuedRows, $result", E_USER_ERROR);
}
}
//Create function for inserting rows that have been searched for into queued rows.
function insertRowInQueuedRows($db, $charactersName) {
$sqlInsertRowInQueuedRows = "Insert INTO queuedRows(charactersName, highscoreFeet, charactersFitnessLevel, worstJump, totalTrainingTime, startingDate, timeOfCreation) SELECT (charactersName, highscoreFeet, charactersFitnessLevel, worstJump, totalTrainingTime, startingDate, timeOfCreation) FROM Statistics where charactersName = ?";
$stmt3 = $db->prepare($sqlInsertRowInQueuedRows);
$stmt3->bind_param(1, $charactersName);
$stmt3->execute();
$stmt3->bind_result($result);
$stmt3->fetch();
$stmt3->close();
if(!$result){
trigger_error("Error inserting into queuedRows, $result", E_USER_ERROR);
}
}
function handleLineOfData( $db,
$rowName,
$charactersName,
$highscoreFeet,
$charactersFitnessLevel,
$worstJump,
$totalTrainingTime,
$startingDate ) {
if($startingDate != "1/1/1") {
//Insert or update a row in main table, Statistics.
insertNewRowIntoStatistics($db,
$rowName,
$charactersName,
$highscoreFeet,
$charactersFitnessLevel,
$worstJump,
$totalTrainingTime,
$startingDate);
} else {
//Search for the character name instead of adding it/delete expired rows.
insertRowInQueuedRows($db, $charactersName);
deleteExpiredRowsInQueuedRows($db);
}
}
//Connecting to your database
$mysqli = new mysqli($hostname, $username, $password, $dbName);
//If error occurs connection to database
if (mysqli_connect_error()) { trigger_error("Cannot connect", E_USER_ERROR); exit; }
//var_dump($_SERVER);
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
var_dump( $_POST );
//capture incoming data
error_reporting(E_ALL);
ini_set('display_errors', 1);
//$sig = $_POST["sig"];
if( isset($_POST['params']) ) {
$jsondata = $_POST["params"];
//Captures sent json to figure out what to send back
//file_put_contents($incomingJson,$jsondata);
//converts JSON to an array
$array = json_decode($jsondata, TRUE);
//formats the array to view it easier
$results = print_r($array,true);
//file_put_contents($fullArray, $results);
//gets the total number of objects in the array
$arrlength = count($array['Children']['1']['Properties']);
//loop through array node and get row values
for ($i=0; $i < $arrlength; $i++) {
// get row value
$value = $array['Children']['1']['Properties'][$i]['Value']."\n";
// convert delimited string to an array
$arrayPieces = explode("|", $value);
$rowName = $arrayPieces[0];
$charactersName = $arrayPieces[1];
$highscoreFeet = $arrayPieces[2];
$charactersFitnessLevel = $arrayPieces[3];
$worstJump = $arrayPieces[4];
$totalTrainingTime = $arrayPieces[5];
$startingDate = $arrayPieces[6];
handleLineOfData( $mysqli, $rowName, $charactersName,
$highscoreFeet, $charactersFitnessLevel,
$worstJump, $totalTrainingTime, $startingDate );
}
}
// report http success even if data wasn't found
//Tells application of success
echo '{"Status":"Success"}';
} // end of POST
// start GET data
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
//var_dump( $_GET );
// initialize the JSON body variable
$jsonBody="";
//get table contents
$query = mysqli_query($mysqli, "SELECT * FROM queuedRows");
//construct an array to hold the data pulled down from mySQL
$rows = array();
// loop through the table and drop the data into the array
while($row = mysqli_fetch_assoc($query)) {
$rows[] = $row;
}
// get the number of rows in the array for the JSON return
$arrlength = count($rows);
// set while loop index
$i = 0;
//loop through array node and get row values
while ($i < $arrlength ) {
// tables we are capturing
$charactersName = $rows[$i]['charactersName'];
$highscoreFeet =$rows[$i]['highscoreFeet'];
$charactersFitnessLevel = $rows[$i]['charactersFitnessLevel'];
$worstJump = $rows[$i]['worstJump'];
$totalTrainingTime = $rows[$i]['totalTrainingTime'];
$startingDate = $rows[$i]['startingDate'];
// table row numbers. index starts at 0, increment it by 1 to get valid row numbers.
$tableRow = $i+1;
// construct the JSON return from data
$jsonString ='{"Name":"'.$tableRow.'","Value":"|'.$charactersName.'|'.$highscoreFeet.'|'.$charactersFitnessLevel.'|'.$worstJump.'|'.$totalTrainingTime.'|'.$startingDate.'|"},';
// append the JSON return with the new data
$jsonBody=$jsonBody.$jsonString;
// increase index and loop again if not at end of array.
$i++;
}
// construct the JSON response to send table back to app
// this is the header of the JSON return.
$jsonHeadher='{"Properties":[],"Name":"id946381_headers","Children":[{"Properties":[{"Name":"rowCount","Value":'.$arrlength.'},{"Name":"columnCount","Value":6},{"Name":"0-1-name","Value":"charactersName"},{"Name":"0-1-type","Value":1},{"Name":"0-2-name","Value":"highscoreFeet"},{"Name":"0-2-type","Value":2},{"Name":"0-3-name","Value":"charactersFitnessLevel"},{"Name":"0-3-type","Value":2},{"Name":"0-4-name","Value":"worstJump"},{"Name":"0-4-type","Value":2},{"Name":"0-5-name","Value":"totalTrainingTime"},{"Name":"0-5-type","Value":2},{"Name":"0-6-name","Value":"startingDate"},{"Name":"0-6-type","Value":1}],"Name":"id946381_headers","Children":[]},{"Properties":[';
// this is the footer of the JSON return.
$jsonFooter='],"Name":"id946381","Children":[]}]}';
// removes an extra comma that the loop above leaves behind
$jsonBody=rtrim($jsonBody, ",");
// constructing the full JSON return
$returnedJson=$jsonHeadher.$jsonBody.$jsonFooter;
// write the JSON data so the app can read it.
echo $returnedJson;
} // end of get
//Close out mysql
$mysqli->close();
?>
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer
答案 2 :(得分:39)
设置动态键的唯一方法是使用括号表示法:
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
}
答案 3 :(得分:5)
受到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上测试)
答案 4 :(得分:2)
对于对象文字,Javascript / ECMAScript脚本指定键可以是有效的IdentifierName,字符串文字或数字 credit RobG (甚至是十六进制)。不是表达式,而是required.applicationPath + "/configs"
。
答案 5 :(得分:2)
如果你有一个深层对象结构(例如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;
}()
}
This fiddle验证了这种方法。
答案 6 :(得分:2)
一个老问题,答案当时是正确的,但时间会发生变化。如果有人在谷歌搜索中挖掘它,新的JavaScript版本(ES6)允许使用表达式作为对象文字的键,如果它们被方括号括起来:
var obj={["a"+Math.PI]:42}
答案 7 :(得分:0)
问题在于使用'this',因为它没有引用任何智能*。 使用applicationPath创建静态文字。
var required={ "applicationPath":"someWhereOverTheRainboW" };
然后使用
required.directories={}; required.directories[required.applicationPath + "/configs"]="Application config folder does not exists"; ....
动态填充
编辑; 我赶紧用我的第一个想法,它没有用。以上工作现在 - 抱歉!
*关键字'this'非常聪明:)但它经常引用窗口对象或元素,事件已被触发或被调用的'active'对象。因此,造成了很多困惑;)