最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Attaching meta data to arrays - Stack Overflow

programmeradmin2浏览0评论

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?

Share Improve this question asked Aug 28, 2013 at 17:28 James AndinoJames Andino 25.8k17 gold badges54 silver badges79 bronze badges
Add a ment  | 

6 Answers 6

Reset to default 3

No, 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.

发布评论

评论列表(0)

  1. 暂无评论