javascript - 复杂对象中的javascript自引用
问题描述
我重构了一些多余的旧 javascript 代码。我们的页面使用旧版本的 Select2 并在多个位置填充新的 Select2 下拉/搜索框。
我采用了多余的代码并从代码中构建了一个对象。该对象在某些函数中具有自引用。
当我使用该对象时,我制作了该对象的浅表副本。我担心的是副本中的自引用可能指向原始对象的元素,而不是副本的元素。
有什么更好的方法来构造这个对象,使浅拷贝不指向原始对象?
我做了几个小时的研究。不知道谷歌到底用了什么词使得这很难研究。如果这很容易解决,请原谅。
我确实查看了 MDNgetters
和this page on self-referenceing in objects。我理解它,但我不知道如何使用它。
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
.
使用 _.cloneDeep 来自 lodash 等将是一种方法。我认为使用 ES6 类语法可能是重构它的最快和最容易理解的(对于下一个编码器)方法。
推荐阅读
- firebase-hosting - 无法使用自定义域将 Firebase 动态链接添加到项目
- python - 在 Python matplotlib 中更改 X 轴步长
- redirect - 如何检查我的页面是否来自 302 重定向?
- windows - Windows 7 和 10 - 在命令行更改文件/文件夹所有权,但不仅仅是我自己
- unity3d - Unity3d Animation - 如何让玩家在动画完成后停留在目标位置
- vue.js - 动态实例化的 Vue 组件如何被缓存?
- html - Magento HTML问题 - 侧栏出现在页面内容下方
- git - Git 将已存在的文件显示为新文件
- react-native - 如何在 defaultNavigationOptions 上添加订阅
- arrays - 在 pymongo 的 mongo 文档中返回整个嵌套数组