原生对象由ecmascript标准定义,如array、date等,跨环境兼容;宿主对象由运行环境提供,如浏览器的document、node.js的process,不可移植且行为不一致。

最直接的区分方式是看这个对象是不是由 JavaScript 语言规范(ECMAScript)明确定义的——是,就是原生对象;不是,而是由浏览器、Node.js 这类运行环境额外提供的,就是宿主对象。
看来源:谁定义的,谁提供的
原生对象是 ECMAScript 标准里白纸黑字写死的,比如 Array、Date、RegExp、Object、Promise、Map 等。只要环境声称“支持 ES2015+”,这些对象就必须存在,行为也基本一致。
宿主对象则完全由运行环境决定。浏览器提供 window、document、fetch、localStorage;Node.js 提供 global、process、Buffer、require。它们不在标准里,换环境就可能消失或行为不同。
看可移植性:能不能跨环境直接跑
一段只用 Array.prototype.map 和 JSON.parse 的代码,在浏览器、Node.js、甚至 Deno 里通常都能正常执行——因为它们是原生对象。
但一旦出现 document.getElementById 或 process.env.NODE_ENV,这段代码就绑定了特定环境。在 Node.js 里调用 document 会报 ReferenceError;在浏览器里访问 process 会是 undefined。
看构造方式和存在时机
原生对象大多支持字面量语法或 new 构造,比如 []、{}、/abc/、new Date()。它们在 JS 引擎启动时就已就绪,不依赖外部注入。
宿主对象通常无法用字面量创建,也不靠 new 实例化(少数例外如 new XMLHttpRequest() 是宿主构造函数)。它们是环境“塞进来”的全局变量,比如一打开浏览器控制台,window 就自动存在,你没写任何 new 或赋值语句。
一个小验证技巧:查 toString 输出
在控制台输入:
console.log([].toString()); // "[object Array]"<br>console.log(document.toString()); // "[object HTMLDocument]" 或类似<br>console.log(window.toString()); // "[object Window]"<br>console.log(Math.toString()); // "[object Math]"(Math 是内置对象,属原生)
注意括号里的类型名:Array、Math 是标准名称;HTMLDocument、Window 则明确标示了宿主环境特有身份。











