后者是否只是引用由自定义构造函数创建的非原始函数对象(例如,var bird1 = new Bird();)?
答案 0 :(得分:124)
这两个术语都在ECMAScript规范中定义:
原生对象
ECMAScript实现中的对象,其语义是完全的 由本规范而不是主机环境定义。
注意本规范中定义了标准本机对象。一些 本机对象是内置的;其他人可能会在期间建造 执行ECMAScript程序的过程。
来源:http://es5.github.com/#x4.3.6
主持人对象
由主机环境提供的对象来完成 ECMAScript的执行环境。
注意任何非本机对象都是主机对象。
来源:http://es5.github.com/#x4.3.8
一些例子:
原生对象:Object
(构造函数),Date
,Math
,parseInt
,eval
,字符串方法,如indexOf
和{{ 1}},数组方法,......
主机对象(假设浏览器环境):replace
,window
,document
,location
,history
,XMLHttpRequest
,{{1 },setTimeout
,...
答案 1 :(得分:22)
我们更清楚地区分三种对象:
内置对象:String
,Math
,RegExp
,Object
,Function
等。 - 核心预定义对象始终以JavaScript提供。在ECMAScript规范中定义。
主机对象:由window
,XmlHttpRequest
,DOM节点等对象组成,这些对象由浏览器环境提供。它们与内置对象不同,因为并非所有环境都具有相同的主机对象。如果JavaScript在浏览器之外运行,例如作为Node.js中的服务器端脚本语言,则可以使用不同的主机对象。
用户对象:JavaScript代码中定义的对象。所以你的例子中的'Bird'将是一个用户对象。
JavaScript规范将内置对象和用户对象组合为本机对象。这是术语“本机”的非正统用法,因为用户对象显然是用JavaScript实现的,而内置函数很可能是用不同的语言实现的,就像宿主对象一样。但是从JavaScript规范的角度来看,内置和用户对象都是JavaScript本机的,因为它们是在JavaScript规范中定义的,而主机对象则不是。
答案 2 :(得分:17)
这是我对规范的理解。
此:
var bird = new Bird();
...导致原始对象恰好是使用new
运算符创建的。
本机对象具有以下之一的内部[[Class]]属性:
“Arguments”,“Array”,“Boolean”,“Date”,“Error”,“Function”,“JSON”,“Math”,“Number”,“Object”,“RegExp”,和“字符串”。
对于bird1
,它将是:
“对象”
就像你创建一个函数一样:
function my_func() {
// ...
}
... my_func
未在ECMAScript中定义,但它仍然是内部[[Class]]的本机对象:
“功能”
宿主对象是环境提供的对象,以便为规范中未定义的环境提供特定目的。
例如:
var divs = document.getElementsByTagName('div')
divs
引用的对象是一个 NodeList ,它以一种常规JavaScript对象的方式集成到环境中,但它没有在任何地方定义规范。
其内部[[Class]]属性为:
“节点列表”
这为实现设计人员提供了一些灵活性,使其能够满足环境的特定需求。
在整个规范中定义了主机对象的要求。
答案 3 :(得分:3)
无法看到var bird1 = new Bird();
是本地对象还是宿主对象这一问题的令人信服的答案。假设Bird是用户定义的函数,则javascript实现将根据http://es5.github.io/#x13.2创建本机非内置对象。相比之下,自javascript程序(例如Object和许多其他程序)启动以来,将存在本机内置对象。本机对象和主机对象之间的区别在于前者是由javascript实现创建的,而后者是由主机环境提供的。因此,宿主对象内部[[class]]属性可以与内置对象使用的属性不同(即"参数","数组","布尔&#34 ;,"日期","错误","功能"," JSON","数学",&#34 ; Number"," Object"," RegExp"和" String")。
另外,值得注意的是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实现指定和提供的对象
答案 4 :(得分:2)
除了有关主机对象的其他答案外。
主机对象特定于环境。那么接下来的浏览器主机对象,还有nodejs的特定对象。
为了示例,首先从Javascript中定义的Standard对象开始。然后是Browser / DOM的常用对象。 Node拥有它自己的对象。
标准Javascript 内置对象示例:
主机对象文档对象模型示例:
Node.js 中的主机对象:
答案 5 :(得分:1)
考虑三个对象:Host,Native,Custom。
主机对象由环境创建,并且是特定于环境的。最知名的环境是网络浏览器,但可能是另一个平台。在Web浏览器中创建的主机对象可以是窗口对象或文档。通常,浏览器使用API来创建主机对象以将文档对象模型反映到JavaScript中。 (Webbrowser使用不同的JavaScript引擎执行此操作)主页对象在页面呈现在浏览器中时自动创建。
开发人员使用预定义的JavaScript类创建本机对象。本地对象在您的书面脚本中。
然后,开发人员从自定义(非预定义或部分预定义)类创建自定义对象。
答案 6 :(得分:0)
原生对象是符合规范的对象,即“标准对象”。
主机对象是浏览器(或节点等其他运行时环境)提供的对象。
大多数宿主对象都是本机对象,每当使用new
实例化某些东西时,你可以99.99%确定它是一个原生对象,除非你乱用奇怪的宿主对象。
由于IE (以及其他旧浏览器?)中存在非常奇怪的对象,因此引入了这个概念。例如:
typeof document.all == "undefined"; // true
document.all.myElementId; // object
当看到这个时,每个人都会同意document.all
显然是“非标准的”,因此是非原生的主机对象。
那么为什么不首先调用本机对象标准对象?简单:毕竟,Standard(!) document也谈论非本地对象,并将它们称为非标准会导致矛盾。
再次:
答案 7 :(得分:0)
这可能过度,但为简单起见,本机对象是存在的,可用于实现ECMAScript兼容引擎的任何环境中。这通常是(但不总是)浏览器。
因此,您的Internet Explorer或Google Chrome不会使String对象可用。您可以使用String对象的原因是因为它是JavaScript语言本身的“本机”(内置)。
但是,如果您想创建一个弹出窗口,则需要使用window对象。窗口对象由浏览器软件本身提供,因此它不是JavaScript的原生,但它是“浏览器对象模型”或BOM的一部分。