I have a less then ideal situation in which I can not change the signature of a function but need to have it pass additional information in its output for a new feature.
Is this ok to do?
q = [ 1 , 2 ,3]
q.meta-data = {additional:'information'}
Is this only assigned to q?
Does this have any effect on other array objects?
Is there a situation where this would break something or will it continue to function as normal?
I have a less then ideal situation in which I can not change the signature of a function but need to have it pass additional information in its output for a new feature.
Is this ok to do?
q = [ 1 , 2 ,3]
q.meta-data = {additional:'information'}
Is this only assigned to q?
Does this have any effect on other array objects?
Is there a situation where this would break something or will it continue to function as normal?
6 Answers
Reset to default 3No, it doesn't assign anything to other arrays - as you work with a specific object here, not its prototype.
But yes, it can bite you back in some situations. For example, some other developer might think that it's a smart idea to iterate over that Array stored in q
with for-in
loop.
Why not just split the data and the meta-data into two properties?
q = {
data: [1, 2, 3],
'meta-data': { additional: 'information' }
};
If you assign a property to q
, that only affects just q
. Other arrays will be fine.
The only issue you'd have with this approach is if you use for..in
to loop over arrays. As long as you only ever loop over it with a "normal" for
loop or .forEach
(which you should be doing anyway), you shouldn't have any issues.
P.S. q.meta-data
is a syntax error (the -
). You need to do q.metadata
(or q.meta_data
) or q['meta-data']
.
The other answers are great, but you could also convert the array to an "array-like" object.
objq = {};
q.forEach(function (elem, idx) {
objq[idx] = elem;
});
objq.length = q.length;
objq["meta-data"] = {additional: "information"};
objq
does not have array methods, but you can call them:
Array.prototype.forEach.call(objq, function (elem) { console.log(elem); });
In case you don't want to create a wrapper for the data. It's a bit safer to attach meta data using symbols.
const data = [1, 2, 3];
// A "secret" key to obtain meta data.
const metaKey = Symbol();
data[metaKey] = {additional: 'information'}
// The meta does not appear in for-in anymore.
for (let item in data) {
console.log(item);
}
// But you still can obtain meta if you have access to the 'metaKey' variable.
console.log(data[metaKey]);
The main downside of this approach is that you need to pass the key to the consumer of this meta data.
I personally do not like adding properties to arrays since this can have unintended consequences. I would probably go with adding an addition parameter that acts as an output parameter. Something like this:
function cantChangeReturn(arg1, arg2, optionalOutputArg) {
// do stuff
if (optionalOutputArg) {
optionalOutputArg.extraResult = extraResult;
}
return result;
}
This way, the extra data does not leak to other parts of the program that do not need it and do not expect it.