朋友们,我再次需要有识之士的帮助。我有一个用于构建表格的简单函数和一个用于填充这张表格的函数:
function createTableEmpty(id, colRows, colColums) {
let table = document.getElementById(id);
let caption = document.createElement('caption')
caption.id = "caption"
caption.className = "text2"
for (let i = 0; i < colRows; i++) {
let tr = document.createElement('tr');
for (let j = 0; j < colColums; j++) {
let td = document.createElement('td');
td.id = `tc${i}${j}`
if (i == 0) {
td.className = "cell4 cell"
} else {
td.className = "cell4"
}
tr.appendChild(td);
}
table.appendChild(caption);
table.appendChild(tr);
}
}
function printDataResTest(data) {
let j = 0;
let property = Object.getOwnPropertyNames(data)
for (var i = 0; i < property.length; i++) {
if (Array.isArray(data[property[i]])) {
for (var k = 0; k < data.rows.length; k++) {
document.getElementById(`tc${k}${j}`).innerHTML = data[property[i]][k]
}
j++
}
}
};
建表函数考虑了 HTML 中的“构建位置”,以及未来表格的列数和行数,这些数是根据基变量 中的数组数量计算的resName,基变量是一个对象,(number列数)和这些数组的长度(行数)。
构建表后,它开始填充变量 中的数组内容resName。
变量本身如下所示:
const HSS = HERO.sexStats;
let resName = {
name: ['Act', 'Virginity', 'Pregnant', 'Birth', 'Fertilization', 'Vaginal sex', 'Anal sex', 'Oral sex', 'Piss drinking', 'Rimjob', 'Footjob', 'Breastjob'],
get data1() {
let a = [];
a[0] = 'Data'
if (HSS.virginity == 0) {
a[1] = 'Yes'
} else {
a[1] = 'No'
}
if (HERO.genderStats.pregnancy == 1) {
a[2] = 'Yes'
} else {
a[2] = 'No'
}
if (HERO.genderStats.birth != 0) {
a[3] = HERO.genderStats.birth
} else {
a[3] = 'No'
}
if (HERO.genderStats.inseminate == 'Yes') {
a[4] = 'Yes'
} else {
a[4] = 'No'
}
for (var i = 0; i < this.support.dom.length; i++) {
a[i+5] = this.support.dom[i] + this.support.sub[i];
}
return a;
},
get data2() {
let j = 0
let a = []
let b = ['Virginity', 'Pregnant', 'Birth', 'Fertilization']
for (var i = 0; i < this.name.length; i++) {
if (this.name[i] == 'Act') {
a[i] = 'Details'
} else {
if (b.includes(this.name[i])) {
a[i] = '';
} else {
a[i] = `Dom: ${this.support.dom[j]} </br> Sub: ${this.support.sub[j]}`
j++
}
}
}
if (this.data1[4] == 'Yes') {
a[4] = HSS.sexFertilization
} else {
a[4] = '';
}
return a;
},
get rows() {
let a = this.name.length;
return a;
},
get colums() {
let a = 0
let property = Object.getOwnPropertyNames(this)
console.log('property: ', property)
for (var i = 0; i < property.length; i++) {
if (Array.isArray(this[property[i]])) {
a++
}
}
return a;
},
get keys() {
return objectKey(this)
},
support: {
dom: [HSS.sexVaginalDom, HSS.sexAnalDom, HSS.sexOralDom, HSS.pissDrinkingDom, HSS.sexRimjobDom, HSS.sexFootjobDom, HSS.sexBreastjobDom,],
sub: [HSS.sexVaginalSub, HSS.sexAnalSub, HSS.sexOralSub, HSS.pissDrinkingSub, HSS.sexRimjobSub, HSS.sexFootjobSub, HSS.sexBreastjobSub,],
id: [
['tc00', 'tc01', 'tc02'],
['tc10', 'tc11', 'tc12'],
['tc20', 'tc21', 'tc22'],
['tc30', 'tc31', 'tc32'],
['tc40', 'tc41', 'tc42'],
['tc50', 'tc51', 'tc52'],
['tc60', 'tc61', 'tc62'],
['tc70', 'tc71', 'tc72'],
['tc80', 'tc81', 'tc82'],
['tc90', 'tc91', 'tc92'],
['tc100', 'tc101', 'tc102'],
['tc110', 'tc111', 'tc112'],
],
},
};
function objectKey(obj) {
let keys = Object.keys(obj)
return keys;
}
createTableEmpty('tableHeroStats', resName.rows, resName.colums);
printDataResTest(resName);
从代码中可以看到,里面有很多getter,在代码执行时立即进行计算。但这就是问题出现的地方:每次建表函数和/或其填充函数执行循环时,所有 getter 都会再次开始重新计算。
结果,代码冻结了(或者更确切地说,执行时间非常长。时间长到编译器只是中断此过程,认为该过程是无限的)。
所以,我的问题是:是否有可能以某种方式转换 getter,以便它们不在构建表和/或填充它的函数循环的每个新步骤中执行重新计算,而是在第一次运行时仅执行一次,然后简单地存储结果值?
=================================================== =============================
let resName = {
name: ['Act', 'Virginity', 'Pregnant', 'Birth', 'Fertilization', 'Vaginal sex', 'Anal sex', 'Oral sex', 'Piss drinking', 'Rimjob', 'Footjob', 'Breastjob'],
data1: [],
data2: [],
get creatData1() {
let a = [];
if (this.data1.length != 0) {
return this.data1
} else {
a[0] = 'Data'
if (HSS.virginity == 0) {
a[1] = 'Yes'
} else {
a[1] = 'No'
}
if (HERO.genderStats.pregnancy == 1) {
a[2] = 'Yes'
} else {
a[2] = 'No'
}
if (HERO.genderStats.birth != 0) {
a[3] = HERO.genderStats.birth
} else {
a[3] = 'No'
}
if (HERO.genderStats.inseminate == 'Yes') {
a[4] = 'Yes'
} else {
a[4] = 'No'
}
for (var i = 0; i < this.support.dom.length; i++) {
a[i+5] = this.support.dom[i] + this.support.sub[i];
}
//return a;
this.data1 = a
}
},
get creatData2() {
let j = 0
let a = [];
let b = ['Virginity', 'Pregnant', 'Birth', 'Fertilization']
if (this.data2.length != 0) {
return this.data2
} else {
for (var i = 0; i < this.name.length; i++) {
if (this.name[i] == 'Act') {
a[i] = 'Details'
} else {
if (b.includes(this.name[i])) {
a[i] = '';
} else {
a[i] = `Dom: ${this.support.dom[j]} </br> Sub: ${this.support.sub[j]}`
j++
}
}
}
if (this.data1[4] == 'Yes') {
a[4] = HSS.sexFertilization
} else {
a[4] = '';
}
//return a;
this.data2 = a
}
},
get rows() {
let a = this.name.length;
return a;
},
colums: 0,
get sumColums() {
let a = 0
if (this.colums != 0) {
return this.colums
} else {
let property = Object.keys(this)
console.log('property: ', property)
for (var i = 0; i < property.length; i++) {
if (Array.isArray(this[property[i]])) {
a++
}
}
this.colums = a;
}
},
support: {
dom: [HSS.sexVaginalDom, HSS.sexAnalDom, HSS.sexOralDom, HSS.pissDrinkingDom, HSS.sexRimjobDom, HSS.sexFootjobDom, HSS.sexBreastjobDom,],
sub: [HSS.sexVaginalSub, HSS.sexAnalSub, HSS.sexOralSub, HSS.pissDrinkingSub, HSS.sexRimjobSub, HSS.sexFootjobSub, HSS.sexBreastjobSub,],
id: [
['tc00', 'tc01', 'tc02'],
['tc10', 'tc11', 'tc12'],
['tc20', 'tc21', 'tc22'],
['tc30', 'tc31', 'tc32'],
['tc40', 'tc41', 'tc42'],
['tc50', 'tc51', 'tc52'],
['tc60', 'tc61', 'tc62'],
['tc70', 'tc71', 'tc72'],
['tc80', 'tc81', 'tc82'],
['tc90', 'tc91', 'tc92'],
['tc100', 'tc101', 'tc102'],
['tc110', 'tc111', 'tc112'],
],
},
};
这段代码有两个问题:
геттера另外,代码存在冗余和格式不良(建议阅读《Clean Code》)
第一个问题是:
本质上返回
this.name.length一个明确的数字,因此在这种情况下使用:这是完全不可接受的(从数字中获取长度没有任何意义),可能是由于不注意您自己的代码。
解决方案的第一部分:
在这种情况下创建变量是没有意义的
a,因为在任何情况下我们都通过引用返回相同的对象(这是反对冗余的一个例子)。第二个问题是:
当此特定代码中的此函数尝试访问循环中某个点的等效
this[property[i]]位置时,它会调用自身,从而消除此键,您可以通过递归解决问题:property[i]'sumColums'геттера解决方案的第二部分: