@@ -448,7 +448,7 @@ if (true)
448448
449449上面代码中,块级作用域将两个语句封装在一起。但是,在块级作用域以外,没有办法得到` t ` 的值,因为块级作用域不返回值,除非` t ` 是全局变量。
450450
451- 现在有一个[ 提案] ( http://wiki.ecmascript.org/doku.php?id=strawman:do_expressions ) ,使得块级作用域可以变为表达式,也就是说可以返回值,办法就是在块级作用域之前加上` do ` ,使它变为` do ` 表达式。
451+ 现在有一个[ 提案] ( http://wiki.ecmascript.org/doku.php?id=strawman:do_expressions ) ,使得块级作用域可以变为表达式,也就是说可以返回值,办法就是在块级作用域之前加上` do ` ,使它变为` do ` 表达式,然后就会返回内部最后执行的表达式的值 。
452452
453453``` javascript
454454let x = do {
@@ -457,7 +457,7 @@ let x = do {
457457};
458458```
459459
460- 上面代码中,变量` x ` 会得到整个块级作用域的返回值。
460+ 上面代码中,变量` x ` 会得到整个块级作用域的返回值( ` t * t + 1 ` ) 。
461461
462462## const 命令
463463
@@ -571,11 +571,11 @@ var constantize = (obj) => {
571571
572572### ES6 声明变量的六种方法
573573
574- ES5 只有两种声明变量的方法:` var ` 命令和` function ` 命令。ES6除了添加 ` let ` 和` const ` 命令,后面章节还会提到,另外两种声明变量的方法:` import ` 命令和` class ` 命令。所以,ES6 一共有6种声明变量的方法。
574+ ES5 只有两种声明变量的方法:` var ` 命令和` function ` 命令。ES6 除了添加 ` let ` 和` const ` 命令,后面章节还会提到,另外两种声明变量的方法:` import ` 命令和` class ` 命令。所以,ES6 一共有6种声明变量的方法。
575575
576576## 顶层对象的属性
577577
578- 顶层对象,在浏览器环境指的是` window ` 对象,在Node指的是 ` global ` 对象。ES5之中 ,顶层对象的属性与全局变量是等价的。
578+ 顶层对象,在浏览器环境指的是` window ` 对象,在 Node 指的是 ` global ` 对象。ES5 之中 ,顶层对象的属性与全局变量是等价的。
579579
580580``` javascript
581581window .a = 1 ;
@@ -587,14 +587,14 @@ window.a // 2
587587
588588上面代码中,顶层对象的属性赋值与全局变量的赋值,是同一件事。
589589
590- 顶层对象的属性与全局变量挂钩,被认为是JavaScript语言最大的设计败笔之一 。这样的设计带来了几个很大的问题,首先是没法在编译时就报出变量未声明的错误,只有运行时才能知道(因为全局变量可能是顶层对象的属性创造的,而属性的创造是动态的);其次,程序员很容易不知不觉地就创建了全局变量(比如打字出错);最后,顶层对象的属性是到处可以读写的,这非常不利于模块化编程。另一方面,` window ` 对象有实体含义,指的是浏览器的窗口对象,顶层对象是一个有实体含义的对象,也是不合适的。
590+ 顶层对象的属性与全局变量挂钩,被认为是 JavaScript 语言最大的设计败笔之一 。这样的设计带来了几个很大的问题,首先是没法在编译时就报出变量未声明的错误,只有运行时才能知道(因为全局变量可能是顶层对象的属性创造的,而属性的创造是动态的);其次,程序员很容易不知不觉地就创建了全局变量(比如打字出错);最后,顶层对象的属性是到处可以读写的,这非常不利于模块化编程。另一方面,` window ` 对象有实体含义,指的是浏览器的窗口对象,顶层对象是一个有实体含义的对象,也是不合适的。
591591
592- ES6为了改变这一点 ,一方面规定,为了保持兼容性,` var ` 命令和` function ` 命令声明的全局变量,依旧是顶层对象的属性;另一方面规定,` let ` 命令、` const ` 命令、` class ` 命令声明的全局变量,不属于顶层对象的属性。也就是说,从ES6开始 ,全局变量将逐步与顶层对象的属性脱钩。
592+ ES6 为了改变这一点 ,一方面规定,为了保持兼容性,` var ` 命令和` function ` 命令声明的全局变量,依旧是顶层对象的属性;另一方面规定,` let ` 命令、` const ` 命令、` class ` 命令声明的全局变量,不属于顶层对象的属性。也就是说,从 ES6 开始 ,全局变量将逐步与顶层对象的属性脱钩。
593593
594594``` javascript
595595var a = 1 ;
596- // 如果在Node的REPL环境,可以写成global .a
597- // 或者采用通用方法,写成this .a
596+ // 如果在 Node 的 REPL 环境,可以写成 global .a
597+ // 或者采用通用方法,写成 this .a
598598window .a // 1
599599
600600let b = 1 ;
@@ -615,7 +615,7 @@ ES5 的顶层对象,本身也是一个问题,因为它在各种实现里面
615615
616616- 全局环境中,` this ` 会返回顶层对象。但是,Node 模块和 ES6 模块中,` this ` 返回的是当前模块。
617617- 函数里面的` this ` ,如果函数不是作为对象的方法运行,而是单纯作为函数运行,` this ` 会指向顶层对象。但是,严格模式下,这时` this ` 会返回` undefined ` 。
618- - 不管是严格模式,还是普通模式,` new Function('return this')() ` ,总是会返回全局对象。但是,如果浏览器用了CSP (Content Security Policy,内容安全政策),那么` eval ` 、` new Function ` 这些方法都可能无法使用。
618+ - 不管是严格模式,还是普通模式,` new Function('return this')() ` ,总是会返回全局对象。但是,如果浏览器用了 CSP (Content Security Policy,内容安全政策),那么` eval ` 、` new Function ` 这些方法都可能无法使用。
619619
620620综上所述,很难找到一种方法,可以在所有情况下,都取到顶层对象。下面是两种勉强可以使用的方法。
621621
0 commit comments