ES6篇-1let和const命令


(1)let命令
    let命令用来声明变量,用法类似于var,但是所声明的变量只在let命令所在的代码块中有效。
在代码块之外调用变量,会报错。
    let命令不存在变量提升,即let命令声明的变量一定要声明后使用否则报错。
    暂时性死区,ES6规定,如果区块中存在let和const命令,这个区块对这些命令声明的
变量,从一开始就形成了封闭作用域,凡是在声明之前就是用这些变量,会报错。
暂时性死区的本质就是,只要一进入当前作用域,所要使用的变量就已经存在了,
但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量。
    说明:ES6 规定暂时性死区和let、const语句不出现变量提升,主要是为了
减少运行时错误,防止在变量声明前就使用这个变量
     let不允许在相同作用域内,重复声明一个变量。


(2)块级作用域
ES5 只有全局作用域和函数作用域,没有块级作用域。有不合适的常见
1.内层变量可能会覆盖外层变量
2.用来计数的循环变量泄露为全局变量
let命令实际上为JavaScript新增了块级作用域。
ES5规定,函数只能在顶层作用域和函数作用域之中声明,不能在块级作用域声明。
ES6引入了块级作用域,明确允许在块级作用域之中声明函数,ES6规定,块级作用域之中,
函数声明语句的行为类似于let,在块级作用域之外不可引用。
ES6中规定,浏览器的ES6环境中,允许在会计作用域内声明函数,函数声明类似于var,即
会提升到全局作用域或函数作用域的头部,同时函数声明还会提升到所在的会计作用域的头部
另外需要注意,ES6的块级作用域必须有大括号,如果没有大括号,JavaScript引擎会认为不存在
块级作用域。

(3)const命令
const声明一个只读的常量,一旦声明就必须立即初始化,不能留到以后赋值。
const和let命令相同,只能在所声明的作用域内有效,且也不会有变量提升,存在暂时性死区
只能在声明的位置后面使用,且不可重复声明。
const实际上保证的不是变量值不得改动,而是变量指向的内存地址保存的数据不得改动。例如
对于简单类型(数字、字符串、布尔值),值就保存在变量指向的内存地址,因此等同于常量。
对于复合类型,变量指向的内存地址存的是实际数据的指针,const只保证这个指针是固定的,
而它指向的数据结构是不是可变的,就完全不能控制了。
   说明:ES5中声明变量的方法:var和function。ES6出了添加了let和const,还添加了
import命令和class命令,所以ES6中一共有6中声明变量的方法。

(4)顶层对象的属性
ES5中,顶层对象的属性与全局变量是等价的。这样的设计很不好,ES6为了改变这一点,同时
保持兼容性,规定:var命令和function命令声明的全局变量,依旧是顶层对象的属性,同时规定
let命令、const命令、class命令声明的全局变量,不属于顶层对象的属性。
    补充说明:ES5中顶层对象的属性和全局变量等价的不好之处在于:无法再编译时就报
出变量未声明的错误,只能运行时才能知道(因为全局变量可能是顶层对象的属性创造的,而属性的创造是动态的);
其次,程序员可能不知不觉就创建了全局变量(比如打错字);顶层对象的属性到处都可
读写,不利于模块化编程。
(5)globalThis对象
JavaScript语言中存在一个顶层对象,提供全局环境,所有的代码都在这个环境中运行,但是
顶层对象在各种实现里不统一,
如:
浏览器里面,顶层对象是window,但 Node 和 Web Worker 没有window。
浏览器和 Web Worker 里面,self也指向顶层对象,但是 Node 没有self。
Node 里面,顶层对象是global,但其他环境都不支持。
下面两种方法,勉强可以使用的获取顶层对象的方法
// 方法一
(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

阮一峰 ES6

 

猜你喜欢

转载自blog.csdn.net/u012149906/article/details/91361794