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


90

后者是否仅引用由自定义构造函数创建的非原始函数对象(例如,var bird1 = new Bird();)?


2
本机对象在ECMAScript规范中定义,而宿主对象则未定义。
森那维达斯

6
new Image()举例来说,DOM元素是一个宿主对象。

@ŠimeVidas:您留下某些与您的答案相矛盾的评论吗?
user113716 2011年

@Ӫ_._Ӫ这就是我现在的事情:)
森那维达斯

1
@ŠimeVidas:您的评论指出,主机对象未在ECMAScript规范中定义。您的答案是“两者的定义在ECMAScript规范中”
user113716 2011年

Answers:


133

这两个术语均在ECMAScript规范中定义:

本机对象

ECMAScript实现中的对象,其语义由此规范而不是由主机环境完全定义。

注:本规范中定义了标准本机对象。一些本地对象是内置的。其他的可以在执行ECMAScript程序的过程中构造。

资料来源:http : //es5.github.com/#x4.3.6

宿主对象

主机环境提供的对象,以完成ECMAScript的执行环境。

注意任何非本地对象都是宿主对象。

来源:http//es5.github.com/#x4.3.8


一些例子:

本地对象:Object(构造函数), ,DateMathparseInteval串的方法,如indexOfreplace,阵列方法,...

主机对象(假设浏览器环境)windowdocumentlocationhistoryXMLHttpRequestsetTimeoutgetElementsByTagNamequerySelectorAll,...


8
也给他一些例子,本地对象:数组,字符串..,宿主对象:窗口...
Poelinca Dorin 2011年

1
自定义custructor呢?例如,我的帖子中的鸟形示例
ppecher 2011年

2
@ŠimeVidas:“然后它是一个宿主对象。” 那是不对的。请参阅此答案host object描述的定义。
user113716 2011年

1
ŠimeVidas:但是规范指出宿主对象的[[Class]]内部属性的值可以是任何字符串值,“ Arguments”,“ Array”,“ Boolean”,“ Date”,“ Error”, “功能”,“ JSON”,“数学”,“数字”,“对象”,“ RegExp”和“字符串”。Bird对象的内部[[Class]]属性将是'Object'或通过Object.prototype.toStringas呈现'[object Object]'
user113716 2011年

2
@ŠimeVidas,我不同意,如果Bird是用户定义的函数,则其语义是由ES规范“完全定义”的(函数对象如何工作,如何创建,执行,与new运算符一起使用等),等等。本机对象...我可能会放弃答案...
Christian C.Salvadó11年

28

如果我们区分三种对象,则更加清楚:

内置对象StringMathRegExpObjectFunction等-核心预定义的对象总是可以在JavaScript中。在ECMAScript规范中定义。

宿主对象windowXmlHttpRequest,DOM节点等等,这是由浏览器环境提供。它们与内置对象不同,因为并非所有环境都具有相同的宿主对象。如果JavaScript在浏览器外部运行(例如,像Node.js中那样作为服务器端脚本语言运行),则可以使用其他主机对象。

用户对象:用JavaScript代码定义的对象。因此,您的示例中的“ Bird”将是一个用户对象。

JavaScript规范将内置对象和用户对象组合为本地对象。这是术语“本机”的非常规用法,因为用户对象显然是用JavaScript实现的,而内置对象很可能是在幕后用其他语言实现的,就像宿主对象一样。但是从JavaScript规范的角度来看,内建函数和用户对象都是JavaScript固有的,因为它们是在JavaScript规范中定义的,而宿主对象则不是。


本机对象是指由javascript实现(引擎)创建的那些对象。内置对象与其他本机对象(用户对象)之间的区别在于,自从Javascript程序启动以来,就存在以前的对象,这些程序符合相关的ECMA规则。由于ECMA6(<ECMA6 ecma-international.org/publications/files/ECMA-ST/...),它不使用上述术语进行分类的对象。请参阅下面的答案。
jaaw

17

这是我对规格的理解。

这个:

var bird = new Bird();

...导致一个本机对象,该对象恰好是使用new运算符创建的。

本机对象具有以下之一的内部[[Class]]属性:

“参数”,“数组”,“布尔”,“日期”,“错误”,“函数”,“ JSON”,“算术”,“数字”,“对象”,“ RegExp”和“ String”

对于您bird1来说:

“目的”

就像您创建一个函数一样:

function my_func() {
    // ...
}

...my_func在ECMAScript中未定义,但是它仍然是带有内部[[Class]]的本机对象:

“功能”

宿主对象是环境提供的对象,用于为规范中未定义的环境提供特定的目的。

例如:

var divs = document.getElementsByTagName('div')

所引用的对象divsNodeList,它以一种感觉像普通的JavaScript对象的方式集成到环境中,但并未在规范的任何地方定义。

其内部[[Class]]属性为:

“ NodeList”

这为实施设计人员提供了一些灵活性,使其可以根据环境的特定需求实施实施。

在整个规范中定义了主机对象的要求。


2
+1,我同意你的看法,bird并且Bird原生对象,他们是一个用户自定义函数(Bird),和对象(bird)的函数作为构造的使用创建的,这一切的约束都在规范中定义。关于宿主对象,不要过分依赖[[Class]]内部属性,例如window.alert具有几乎所有实现的属性"Function"值,[[Class]]就拥有IE而言"Object",它仍然是宿主对象……
Christian C.SalvadóSep

感谢@CMS。是的,我不是要过分强调使用internal [[Class]]。只是将其用作对实现者如何解释不同类型对象的实际了解。那么window.alert,内部[[Class]]使用"Function"似乎违反了ES 5?
user113716 2011年

我正在尝试查看此操作,但是如果得到该div的类型,则divs/NodeList得到object。我猜我还不明白这一点,但是这不是使它成为本机对象吗?
Mark B

这是有帮助的。获取所有内容将window显示所有宿主对象
Mark B

Bird不是本机对象,因为ECMASCript标准未完全描述它的接口。真的就是这么简单。对象是本机,字符串是本机,但是用户定义或主机定义的对象不是本机。
Scott Marcus 2014年

3

对于本var bird1 = new Bird();机对象还是宿主对象,无法看到令人信服的答案。假设Bird是用户定义的函数,则将根据自javascript程序启动以来将出现的对象创建本机非内置对象(例如Object等)。本机对象和宿主对象之间的区别在于,前者是由javascript实现创建的,后者是由宿主环境提供的。结果,主机对象的内部[[class]]属性可以与内置对象使用的属性不同(例如,“参数”,“数组”,“布尔”,“日期”,“错误”,“函数”,“ JSON”,“ Math”,“ Number”,“ Object”,“ RegExp”和“ String”)。则JavaScript实现http://es5.github.io/#x13.2。相反,本机内置

另外,值得注意的是ECMA6 http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf不再使用本机和宿主对象术语。相反,它在下面定义了对象类型,并对其预期行为进行了更清晰的说明。

4.3.6普通物体

具有必须由所有对象支持的基本内部方法的默认行为的对象

4.3.7异物

不具有所有对象都必须支持的一个或多个基本内部方法的默认行为的对象注意任何非普通对象的对象都是一个外来对象。

4.3.8标准对象

该规范定义了其语义的对象

4.3.9内置对象

由ECMAScript实现指定和提供的对象


3

除了有关主机对象的其他答案。

主机对象特定于环境。因此,接下来浏览器的主机对象,还有针对nodejs的特定对象。

为了示例起见,首先从Javascript中定义的Standard对象开始。然后是浏览器/ DOM的通用对象。节点有它自己的对象。

  1. 标准Javascript内置对象示例:

  2. 主机对象文档对象模型示例:

  3. Node.js中的主机对象:


1

考虑三个对象:主机,本机,自定义。

主机对象是由环境创建的,并且是特定于环境的。最知名的环境是Web浏览器,但可能是另一个平台。在Web浏览器中创建的宿主对象可以是窗口对象或文档。通常,浏览器使用API​​创建主机对象,以将文档对象模型反映到JavaScript中。(Webbrowser具有执行此操作的不同JavaScript引擎)当页面在浏览器中呈现时,会自动创建一个宿主对象。

开发人员使用预定义的JavaScript类创建本机对象。本机对象在您的书面脚本中。

然后,开发人员通过自定义(未预定义或部分预定义)的类创建自定义对象。


0

原始对象是符合规范的对象,即“标准对象”。

主机对象是浏览器(或其他运行时环境,如Node)提供的对象。

大多数宿主对象都是本机对象,只要您使用实例化某些对象,new就可以99.99%确保它是本机对象,除非您弄乱了奇怪的宿主对象。

由于IE (和其他旧的浏览器?)中存在非常奇怪的对象,因此引入了此概念。例如:

typeof document.all == "undefined"; // true
document.all.myElementId; // object

看到这一点,每个人都会同意这document.all显然是“非标准的”,因此是非本地宿主对象。

那么为什么不首先将本机对象称为标准对象呢?很简单:毕竟,Standard(!)文档还讨论了非本地对象,将它们称为非标准对象会导致自相矛盾。

再次:

  • 本地==“标准”
  • 主机==由浏览器或Node或…提供
  • 大多数宿主对象是本机的,所有非宿主对象也是本机的

您在那里有些脱离轨道了。“大多数主机对象是本机”不正确。实际上,根据定义,所有主机对象都不是本机的。Native肯定是“标准”,但在语言规范中是标准,不是非同一般的标准。JavaScript(ECMASCript)定义了由浏览器和其他主机实现的多个接口/ API,例如:字符串,日期,MATH,布尔值,数字,JSON和XmlHTTP。这些对象可用,因为主机实现了ECMAScript兼容引擎并符合ECMA标准。
Scott Marcus 2014年

0

这可能是过大的,但为简单起见,本机对象是一个存在的对象,可在实现ECMAScript兼容引擎的任何环境中使用。通常是(但不总是)浏览器。

因此,例如,您的Internet Explorer或Google Chrome浏览器不会使String对象可用。之所以可以使用String对象,是因为它是JavaScript语言本身的“本机”(内置)。

但是,如果您想创建一个弹出窗口,则需要使用window对象。窗口对象是由浏览器软件本身提供的,因此它不是JavaScript固有的,而是“浏览器对象模型”或BOM的一部分。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.