02 | 顶层对象和global对象
顶层对象的属性
顶层对象,在浏览器环境指的是window
对象,在Node指的是global
对象。ES5之中,顶层对象的属性与全局变量是等价的。
window.a = 1;
a // 1
a = 2;
window.a // 2
上面代码中,顶层对象的属性赋值与全局变量的赋值,是同一件事。
顶层对象的属性与全局变量挂钩,被认为是JavaScript语言最大的设计败笔之一。这样的设计带来了几个很大的问题,首先是没法在编译时就报出变量未声明的错误,只有运行时才能知道(因为全局变量可能是顶层对象的属性创造的,而属性的创造是动态的);其次,程序员很容易不知不觉地就创建了全局变量(比如打字出错);最后,顶层对象的属性是到处可以读写的,这非常不利于模块化编程。另一方面,window
对象有实体含义,指的是浏览器的窗口对象,顶层对象是一个有实体含义的对象,也是不合适的。
ES6为了改变这一点,一方面规定,为了保持兼容性,var
命令和function
命令声明的全局变量,依旧是顶层对象的属性;另一方面规定,let
命令、const
命令、class
命令声明的全局变量,不属于顶层对象的属性。也就是说,从ES6开始,全局变量将逐步与顶层对象的属性脱钩。
var a = 1;
// 如果在Node的REPL环境,可以写成global.a
// 或者采用通用方法,写成this.a
window.a // 1
let b = 1;
window.b // undefined
上面代码中,全局变量a
由var
命令声明,所以它是顶层对象的属性;全局变量b
由let
命令声明,所以它不是顶层对象的属性,返回undefined
。
global 对象
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');
};
现在有一个提案,在语言标准的层面,引入global
作为顶层对象。也就是说,在所有环境下,global
都是存在的,都可以从它拿到顶层对象。
垫片库system.global
模拟了这个提案,可以在所有环境拿到global
。
// CommonJS的写法
require('system.global/shim')();
// ES6模块的写法
import shim from 'system.global/shim'; shim();
上面代码可以保证各种环境里面,global
对象都是存在的。
// CommonJS的写法
var global = require('system.global')();
// ES6模块的写法
import getGlobal from 'system.global';
const global = getGlobal();
上面代码将顶层对象放入变量global
。
02 | 顶层对象和global对象的更多相关文章
- 第一百零八节,JavaScript,内置对象,Global对象字符串编码解码,Math对象数学公式
JavaScript,内置对象,Global对象字符串编码解码,Math对象数学公式 学习要点: 1.Global对象 2.Math对象 ECMA-262对内置对象的定义是:"由ECMASc ...
- JavaScript的内置对象(Global对象)
内置对象的定义 由 javaScript 实现提供的.不用自己创建,这些对象在 ECMAScript 程序执行之前就已经存在了. 意思就是说,开发人员不必显示地实例化内置对象:因为它们已经实例化了. ...
- CSS 换行问题white-space属性 window对象和global对象
white-space: nowrap禁止换行 1.word-wrap:break-word; 内容将在边界内换行,仅用于块对象,内联对象要用的话,必须要设定height.width或display: ...
- JavaScript的内置对象和浏览器对象
在javascript中对象通常包括两种类型:内置对象和浏览器对象,此外,用户还可以自定义对象. 对象包含两个要素:1.用来描述对象特性的一组数据,也就是若干变量,通常称为属性.2.用来操作对象特性的 ...
- Nodejs随笔(三):全局对象之global
首先,进入node REPL: mesogene@mesogene-team:~$ node > 查看global对象,发现其他全局对象(包括Buffer.require对象)以及全局方法都包含 ...
- JavaScript中的global对象,window对象以及document对象的区别和联系
JavaScript中的global对象,window对象以及document对象的区别和联系 一.概念区分:JavaScript中的global对象,window对象以及document对象 1.g ...
- 5.7.1.3 Global 对象的属性
Global对象还包含了一些属性,例如,特殊的值undefined.NaN以及Infinity都是Global对象的属性.此外,所有原生引用类型的构造函数,像Object和Function,也都是Gl ...
- 重操JS旧业第四弹:Date与Global对象
1 Date原理 Date类型表示时间,js中采用UTC国际协调时间,以1971年1月1日0分0秒0微秒开始,经过的毫秒数来表示时间,比如一年的时间计算 1分:1000*60: 1小时:1000(毫秒 ...
- node基础—global对象(全局对象)
global对象的__filename属性和__dirname属性 __filename属性:返回当前执行的文件的文件路径,该路径是经过解析后的绝对路径,在模块中,该路径是模块文件的路径,此属性并非全 ...
随机推荐
- 给你一个app,怎么测试
安装卸载 安装卸载路径是否能自己选择,在不同操作系统下(Android.ios)安装是否正常,能正常运行,安装的文件及文件夹是否写入了指定的目录里,安装来自不同来源的(应用宝.360助手)下是否正常. ...
- DeepDB:Learn From Data,not from Queries!
ABSTRACT DBMS典型学习方法的弊端:手机数据集的成本过高;工作方向或数据库发生改变时,必须重新收集数据.--------------解决:提出了一种新的数据驱动方式,直接支持工作负载和数据库 ...
- 基于预计算的全局光照(Global Illumination Based On Precomputation)
目录 基于图像的光照(Image Based Lighting,IBL) The Split Sum Approximation 过滤环境贴图 预计算BRDF积分 预计算辐射度传输(Precomput ...
- NOIP 模拟六 考试总结
T1辣鸡 T1就搞得这莫不愉快.. 大致题意是给你几个矩形,矩形覆盖的点都标记上,每个矩形无重复部分,求满足(x,y) (x+1,y+1)都标记过的点对数,范围1e9. 看起来很牛的样子,我确实也被1 ...
- 反调试--CRC检测
#include"CRC32.h" #include<Windows.h> #include<iostream> using namespace std; ...
- 从零入门 Serverless | 教你 7 步快速构建 GitLab 持续集成环境
作者 | 存诚 阿里云弹性计算团队 本文整理自<Serverless 技术公开课>,"Serverless"公众号后台回复"入门",即可获取系列文章 ...
- 【nvidia jetson xavier】 Deepstream Yolov3示例模型运行
作者声明 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 原文链接:https://www.cnblogs.com/phoenixash/p/15 ...
- Rigidbody钢体移动时抖动问题
Rigidbody移动时抖动问题 撞墙抖动 Unity中物体移动有非常多的方式: 比如: transform.position += dir*speed*Time.deltaTime; transfo ...
- mysql update语句的执行流程是怎样的
update更新语句流程是怎么样的 update更新语句基本流程也会查询select流程一样,都会走一遍. update涉及更新数据,会对行加dml写锁,这个DML读锁是互斥的.其他dml写锁需要等待 ...
- Windows系统安装Java步骤
今天学习到Burp Suite的使用,提示到安装Burp Suite需要安装Java环境. 于是乎,本弱鸡开启了漫长的Java环境安装之路~ 一.Java SE版本众多,在这里推荐下载Java1.8版 ...