本机对象和宿主对象之间的区别是什么?

我不明白在 JavaScript 中 本地物体主机对象之间的区别。后者是否只是简单地引用由自定义构造函数(例如 var bird1 = new Bird();)创建的非原语函数对象?

54801 次浏览

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

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.

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.

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.

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.

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.

  1. Standard Javascript built-in object examples:
  1. Host Objects Document Object Model Examples:
  1. Host Objects in Node.js: