javascript 复杂对象中的自引用
javascript self references in complex objects
我重构了一些旧的 javascript 冗余代码。我们的页面使用旧版本的 Select2 并在多个位置填充新的 Select2 dropdown/search 框。
我提取了多余的代码并从代码中构建了一个对象。该对象在某些函数中具有自引用。
当我使用这个对象时,我做了一个对象的浅拷贝。我担心的是副本中的自引用可能指向原始对象的元素,而不是副本的元素。
有什么更好的方法来构建此对象,使浅拷贝不指向原始对象?
我已经做了几个小时的研究。不确切地知道 google 是什么词使得这很难研究。如果这很容易解决,请原谅。
我确实在 getters
和 this page 上查看了关于对象中自引用的 MDN。我看懂了,就是不知道怎么用
ajax: {
main: function () {
let results = (mainObject.ajax.type.toLowerCase === 'new' ? mainObject.ajax.resultNew : mainObject.ajax.resultPreExisting);
if (typeof (results) != 'function') {
mainObject.error;
}
ajaxObj = {
url: someOutSideVariableForURL,
dataType: "json",
quietMillis: 100,
data: function (c, d) {
return {
searchFor: c,
maxPerPage: 30,
page: d
};
},
results: results
}
return ajaxObj;
},
type: "",
resultNew: function (e, d) {
//new result function
var c = {
results: e.results,
more: false
};
if (d < e.info.totalPages) {
c.more = true;
}
if (c.results.length) {
$("#someIDTag input[name=firstStuff_" + mainObject.idCount + "]").data("hasResults", true);
}
return c;
},
resultPreExisting: function (e, d) {
// Pre existing result function
var c = {
results: e.results,
more: false
};
if (d < e.info.totalPages) {
c.more = true;
}
$("#someIDTag input[name=firstStuff_" + mainObject.idCount + "]").data("hasResults", false);
if (c.results.length) {
$("#someIDTag input[name=firstStuff_" + mainObject.idCount + "]").data("hasResults", true);
}
return c;
}
},
createSearchChoice: function (d) {
var c = {
hasResults: $("#someIDTag input[name=firstStuff_" + mainObject.idCount + "]").data("hasResults"),
results: null
};
if ($.trim(d).length) {
c.results = {
id: 0,
text: d
};
}
return c.results;
},
error: function(){
alert("mainObject improper configuration")
return null
},
formatResult: function (item, container, escapeMarkup) {
var d = {
response: item.text,
markup: []
};
window.Select2.util.markMatch(d.response, escapeMarkup.term, d.markup);
if (item.id == 0) {
d.response += '<br/><i style="font-size:0.8em;"><i class="icon-plus-sign"></i> Add new stuff</i>';
} else {
d.response = d.markup.join("");
}
if (item.data && item.data.businessFunctions.length) {
d.response += '<br /><span style="font-size:0.75em;opacity:0.55;">(' + item.data.businessFunctions + ")</span>";
}
return d.response;
},
formatSearching: function () {
return ' <i class="icon-spinner icon-spin"></i> Searching stuff...';
},
formatSelection: function (item, container) {
$("#someOtherIDTag input[name=stuff_" + mainObject.idCount + "]").val(item.text);
$("#someOtherIDTag input[name=stuff_other_" + mainObject.idCount + "]").val(item.id);
if (item.id == 0) {
$(container).append('<i class="pull-right" style="font-size:0.8em;color:#049cdb;font-weight:bold;"><i class="icon-warning-sign"></i> New</i>');
}
return item.text;
},
getIdCount: function(){ //tried this but do not know how to use it properly
return this.idCount
},
idCount: 0,
initSelection: function (c, d) {
d({
id: $("input[name=dealCompanyID_" + mainObject.idCount + "]").val(),
text: c.val()
});
},
S2Base: {
dropdownCssClass: SELECT2FIXED,
placeholder: "",
minimumInputLength: 2
}
}
// As you can see mainObject is accessed in a few places. Please remember this is not my code. I am just trying to refactor it into an object as the project expands.
// This is how I use the object (and this is done a few times each time with a different name for newCopyObject):
$(".someClass").each(function(){
const newCopyObject = {...mainObject};
newCopyObject.idCount = fromDataAttrOnHTMLNode;
newCopyObject.ajax.type = 'new';
$(this).select2({
...newCopyObject.S2Base,
formatSearching: newCopyObject.formatSearching,
initSelection: newCopyObject.initSelection,
ajax: newCopyObject.ajax.main(),
createSearchChoice: newCopyObject.createSearchChoice,
formatResult:newCopyObject.formatResult,
formatSelection: newCopyObject.formatSelection
});
});
// ...do a bunch of other things
在我看来你可能想要重构。我不完全明白发生了什么,但如果 mainObject
有对自身的引用,那么在 const newCopyObject = {...mainObject};
newCopyObject
之后,那些的新副本将指向 mainObject
。
使用来自 lodash 等的 _.cloneDeep 是一种方法。我认为使用 ES6 class 语法可能是重构它的最快和最容易理解的方式(对下一个编码器而言)。
我重构了一些旧的 javascript 冗余代码。我们的页面使用旧版本的 Select2 并在多个位置填充新的 Select2 dropdown/search 框。
我提取了多余的代码并从代码中构建了一个对象。该对象在某些函数中具有自引用。
当我使用这个对象时,我做了一个对象的浅拷贝。我担心的是副本中的自引用可能指向原始对象的元素,而不是副本的元素。
有什么更好的方法来构建此对象,使浅拷贝不指向原始对象?
我已经做了几个小时的研究。不确切地知道 google 是什么词使得这很难研究。如果这很容易解决,请原谅。
我确实在 getters
和 this page 上查看了关于对象中自引用的 MDN。我看懂了,就是不知道怎么用
ajax: {
main: function () {
let results = (mainObject.ajax.type.toLowerCase === 'new' ? mainObject.ajax.resultNew : mainObject.ajax.resultPreExisting);
if (typeof (results) != 'function') {
mainObject.error;
}
ajaxObj = {
url: someOutSideVariableForURL,
dataType: "json",
quietMillis: 100,
data: function (c, d) {
return {
searchFor: c,
maxPerPage: 30,
page: d
};
},
results: results
}
return ajaxObj;
},
type: "",
resultNew: function (e, d) {
//new result function
var c = {
results: e.results,
more: false
};
if (d < e.info.totalPages) {
c.more = true;
}
if (c.results.length) {
$("#someIDTag input[name=firstStuff_" + mainObject.idCount + "]").data("hasResults", true);
}
return c;
},
resultPreExisting: function (e, d) {
// Pre existing result function
var c = {
results: e.results,
more: false
};
if (d < e.info.totalPages) {
c.more = true;
}
$("#someIDTag input[name=firstStuff_" + mainObject.idCount + "]").data("hasResults", false);
if (c.results.length) {
$("#someIDTag input[name=firstStuff_" + mainObject.idCount + "]").data("hasResults", true);
}
return c;
}
},
createSearchChoice: function (d) {
var c = {
hasResults: $("#someIDTag input[name=firstStuff_" + mainObject.idCount + "]").data("hasResults"),
results: null
};
if ($.trim(d).length) {
c.results = {
id: 0,
text: d
};
}
return c.results;
},
error: function(){
alert("mainObject improper configuration")
return null
},
formatResult: function (item, container, escapeMarkup) {
var d = {
response: item.text,
markup: []
};
window.Select2.util.markMatch(d.response, escapeMarkup.term, d.markup);
if (item.id == 0) {
d.response += '<br/><i style="font-size:0.8em;"><i class="icon-plus-sign"></i> Add new stuff</i>';
} else {
d.response = d.markup.join("");
}
if (item.data && item.data.businessFunctions.length) {
d.response += '<br /><span style="font-size:0.75em;opacity:0.55;">(' + item.data.businessFunctions + ")</span>";
}
return d.response;
},
formatSearching: function () {
return ' <i class="icon-spinner icon-spin"></i> Searching stuff...';
},
formatSelection: function (item, container) {
$("#someOtherIDTag input[name=stuff_" + mainObject.idCount + "]").val(item.text);
$("#someOtherIDTag input[name=stuff_other_" + mainObject.idCount + "]").val(item.id);
if (item.id == 0) {
$(container).append('<i class="pull-right" style="font-size:0.8em;color:#049cdb;font-weight:bold;"><i class="icon-warning-sign"></i> New</i>');
}
return item.text;
},
getIdCount: function(){ //tried this but do not know how to use it properly
return this.idCount
},
idCount: 0,
initSelection: function (c, d) {
d({
id: $("input[name=dealCompanyID_" + mainObject.idCount + "]").val(),
text: c.val()
});
},
S2Base: {
dropdownCssClass: SELECT2FIXED,
placeholder: "",
minimumInputLength: 2
}
}
// As you can see mainObject is accessed in a few places. Please remember this is not my code. I am just trying to refactor it into an object as the project expands.
// This is how I use the object (and this is done a few times each time with a different name for newCopyObject):
$(".someClass").each(function(){
const newCopyObject = {...mainObject};
newCopyObject.idCount = fromDataAttrOnHTMLNode;
newCopyObject.ajax.type = 'new';
$(this).select2({
...newCopyObject.S2Base,
formatSearching: newCopyObject.formatSearching,
initSelection: newCopyObject.initSelection,
ajax: newCopyObject.ajax.main(),
createSearchChoice: newCopyObject.createSearchChoice,
formatResult:newCopyObject.formatResult,
formatSelection: newCopyObject.formatSelection
});
});
// ...do a bunch of other things
在我看来你可能想要重构。我不完全明白发生了什么,但如果 mainObject
有对自身的引用,那么在 const newCopyObject = {...mainObject};
newCopyObject
之后,那些的新副本将指向 mainObject
。
使用来自 lodash 等的 _.cloneDeep 是一种方法。我认为使用 ES6 class 语法可能是重构它的最快和最容易理解的方式(对下一个编码器而言)。