顶层对象,在浏览器环境指window对象,在node指global对象。
1、顶层对象的属性
var和function关键字声明的全局变量,为顶层对象的属性;let、const和class关键字声明的全局变量,不属于顶层对象的属性。也就是说,从ES6开始,全局变量将逐步与顶层对象的属性脱钩。
var a = 1;
//this.a为通用方法
//如果在node的REPL环境,可以写成global.a
console.log(this.a); // 1
let b = 2;
console.log(this.b); //undefined
2、globalThis对象
顶层对象在各种实现里是不统一的:
在浏览器,顶层对象是window;
在浏览器和Web Worker,self也指向顶层对象;
在Node,顶层对象是global。
同一段代码为了在各环境下都能取到顶层对象,一般使用this变量的通用方法,但是this并不是都能够取得到顶层对象的,比如:
事件函数内部的this指向事件源,但是事件函数内的普通函数的this指向顶层对象;
对象的方法内的this在方法调用时指向对象。
所以,很难在所有情况下,都能取到顶层对象。会有这样两种方法:
// 方法一
(typeof window !== 'undefined'
? window
: (typeof process === 'object' &&
typeof require === 'function' &&
typeof global === 'object')
? global
: this);
// 方法二
var getGlobal = function () {
if (typeof self !== 'undefined') { return self; }
if (typeof window !== 'undefined') { return window; }
if (typeof global !== 'undefined') { return global; }
throw new Error('unable to locate global object');
};
但比较繁琐。
ES2020便在语言标准层面,引入globalThis作为顶层对象,任何环境下,globalThis都是存在的,都可以取到顶层对象。