Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does AngularJS not use instanceof in its isArray function?

From AngularJS isArray source:

return toString.call(value) === '[object Array]';

Why did they not go with?

return value instanceof Array;
like image 951
Ben Aston Avatar asked Feb 12 '23 06:02

Ben Aston


1 Answers

Because if you receive an array from a different window (e.g., another frame or iframe, a child window, a parent window, etc.), it won't be instanceof the Array constructor in your window.

This is why in ES5 they added the Array.isArray function to JavaScript, so we could stop doing it the hard way, which looks like this:

if (Object.prototype.toString.call(theArray) === "[object Array]") ...

Example of the various aspects of this: Live Copy

Parent window:

<body>
  <input type="button" value="Click To Open Window">
<script>
  (function() {
    "use strict";

    var wnd;

    document.querySelector("input").onclick = function() {
      wnd = window.open("http://jsbin.com/yimug/1");
      display("Opened, waiting for child window to load...");
      setTimeout(waitForChild, 10);
    };

    function waitForChild() {
      if (wnd && wnd.sendMeSomething) {
        display("Child window loaded, sending [1, 2, 3]");
        wnd.sendMeSomething([1, 2, 3]);
      }
    }

    function display(msg) {
      var p = document.createElement('p');
      p.innerHTML = String(msg);
      document.body.appendChild(p);
    }
  })();
</script>
</body>

Child window:

<script>
  (function() {
    "use strict";

    window.sendMeSomething = function(something) {
      display("Got " + something.join(", "));
      display("something instanceof Array? " + (something instanceof Array));
      display("Object.prototype.toString.call(something): " + Object.prototype.toString.call(something));
      if (Array.isArray) {
        display("Array.isArray(something)? " + Array.isArray(something));
      }
    };
    function display(msg) {
      var p = document.createElement('p');
      p.innerHTML = String(msg);
      document.body.appendChild(p);
    }
  })();
</script>

Output (in child window) (something is the name of the argument where it receives an array from the parent):

Got 1, 2, 3
something instanceof Array? false
Object.prototype.toString.call(something): [object Array]
Array.isArray(something)? true
like image 132
T.J. Crowder Avatar answered Feb 15 '23 09:02

T.J. Crowder