为何无需指定window对象即可访问window.document属性?
document而不用写window.document? 嘿,这个问题问到点子上了——很多JavaScript新手刚接触浏览器环境时都会有这个疑惑,其实背后是浏览器JS环境里全局对象与全局作用域的特殊绑定机制在起作用,我来给你拆解清楚:
1. window是浏览器的全局对象,它的属性自动成为全局变量
在浏览器的JavaScript运行环境中,window是顶层的全局对象。所有在全局作用域中声明的变量、函数,都会自动成为window的属性;反过来,window的所有可枚举属性,也会自动被挂载到全局作用域中,成为可以直接访问的全局变量。
document就是浏览器预定义好的window属性之一——它代表当前页面的文档对象模型。所以document本质上和你在全局作用域声明的变量一样,已经被添加到全局作用域里了,自然可以直接调用document.getElementById('one'),而不用写完整的window.document。
你可以自己验证一下:
console.log(document === window.document); // 输出 true,说明两者是同一个引用
2. JS的作用域链查找机制帮你省略了前缀
当你直接写document时,JavaScript引擎会按照作用域链从当前作用域开始向上查找这个标识符:
- 如果当前作用域里找不到
document,就往上一层作用域找; - 一直找到最顶层的全局作用域,而全局作用域里的
document就是window.document的引用,所以能直接访问到。
3. 自定义对象为什么不行?
你提到的自定义普通对象,比如:
const myCustomObj = { myProp: 'test' };
这里的myProp只是myCustomObj的属性,它并没有被挂载到全局作用域中。JS引擎在全局作用域里找不到myProp这个标识符,所以你必须写完整的myCustomObj.myProp才能访问到它——这和window的特殊绑定机制完全不同。
总结一下
浏览器为了方便开发者快速使用常用的API(比如document、console、alert等),把window的可枚举属性自动映射到了全局作用域中,让你可以直接调用这些属性而不用写window.前缀。这是浏览器JS环境特有的设计,在Node.js等其他JS环境里,全局对象是globalThis,机制类似但具体对象不同。
内容的提问来源于stack exchange,提问作者Artem

