18

I want to write a series of JavaScript related articles/tutorials. I was looking up the ECMA specification when I discovered this interesting paragraph.

As ECMA-262 (Version 6) states:

4.3.7 exotic object

object that does not have the default behaviour for one or more of the essential internal methods that must be supported by all objects

NOTE Any object that is not an ordinary object is an exotic object.

Now I am curious. Are such exotic objects to be found in modern browser's JavaScript?

If so: Could one give me an example and tell in how far its behaviour is different from 'ordinary objects'?

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
Tim Hallyburton
  • 2,741
  • 1
  • 21
  • 29
  • 4
    In DOM API host land, the `HTMLElement.dataset.prototype` object has magic getters and setters, which behave different than ordinary objects. – user3459110 Jul 29 '15 at 19:18
  • 2
    [document.all](https://html.spec.whatwg.org/multipage/obsolete.html#dom-document-all) – Knu Jul 29 '15 at 19:54
  • 1
    Definition in the Living Standard: [Exotic Object](https://tc39.es/ecma262/#exotic-object) – cachius May 07 '22 at 21:52

3 Answers3

18

A possible example:

The instance objects created by Array are exotic (a term used by the ECMAScript specification for objects that have features that normal objects don’t have): Their property length tracks and influences the management of array elements. In general, exotic objects can be created from scratch, but you can’t convert an existing normal object into an exotic one.

Taken from http://www.2ality.com/2015/02/es6-classes-final.html

There's also a list later in the spec including Array, String, and so on.

They're not "exotic" in the sense of mysterious and/or sexy.

Dave Newton
  • 158,873
  • 26
  • 254
  • 302
  • what do you mean by "features that normal objects don’t have"? finally there are some built-in codes(ex: for length tracks of an array) which normal objects could have. – Mehdi Raash Jan 08 '16 at 12:28
  • @Vandaad *Could* have, yes. Although`length` does more than just track the length. E.g., http://stackoverflow.com/a/31550694/438992, and from the spec: "An exotic object is any form of object whose property semantics differ in any way from the default semantics." I think people are reading too much into the word "exotic". – Dave Newton Jan 08 '16 at 13:44
  • 1
    I have just been reading about `Bound Functions` https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_objects/Function/bind - These are exotic object too. Out of interest, could we also say these objects are `Tropical` and `Temperate`? – Luke T O'Brien Jun 22 '17 at 10:56
  • Plus one for the mysterious and/or sexy clarification. XD – DeltaTango Jul 22 '20 at 20:14
8

Section 9.4 of the same document lists exotic objects. For example an array is such an object. Among other things, it's [[DefineOwnProperty]] internal method is different from the standard method defined for objects in that it treats numerical "keys" differently.

Amit
  • 45,440
  • 9
  • 78
  • 110
  • And to give an overview of the types in that section, the following exotic object types are recognized: bound functions, arrays, string, arguments, integer indexed (apparently related to array buffers), module namespace, and proxy. A longer summary is here: https://www.quora.com/What-are-some-examples-of-ES6-JavaScript-exotic-objects – Brett Zamir Jan 24 '17 at 22:37
3

DOM arrays vs Array

if you try in a browser document.getElementsByTagName('*') the result looks to be an Array object containing all the DOM elements matching your query. But on that Array you cannot call most Array functionality as it's not really an Array.

here is a example :

var normalArray = [{objectId: 1}, {objectId: 2}, {objectId: 3}, {objectId: 4}];
var domArray = document.getElementsByTagName('*');

log(normalArray.length + ' objects in normalArray');
printArray(normalArray);
log(domArray.length + ' objects in domArray');
printArray(domArray);

function printArray(array){
  // lets try with array
  try{
    array.forEach(function(data, index){
      log('Iteration on ' + index + ' ok', 'success');  
    });
  }catch(e){
    log('failed because of ' + e, 'error');
  }
}

function log(msg, className){
  var logEl = document.createElement('pre');
  logEl.innerText = msg;
  logEl.className = className || '';
  document.getElementById('logs').appendChild(logEl);
}
pre{
  background: #eee;
  padding: 3px;
  margin: 1px;
  border-radius: 3px;
}

pre.error{
  background: #fdd;
}

pre.success{
  background: #dfd;
}
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>some test</title>
    </head>
    <body>
        <h1>title</h1>
        <p>
            Some texts with some <a href="#">links</a>
        </p>
      
        <div id="logs"></div>
    </body>
</html>
zeachco
  • 754
  • 4
  • 16
  • What's the point in this snippet? Are you trying to say that `domArray` is exotic because it doesn't have a `forEach` function defined? (Hint: that's not a "requirement" for ordinary objects) – Amit Jul 29 '15 at 19:45
  • 5
    `getElementsByTagName` and similar methods return a `NodeList`, not an Array. – Lesleh Jul 29 '15 at 19:46
  • I misunderstood that definition I guess, can we define `essential internal methods` then, I would like to know too. – zeachco Jul 30 '15 at 16:19