LastPoem / Notes

This is a note library
1 stars 0 forks source link

ES6_var,let 和const #1

Open LastPoem opened 5 years ago

LastPoem commented 5 years ago

1.作用域

var 如果在函数内声明它的变量的作用域就是函数内部,除此之外就是全局作用域了。 let和const 声明的变量都是块级作用域。可用大括号形成代码块以划定作用域范围。 let 所声明的变量只在它所在的代码块中有效(块级作用域)。因此for循环的计数器就非常适用let const和let作用域一样

ES5只有全局作用域和函数作用域 ES6多了块级作用域

关于for循环:for循环中设置循环变量的部分是一个父作用域,而循环体内部是一个子作用域

2.重复声明

var声明的变量可以重复声明,虽然这可能会造成bug. let不允许在同作用域内重复声明同一个变量。用let声明后的变量不能再用let或var再次声明。 因此不能在函数内部重新声明参数。

3.变量提升

var声明的变量存在变量提升,let和const不存在变量提升。因此用let和const会存在暂时性死区(TDZ)即在let声明变量前使用它是非法的

顶层对象

顶层对象,在浏览器环境指的是window对象,在 Node 指的是global对象。ES5 之中,顶层对象的属性与全局变量是等价的。ES6 为了改变这一点,一方面规定,为了保持兼容性,var命令和function命令声明的全局变量,依旧是顶层对象的属性;另一方面规定,let命令、const命令、class命令声明的全局变量,不属于顶层对象的属性。也就是说,从 ES6 开始,全局变量将逐步与顶层对象的属性脱钩。

globalThis 对象

JavaScript 语言存在一个顶层对象,它提供全局环境(即全局作用域),所有代码都是在这个环境中运行。但是,顶层对象在各种实现里面是不统一的。

浏览器里面,顶层对象是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');
};

现在有一个提案,在语言标准的层面,引入globalThis作为顶层对象。也就是说,任何环境下,globalThis都是存在的,都可以从它拿到顶层对象,指向全局环境下的this。 垫片库global-this模拟了这个提案,可以在所有环境拿到globalThis。