ES5顶层对象属性与全局对象关系
- 顶层对象在浏览器中指的是window对象;
- 在node环境中,指的是global对象;
-
在ES5中,顶层对象的属性与全局属性是等价的;
上面的代码中,顶层对象的赋值与全局变量的赋值是同一件事;
顶层对象的属性与全局变量相关的弊端
顶层对象的属性与全局变量相关,被认为是JavaScript语言中最大的设计败笔之一。这样的设计带来了几个很大的问题:
- 首先,无法在编译时就提示变量未声明的错误,只有在运行时才能知道,因为全局变量可能是顶层对象的属性创造的,而属性的创造是动态的
- 其次,程序员很容易不知不觉地就创建全局变量
- 最后,顶层对象的属性到粗都可以读写的,这样非常不利于模块化编程;
- window对象有实体含义,指的是浏览器的窗口对象,这样也是不合适的。
ES6的解决方案
ES6为了改变上面所说的问题,一方面规定,为了保持兼容性,var命令和function命令声明的全局变量依旧是顶层对象的属性;另一方面规定,let命令、const命令、class命令声明的全局变量不属于顶层对象的属性。也就是,从ES6开始,全局变量将逐步与顶层对象的属性隔离。
上面的代码中,全局变量是由let命令声明,所以它不是顶层对象的属性,返回undefined;
顶层对象本身的问题
es5的顶层对象本身的问题是,它在各种实现中是不统一的。
- 在浏览器中,顶层对象是window,但Node 和 Web Worker 没有window。
- 在浏览器和Web Worker中,self指向顶层对象,但是Node没有self。
- 在Node中,顶层对象是global,但其他环境都不支持。
同一段代码为了能够在各种环境中都取到顶层对象,目前一般是使用this变量,但是也有局限。
- 在全局环境中,this会返回顶层对象,但是,在Node模块和ES6模块中,this返回的是当前模块;