JS 顶层对象

发布于 2024-11-11 07:44:52 字数 1846 浏览 6 评论 0

定义

  1. 在浏览器环境指的是 window 对象,在 Node 指的是 global 对象, Web Worker 里面指的是 self 对象。
  2. ES5 之中,顶层对象的属性与全局变量是等价的。
  3. 因此顶层对象的属性赋值与全局变量的赋值,是同一件事

顶层对象的属性与全局变量挂钩,被认为是 JavaScript 语言最大的设计败笔之一。这样的设计带来了几个很大的问题,首先是没法在编译时就报出变量未声明的错误,只有运行时才能知道(因为全局变量可能是顶层对象的属性创造的,而属性的创造是动态的);其次,程序员很容易不知不觉地就创建了全局变量(比如打字出错);最后,顶层对象的属性是到处可以读写的,这非常不利于模块化编程。另一方面,window 对象有实体含义,指的是浏览器的窗口对象,顶层对象是一个有实体含义的对象,也是不合适的。

ES6 为了改变这一点,一方面规定,为了保持兼容性,var 命令和 function 命令声明的全局变量,依旧是顶层对象的属性;

另一方面规定,let 命令、const 命令、class 命令声明的全局变量,不属于顶层对象的属性。

也就是说, 从 ES6 开始,全局变量将逐步与顶层对象的属性脱钩

var a = 1
// 或者采用通用方法,写成 this.a
window.a // 1

let b = 1
window.b // undefined

获取顶层对象

ES5 的顶层对象,本身也是一个问题,因为它在各种实现里面是不统一的,浏览器里面,顶层对象是 window,但 Node 和 Web Worker 没有 window,浏览器和 Web Worker 里面,self 也指向顶层对象,但是 Node 没有 self,Node 里面,顶层对象是 global,但其他环境都不支持。

同一段代码为了能够在各种环境,都能取到顶层对象,现在一般是使用 this 变量,但是有局限性。

全局环境中,this 会返回顶层对象。但是,Node 模块和 ES6 模块中,this 返回的是当前模块。

函数里面的 this,如果函数不是作为对象的方法运行,而是单纯作为函数运行,this 会指向顶层对象。但是,严格模式下,这时 this 会返回 undefined。

不管是严格模式,还是普通模式,new Function('return this')(),总是会返回全局对象。但是,如果浏览器用了 CSP(Content Security Policy,内容安全策略),那么 eval、new Function 这些方法都可能无法使用。

综上所述,很难找到一种方法,可以在所有情况下,都取到顶层对象。下面是两种勉强可以使用的方法。

// 方法一
(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')
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

0 文章
0 评论
24 人气
更多

推荐作者

末蓝

文章 0 评论 0

年少掌心

文章 0 评论 0

党海生

文章 0 评论 0

飞翔的企鹅

文章 0 评论 0

鹿港小镇

文章 0 评论 0

wookoon

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文