将变量或 属性 值传递给 JavaScript 对象中的方法 returns "undefined"
Passing a variable or property value to a method in a JavaScript object returns "undefined"
我正在尝试通过 2 个级联循环从 2 个 JSON 对象构建一个 xml 文件。在第二个循环中,我找不到如何传递上一个循环中的值:
在下面的示例中,我想将 "docnumber" 值传递给我的第二个循环(通过 GroupsACLJSON)以便从第二个 "acl" 节点构建 JSON 对象,但使用来自父对象 属性 returns "undefined" 的 "this.docnumber",从而导致一个空的 "acl" 节点。
var documentsJSON = [{
"folder": "Enterprise1",
"extension": "DOCX",
"docnumber": "3912271",
"version": "1"
},
{
"folder": "Enterprise2",
"extension": "MSG",
"docnumber": "3912298",
"version": "1"
},
{
"folder": "Enterprise3",
"extension": "DOCX",
"docnumber": "3912692",
"version": "1"
}
]
var GroupsACLJSON = [{
"docNumber": "3912271",
"groupName": "group1"
},
{
"docNumber": "3912271",
"groupName": "group2"
},
{
"docNumber": "3912298",
"groupName": "group3"
},
{
"docNumber": "3912298",
"groupName": "group4"
}
]
// importing and declaring xmlbuilder variable:
var builder = require('xmlbuilder');
var xmlObjectImporter = builder.create('import', {
version: '1.0',
encoding: 'UTF-8',
standalone: true
}, {
headless: false,
stringify: {}
});
var nodeArray = [];
var xmlObjectElement = {
node: function() {
for (var i = 0; i < documentsJSON.length; i++) {
// populate the nodeObject for each row in documentsJSON and add it to the nodeArray:
var nodeObject = {
location: documentsJSON[i].folder,
category: {
attribute: [{
'#text': documentsJSON[i].docnumber,
'@name': "Document Number"
}],
'@name': "ACME",
},
docnumber: documentsJSON[i].docnumber,
// loop through GroupsACLJSON to find if we have specific ACL groups for this document:
acl: function() {
var documentNumber = this.docnumber
console.log(this.docnumber);
var acl = [];
var aclObject = {};
for (var j = 0; j < GroupsACLJSON.length; j++) {
if (GroupsACLJSON[j].docNumber == documentNumber) {
aclObject = {
'@group': GroupsACLJSON[j].groupName,
'@permissions': '111111100'
};
acl.push(aclObject);
};
};
return acl;
},
'@type': "document",
'@action': "create",
};
nodeArray.push(nodeObject);
};
return nodeArray;
}
};
// writing our elements in the xml file using the XML object:
var ele = xmlObjectImporter.ele(xmlObjectElement);
console.log(xmlObjectImporter.toString({
pretty: true
}));
这是我期望的输出:
<import>
<node type="document" action="create">
<location>Enterprise1</location>
<category name="ACME">
<attribute name="Document Number">3912271</attribute>
</category>
<docnumber>3912271</docnumber>
<acl group="group1" permissions="111111100" />
<acl group="group2" permissions="111111100" />
</node>
<node type="document" action="create">
<location>Enterprise2</location>
<category name="ACME">
<attribute name="Document Number">3912298</attribute>
</category>
<docnumber>3912298</docnumber>
<acl group="group3" permissions="111111100" />
<acl group="group4" permissions="111111100" />
</node>
<node type="document" action="create">
<location>Enterprise3</location>
<category name="ACME">
<attribute name="Document Number">3912692</attribute>
</category>
<docnumber>3912692</docnumber>
<acl/>
</node>
</import>
在严格模式下 运行 时,您有几个未声明的变量会导致您的代码中断。
您的 for 循环中的 i
和 j
都需要声明。例如let i = 0
.
- 未声明
aclObject
。您需要添加一个 var 声明,例如const aclObject = { ... }
.
修复这些问题后,我没有遇到任何问题 运行 你的代码,至少,我没有遇到构建 xmlObjectElement 和执行 node() 和 acl() 函数的问题,它们工作正常.
已更新
这不会修复 xml-builder 遍历您的对象并构建 xml 的方式,但可以通过使用 Array 方法而不是 for 循环来改进您的函数。您无需使用 i
或 j
并减少因此引入错误的机会。
例如,您可以使用 .map()
轻松替换这两个循环。参见 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map。
var xmlObjectElement = {
node: function () {
return documentsJSON.map((document) => {
// populate the nodeObject for each row in documentsJSON and add it to the nodeArray:
return {
location: document.folder,
category: {
attribute: [
{ '#text': document.docnumber, '@name': "Document Number" }
],
'@name': "ACME",
},
....
})
按照 nxSolari 的建议,我使用 2 个函数而不是大对象和方法重新编写了代码,并得到了预期的结果。我仍然不明白代码是如何通过对象和方法的,但这是新的工作代码:
'use strict';
var documentsJSON = [{
"folder":"Enterprise1" ,
"extension":"DOCX" ,
"docnumber":"3912271" ,
"version":"1"
},
{
"folder":"Enterprise2" ,
"extension":"MSG" ,
"docnumber":"3912298" ,
"version":"1"
},
{
"folder":"Enterprise3" ,
"extension":"DOCX" ,
"docnumber":"3912692" ,
"version":"1"
}
]
var GroupsACLJSON = [{
"docNumber":"3912271" ,
"groupName":"group1"
},
{
"docNumber":"3912271" ,
"groupName":"group2"
},
{
"docNumber":"3912298" ,
"groupName":"group3"
},
{
"docNumber":"3912298" ,
"groupName":"group4"
},
{
"docNumber":"3912692" ,
"groupName":"group5"
}
]
// importing and declaring xmlbuilder variable:
var builder = require('xmlbuilder');
var xmlObjectImporter = builder.create('import', {
version: '1.0',
encoding: 'UTF-8',
standalone: true
}, {
headless: false,
stringify: {}
});
var xmlObjectElement = {};
function buildACLnode(passedDoc, acls) {
var acl= [];
for (var jDoc = 0 ; jDoc < acls.length ; jDoc++) {
if (acls[jDoc].docNumber == passedDoc) {
var aclObject = {
'@group': acls[jDoc].groupName,
'@permissions': '111111100'
};
acl.push(aclObject);
};
};
return acl;
}
function buildXML(documents) {
var nodeArray = [];
for (var iDoc = 0; iDoc < documents.length; iDoc++) {
var nodeObject = {
node: {
location: documentsJSON[iDoc].folder,
category: {
attribute: [
{ '#text': documentsJSON[iDoc].docnumber, '@name': "Document Number" }
],
'@name': "ACME",
},
acl: buildACLnode(documentsJSON[iDoc].docnumber, GroupsACLJSON),
'@type': "document",
'@action': "create",
}
};
nodeArray.push(nodeObject);
};
return nodeArray;
}
xmlObjectElement = buildXML(documentsJSON);
// writing our elements in the xml file using the XML object:
var ele = xmlObjectImporter.ele(xmlObjectElement);
console.log(xmlObjectImporter.toString({
pretty: true
}));
我正在尝试通过 2 个级联循环从 2 个 JSON 对象构建一个 xml 文件。在第二个循环中,我找不到如何传递上一个循环中的值:
在下面的示例中,我想将 "docnumber" 值传递给我的第二个循环(通过 GroupsACLJSON)以便从第二个 "acl" 节点构建 JSON 对象,但使用来自父对象 属性 returns "undefined" 的 "this.docnumber",从而导致一个空的 "acl" 节点。
var documentsJSON = [{
"folder": "Enterprise1",
"extension": "DOCX",
"docnumber": "3912271",
"version": "1"
},
{
"folder": "Enterprise2",
"extension": "MSG",
"docnumber": "3912298",
"version": "1"
},
{
"folder": "Enterprise3",
"extension": "DOCX",
"docnumber": "3912692",
"version": "1"
}
]
var GroupsACLJSON = [{
"docNumber": "3912271",
"groupName": "group1"
},
{
"docNumber": "3912271",
"groupName": "group2"
},
{
"docNumber": "3912298",
"groupName": "group3"
},
{
"docNumber": "3912298",
"groupName": "group4"
}
]
// importing and declaring xmlbuilder variable:
var builder = require('xmlbuilder');
var xmlObjectImporter = builder.create('import', {
version: '1.0',
encoding: 'UTF-8',
standalone: true
}, {
headless: false,
stringify: {}
});
var nodeArray = [];
var xmlObjectElement = {
node: function() {
for (var i = 0; i < documentsJSON.length; i++) {
// populate the nodeObject for each row in documentsJSON and add it to the nodeArray:
var nodeObject = {
location: documentsJSON[i].folder,
category: {
attribute: [{
'#text': documentsJSON[i].docnumber,
'@name': "Document Number"
}],
'@name': "ACME",
},
docnumber: documentsJSON[i].docnumber,
// loop through GroupsACLJSON to find if we have specific ACL groups for this document:
acl: function() {
var documentNumber = this.docnumber
console.log(this.docnumber);
var acl = [];
var aclObject = {};
for (var j = 0; j < GroupsACLJSON.length; j++) {
if (GroupsACLJSON[j].docNumber == documentNumber) {
aclObject = {
'@group': GroupsACLJSON[j].groupName,
'@permissions': '111111100'
};
acl.push(aclObject);
};
};
return acl;
},
'@type': "document",
'@action': "create",
};
nodeArray.push(nodeObject);
};
return nodeArray;
}
};
// writing our elements in the xml file using the XML object:
var ele = xmlObjectImporter.ele(xmlObjectElement);
console.log(xmlObjectImporter.toString({
pretty: true
}));
这是我期望的输出:
<import>
<node type="document" action="create">
<location>Enterprise1</location>
<category name="ACME">
<attribute name="Document Number">3912271</attribute>
</category>
<docnumber>3912271</docnumber>
<acl group="group1" permissions="111111100" />
<acl group="group2" permissions="111111100" />
</node>
<node type="document" action="create">
<location>Enterprise2</location>
<category name="ACME">
<attribute name="Document Number">3912298</attribute>
</category>
<docnumber>3912298</docnumber>
<acl group="group3" permissions="111111100" />
<acl group="group4" permissions="111111100" />
</node>
<node type="document" action="create">
<location>Enterprise3</location>
<category name="ACME">
<attribute name="Document Number">3912692</attribute>
</category>
<docnumber>3912692</docnumber>
<acl/>
</node>
</import>
在严格模式下 运行 时,您有几个未声明的变量会导致您的代码中断。
-
您的 for 循环中的
i
和j
都需要声明。例如let i = 0
.- 未声明
aclObject
。您需要添加一个 var 声明,例如const aclObject = { ... }
.
修复这些问题后,我没有遇到任何问题 运行 你的代码,至少,我没有遇到构建 xmlObjectElement 和执行 node() 和 acl() 函数的问题,它们工作正常.
已更新
这不会修复 xml-builder 遍历您的对象并构建 xml 的方式,但可以通过使用 Array 方法而不是 for 循环来改进您的函数。您无需使用 i
或 j
并减少因此引入错误的机会。
例如,您可以使用 .map()
轻松替换这两个循环。参见 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map。
var xmlObjectElement = {
node: function () {
return documentsJSON.map((document) => {
// populate the nodeObject for each row in documentsJSON and add it to the nodeArray:
return {
location: document.folder,
category: {
attribute: [
{ '#text': document.docnumber, '@name': "Document Number" }
],
'@name': "ACME",
},
....
})
按照 nxSolari 的建议,我使用 2 个函数而不是大对象和方法重新编写了代码,并得到了预期的结果。我仍然不明白代码是如何通过对象和方法的,但这是新的工作代码:
'use strict';
var documentsJSON = [{
"folder":"Enterprise1" ,
"extension":"DOCX" ,
"docnumber":"3912271" ,
"version":"1"
},
{
"folder":"Enterprise2" ,
"extension":"MSG" ,
"docnumber":"3912298" ,
"version":"1"
},
{
"folder":"Enterprise3" ,
"extension":"DOCX" ,
"docnumber":"3912692" ,
"version":"1"
}
]
var GroupsACLJSON = [{
"docNumber":"3912271" ,
"groupName":"group1"
},
{
"docNumber":"3912271" ,
"groupName":"group2"
},
{
"docNumber":"3912298" ,
"groupName":"group3"
},
{
"docNumber":"3912298" ,
"groupName":"group4"
},
{
"docNumber":"3912692" ,
"groupName":"group5"
}
]
// importing and declaring xmlbuilder variable:
var builder = require('xmlbuilder');
var xmlObjectImporter = builder.create('import', {
version: '1.0',
encoding: 'UTF-8',
standalone: true
}, {
headless: false,
stringify: {}
});
var xmlObjectElement = {};
function buildACLnode(passedDoc, acls) {
var acl= [];
for (var jDoc = 0 ; jDoc < acls.length ; jDoc++) {
if (acls[jDoc].docNumber == passedDoc) {
var aclObject = {
'@group': acls[jDoc].groupName,
'@permissions': '111111100'
};
acl.push(aclObject);
};
};
return acl;
}
function buildXML(documents) {
var nodeArray = [];
for (var iDoc = 0; iDoc < documents.length; iDoc++) {
var nodeObject = {
node: {
location: documentsJSON[iDoc].folder,
category: {
attribute: [
{ '#text': documentsJSON[iDoc].docnumber, '@name': "Document Number" }
],
'@name': "ACME",
},
acl: buildACLnode(documentsJSON[iDoc].docnumber, GroupsACLJSON),
'@type': "document",
'@action': "create",
}
};
nodeArray.push(nodeObject);
};
return nodeArray;
}
xmlObjectElement = buildXML(documentsJSON);
// writing our elements in the xml file using the XML object:
var ele = xmlObjectImporter.ele(xmlObjectElement);
console.log(xmlObjectImporter.toString({
pretty: true
}));