I don't understand the difference between native objects and host objects in JavaScript. Does the latter simply refer to non-primitive function objects that were created by a custom constructor (e.g., var bird1 = new Bird();)?
Both terms are defined in the ECMAScript specification:
native object
object in an ECMAScript implementation whose semantics are fully
defined by this specification rather than by the host environment.
NOTE Standard native objects are defined in this specification. Some
native objects are built-in; others may be constructed during the
course of execution of an ECMAScript program.
Source: http://es5.github.com/#x4.3.6
host object
object supplied by the host environment to complete the
execution environment of ECMAScript.
NOTE Any object that is not native is a host object.
Source: http://es5.github.com/#x4.3.8
A few examples:
Native objects: Object (constructor), Date, Math, parseInt, eval, string methods like indexOf and replace, array methods, ...
Host objects (assuming browser environment): window, document, location, history, XMLHttpRequest, setTimeout, getElementsByTagName, querySelectorAll, ...
It is more clear if we distinguish between three kinds of objects:
Built-in objects: String, Math, RegExp, Object, Function etc. - core predefined objects always available in JavaScript. Defined in the ECMAScript spec.
Host objects: objects like window, XmlHttpRequest, DOM nodes and so on, which is provided by the browser environment. They are distinct from the built-in objects because not all environment will have the same host objects. If JavaScript runs outside of the browser, for example as server side scripting language like in Node.js, different host objects will be available.
User objects: objects defined in JavaScript code. So 'Bird' in your example would be a user object.
The JavaScript spec groups built-in objects and user objects together as native objects. This is an unorthodox use of the term "native", since user objects are obviously implemented in JavaScript while the built-ins is most likely implemented in a different language under the hood, just as the host objects would be. But from the perspective of the JavaScript spec, both builtins and user objects are native to JavaScript because they are defined in the JavaScript spec, while host objects are not.
Here's my understanding of the spec.
This:
var bird = new Bird();
...results in a native Object that simply happened to be created using the new operator.
Native objects have an internal [[Class]] property of one of the following:
"Arguments", "Array", "Boolean", "Date", "Error", "Function", "JSON", "Math", "Number", "Object", "RegExp", and "String".
For your bird1 it will be:
"Object"
Just like if you create a function:
function my_func() {
// ...
}
...my_func isn't defined in ECMAScript, but it is still a native object with the internal [[Class]]:
"Function"
A host object is an object provided by the environment in order to serve a specific purpose to that environment not defined in by the specification.
For example:
var divs = document.getElementsByTagName('div')
The object referenced by divs is a NodeList, which is integrated into the environment in such a manner that it feels like a regular JavaScript object, yet it isn't defined anywhere by the specification.
Its internal [[Class]] property is:
"NodeList"
This provides implementation designers some flexibility in suiting the implementation to the specific need of the environment.
There are requirements of host objects that are defined throughout the spec.
In addition to the other answers regarding Host Objects.
Host objects are specific to a environment. So next to the browsers' host objects, there are also specific objects in nodejs.
For the sake of the example, first starting with the Standard objects as defined in Javascript. Then the common objects for the Browser/DOM. Node has it's own Objects.
Standard Javascript built-in object examples:
Object
Function
Boolean
Symbol
Number
Math
... (See full list on MDN web docs)
Host Objects Document Object Model Examples:
Window
Document
History
... (See full list on DOM objects on MDN web docs)
XMLHttpRequest (part of Web API)
... (See full list Web API on MDN web docs)
Host Objects in Node.js:
http
https
fs
url
os
... (See full list on nodejs.org)
Could not see a convincing answer to the question whether var bird1 = new Bird(); is a native or host object. Assuming Bird is a user defined function, a native non-built-in object will be created according to http://es5.github.io/#x13.2 by the javascript implementation. In contrast, native built-in objects will be present since the start of a javascript program (such as Object and many others). A difference between a native object and a host object is that former is created by the javascript implementation and the latter is provided by the host environment. As a result host object internal [[class]] property can be different from those used by built-in objects (i.e. "Arguments", "Array", "Boolean", "Date", "Error", "Function", "JSON", "Math", "Number", "Object", "RegExp", and "String").
Also, worthwhile noting that ECMA6 http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf does not use the terminology native and host objects any more. Instead, it defines below object types, with more clear explanations of their intended behaviour.
4.3.6 ordinary object
object that has the default behaviour for the essential internal methods that must be supported by all objects
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.
4.3.8 standard object
object whose semantics are defined by this specification
4.3.9 built-in object
object specified and supplied by an ECMAScript implementation
Considering three objects: Host, Native, Custom.
Host Objects are created by the environment and are environment specific. Best known environment would be a web-browser but could be another platform. The host objects created in web-browser could be the window object or the document. Typically a browser uses an API to create Host Objects to reflect the Document Object Model into JavaScript. (Webbrowser have different JavaScript Engines that do this) A host object is created automatically the moment the page renders in a browser.
A Native Object is created by the developer using predefined classes of JavaScript. Native Objects are in your written script.
Than, a Custom Object is made by the developer from a custom (not predefined, or partially predefined) class.
Native objects are objects that adhere to the specs, i.e. "standard objects".
Host objects are objects that the browser (or other runtime environment like Node) provides.
Most host objects are native objects, and whenever you instantiate something using new, you can be 99.99% sure that it is a native object, unless you mess around with weird host objects.
This notion has been introduced due to the presence of very bizarre objects in IE(and other old browsers?). For example:
typeof document.all == "undefined"; // true
document.all.myElementId; // object
When seeing this, everyone would agree that document.all is clearly "non-standard", and thus a non-native host object.
So why not call native objects standard objects in the first place? Simple: after all, the Standard(!) document talks about non-native objects too, and calling them non-standard would lead to a paradox.
Again:
native == "standard"
host == provided by the browser or Node or …
most host objects are native, and all non-host objects are native too
This may be overkill, but for simplicity a native object is one that exist and is usable in any environment that implements an ECMAScript compliant engine. This is usually (but not always) a browser.
So, your Internet Explorer or your Google Chrome, doesn't make the String object available to you, for example. The reason you can use the String object is because it is "native" (built-in) to the JavaScript language itself.
However, if you'd like to create a pop-up window, you'll need to use the window object. The window object is provided by the browser software itself, so it is not native to JavaScript, but it is part of the "Browser Object Model" or the BOM.
Related
Is there any way to reliably whether a JavaScript object is an exotic object type, and if so what its type is?
By "exotic", I mean (for the purposes of this question) anything which is could not be created using Object.create. This includes everything the ES2016 spec defines as exotic (any "object that does not have the default behaviour for one or more of the essential internal methods") plus anything created by the ObjectCreate specification method with a non-empty internalSlotsList, plus any kind of host object.
By "reliable", I mean not subject to being tricked by adding / removing properties from the object, using Object.create or Object.setPrototypeOf to give the object an unexpected prototype, modifying the object's ##toStringTag, or a constructor's ##hasInstance. This is important for library functions that need to correctly handle arbitrary user data.
(This means, in particular, that instanceof and Object.prototype.isPrototypeOf() are not useful. For example: var a = Object.create(Array.prototype) makes a something that looks and smells like an array—a instanceof Array === true and a.push and a.pop work as expected—but lacks the magic behaviour .length and is easily shown not to be an actual array exotic: Array.isArray(a) === false.)
By "type", I mean roughly what the ECMAScript 5.1 language specification referred to as [[Class]] - i.e., that quality that separates an Array instance, with its special [[DefineOwnProperty]] behaviour, from an ordinary Object.
Examples
Some cases are pretty easy:
Array exotic objects can be reliably detected using Array.isArray(a).
Functions can be reliably detected using typeof f === 'function'.
But is there any way to detect if a function is a bound function, native function or closure?
Some other exotic objects can be reliably detected by careful application of methods from their prototype object, e.g.
Sets can be detected by calling Set.prototype.has.apply(s, undefined), and seeing whether it throws a TypeError or not.
Is there any general way to make such a detection?
In particular:
Is there any general way to determine whether an object is plain or exotic?
Is there any general way to determine the type of an exotic object?
I note that Object.toString.apply(o) used to work reasonably well for this purpose: although in many browsers it would lie about the type of host objects, for all the types defined in the ES 5.1 spec it could be counted on to reliably tell you whether the object was a plain [object Object] or an exotic [object <Type>]. In ES6 and later, however, modifying ##toStringTag will subvert this test.
A means of detection which works in any conformant JS implementation would be ideal, but a means that is specific to Node.js would still be useful.
But is there any way to detect if a function is a bound function, native function or closure?
No. They are all plain and simple functions.
Some other exotic objects can be reliably detected by careful application of methods from their prototype object, e.g.
Sets can be detected by calling Set.prototype.has.apply(s, undefined), and seeing whether it throws a TypeError or not.
You can use the instanceof operator to test if an object is an instance of a particular function constructor (or something up its prototype chain).
var mySet = new Set();
console.log(mySet instanceof Set);
I'm currently learning JavaScript using the Mozilla Developer Network as a reference.
It confuses me that MDN refers to objects as interfaces.
For example: Document.createTreeWalker()
At the bottom, there is a link to the TreeWalker Object, but it says:
The interface of the object it creates: TreeWalker
How can TreeWalker be an interface if I can instantiate it?
And TreeWalker is only an example, almost every object in MDN is referred to as an interface.
I come from a Java background, so the use of interface in this context is not clear to me. Does interface in JavaScript mean something different than in Java?
"interface" arises in this context because that is the term used in standards applicable to the (javascript) object being described on MDN.
Web standards use an interface definition language or IDL described in Web IDL to describe the behavior of browser objects independent of the language, e.g. javascript, used to manipulate them. Hence TreeWalker is documented as an "interface" in the Document Object Model (DOM) Level 2 Traversal and Range Specification
So in a sense MDN is simply using the vocabulary of the standard which defines the interface exposed by the browser object it is describing. To what extent the subject of the documentation would be described as an "interface" in another language might vary on a case by case basis.
C.F. the definition of interface used in web standards.
No, javascript doesn't really have a true interface type or anything. The createTreeWalker() function simply uses Object.create to return on object.
See also:
How to implement interface in javascript
Does JavaScript have the interface type (such as Java's 'interface')?
There isn't a true interface built into JavaScript. It seems like they are referring to an object that gets inherited from as the interface. In your example Document.createTreeWalker() returns an instance of the TreeWalker object.
// myTreeWalker is your object. TreeWalker is the interface.
var myTreeWalker = Document.createTreeWalker()
In terms of the language what do I get back when I grab an element from the DOM as such:
var obj = document.getElementById('foo');
It has properties, so I thought that maybe it might be an object literal. Using type checks I determined that it is not an object literal, it is also not an array literal.
I know what it is used for, and how to use it, just not what it is, technically speaking in terms of the language.
I ran it through this test which I call a test for an abstract object.
obj === Object(obj);
which it returned false.
I know that I can identify node elements as such
obj.nodeType === 1
but still this doesn't tell me what it is, in terms of the language (ES5). What is an element expressed in terms of the language?
Clarification
I mean the language, based on a grammar, JavaScript, the Good
Parts, Chapter 2, This grammar only knows how to deal with language
components, arrays, objects, etc.
Element is not defined in terms of ES5. It is a part of the DOM API.
Here is its definition
The Element interface represents an element in an HTML or XML document.
A language does not have to implement the ES5 specification to implement the DOM API interface, moreover - ES5 implementations can be valid and not implement Element. For example, NodeJS does server side JavaScript and does not implement Element.
In terms of the ECMAScript specification, DOM Elements are "host objects" provided by the browser's host environment (emphasis mine below):
ECMAScript as defined here is not intended to be computationally self-sufficient; indeed, there are no provisions in this specification for input of external data or output of computed results. Instead, it is expected that the computational environment of an ECMAScript program will provide not only the objects and other facilities described in this specification but also certain environment-specific host objects, whose description and behaviour are beyond the scope of this specification except to indicate that they may provide certain properties that can be accessed and certain functions that can be called from an ECMAScript program.
The particular properties of DOM elements are specified by the interfaces laid out in the W3C's DOM specification, not by the ECMAScript spec (although the ECMAScript spec allows for them to exist, by allowing for environment-supplied host objects).
Addendum:
You have added some clarification that your confusion stems from the fact that JavaScript uses a grammar. I'm having a hard time understanding why that causes confusion for you, but I'll try to clear things up.
JavaScript's grammar is lexical, i.e., it deals with written code. That written code is parsed (using a grammar) and the parser identifies particular expressions in the code. Those expression correspond to programmatic operations in the execution environment.
The grammar that is used to refer to a host object is identical to the grammar used to refer to a native object. In fact, a host object is an object. The only difference is that a host object can specify the behavior of its internal methods, like [[Get]] (used for property access).
I am currently learning advanced JavaScript, with an aim to build a standards compliant (HTML5, CSS3, ESv5) library. Along my way I have already asked a couple of related questions to try and figure out where to start, what to do, what not to do, what to avoid etc. I have already begun reading the ECMA-262 (ECMAScript version 5) documentation, and have been running a few tests before I get started on development work.
Previous questions:
Writing ECMAScript5 compliant code
What's the difference between JavaScript, JScript & ECMAScript?
In my research I found out that different browsers implement the standard differently, and in that respect, they implement different objects. For example, IE implements an object called ActiveXObject, but this is not the case in FireFox. So I wrote a little test facility which determines if something is defined within the browser.
Consider the following which tests a few known objects (including jQuery since this is not built in).
Again, I have reached a point where I am in need of help:
Questions:
Given the example above, what is the difference between an object and a function?
Do I write functions or objects in ES/JS?
Why is Object a function and not an object?
Is there any hierarchical structure to built in objects / functions?
Can built in objects / functions be redefined as something entirely different?
Can built in objects / functions be undefined?
Can built in objects / functions be assigned new features if they do not already support them natively?
If an object is defined in one browser and not another, how can I compensate for this?
P.S. I do not want answers relating to specific implementations (JavaScript/JScript), rather answers relating to the standard (ECMAScript v5). Thanks in advance!
Given the example above, what is the difference between an object and a function?
In Chrome, all these items are functions. In general however, a function is an object with the addition that it holds code and that you can call it. So, you can also just add properties to functions (like jQuery does: $("selector") or $.ajax).
Do I write functions or objects in ES/JS?
Well, obviously that depends on what you code. function() {} gives you a function; {} gives you an object. (Again, functions are objects in the end.)
Why is Object a function and not an object?
Object is a function because you can call it, either as a constructor or not:
Object(); // returns an empty object
new Object(); // same
Also, given that almost everything is an instance of Object, it follows that Object is a constructor and thus a function. (Note again that functions are also objects.)
Is there any hierarchical structure to built in objects / functions?
As for the ECMAScript built-in objects, there is in a sense. There are constructor functions (String) on the global object, functions for instances (Array.prototype.forEach), and "static" functions (Object.defineProperty which is meant to be used on objects, Array.isArray for arrays).
Can built in objects / functions be redefined as something entirely different?
Sure, you can do Object = null. But any code relying on Object will start throwing exceptions, so it's not recommended at all.
Can built in objects / functions be undefined?
No, an object is not undefined by definition. undefined is not an object and vice-versa. This holds for any object.
Can built in objects / functions be assigned new features if they do not already support them natively?
Yes, if e.g. Array.prototype.forEach does not exist, you could set it yourself. But it should be noted that such functions turn up in for(var key in arr) loops which again can cause code to behave differently. This can be solved using Object.defineProperty by using {enumerable: false}. But there is another caveat: the function is shared across the whole environment (e.g. the current page). If other code is also setting them you're experiencing collisions.
If an object is defined in one browser and not another, how can I compensate for this?
You can "shim" such functions. For e.g. ES5 functions such as Array.prototype.forEach there are shims available which make them available on older browsers as well. Underscore.js may be a good example.
Given the example above, what is the difference between an object and a function?
A function is just an object which is callable. However, I guess you ask for the types of host objects (Node, HTMLCollection etc): Their behaviour is implementation-dependent ("not ecmascript-native") - you can't rely on anything.
Do I write functions or objects in ES/JS?
Huh? You write code, which can be interpreted.
Why is Object a function and not an object?
Object is the native object constructor, and therefore a function (and also an Object).
Is there any hierarchical structure to built in objects / functions?
Do you ask for "Everything is an Object"? If you ask for the structure of DOM interfaces: They are implementation-dependent host objects again, but most implementors have a inheritance system based on the DOM specification.
Can built in objects / functions be redefined as something entirely different? Can built in objects / functions be undefined?
No. You can overwrite the global variables pointing to them (the properties of the global object), but every instance will nevertheless be constructed from the native (then [nearly] unaccessible) constructors.
Can built in objects / functions be assigned new features if they do not already support them natively? If an object is defined in one browser and not another, how can I compensate for this?
Yes, you can extend the native objects and their prototypes. But watch out for host objects, they might not like it. If an object is defined only in certain environments, you can easily test for its existance and possibly shim it (es5, html5).
As part of my research into ECMAScript / JavaScript, I have found the following resource which provides a lot of information regarding the JS DOM.
http://krook.org/jsdom/index-all.html
I suppose a definition of native and built-in objects is required to answer this question. Here's what the ECMAScript spec defines these as:
4.3.6 native object
object in an ECMAScript implementation, independent of the host environment, that is present at the start of
the execution of an ECMAScript program.
NOTE Standard native built-in objects are defined in this
specification. Some native objects are built-in; others may be
constructed during the course of execution of an ECMAScript program
4.3.7 built-in object
object supplied by an ECMAScript implementation, independent of the host environment, that is present
at the start of the execution of an ECMAScript program
NOTE Standard built-in objects are defined in this specification,
and an ECMAScript implementation may specify and define others. Every
built-in object is a native object. A built-in constructor is a
built-in object that is also a constructor.
I'm looking forward to an explanation of this one.
Here is what ES5 shows:
4.3.6
native object # Ⓣ
object in an ECMAScript implementation whose semantics are fully defined by this specification rather than by the host environment.
NOTE Standard native objects are defined in this specification. Some native objects are built-in; others may be constructed during the course of execution of an ECMAScript program.
4.3.7
built-in object # Ⓣ
object supplied by an ECMAScript implementation, independent of the host environment, that is present at the start of the execution of an ECMAScript program.
NOTE Standard built-in objects are defined in this specification, and an ECMAScript implementation may specify and define others. Every built-in object is a native object. A built-in constructor is a built-in object that is also a constructor.
As you can see, it's different that what you've shown.
Built-in objects are native objects made available by the ECMAScript-compliant engine. For example:
String
Object
Array
Undefined
Boolean
etc.
A native object is, for example:
var obj = {};
Or the list shown before. Built-in objects are native.
Also, you didn't show it, but a host object is an object dependant on the environment. For example, in browsers, the host object is window. There are other host objects such as document or XMLHttpRequest though.
Native object - means implemented not in ECMAScript itself. Buiilt-in object - the one that's provided by the engine. Think Math, String and such.