I have refactored some old javascript code that is redundant. Our page uses an old version of Select2 and populates new Select2 dropdown/search boxes in several places.
I took the code that was redundant and built an object out of the code. The object has self-references within some functions.
When I use the object, I make a shallow copy of the object. My concern is that the self-references within the copies may be pointing back to the element of the original object, not the element of the copy.
What is a better way to structure this object so shallow copies do not point back to the original object?
I have done a few hours of research. Not knowing exactly what words to google made this difficult to research. Please excuse me if this is something easy to fix.
I did review MDN on getters
and this page on self-referencing in objects. I understood it but I do not know how to use one.
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