Miya

ES6的变量和常量
let 和 const 命令 let、const与var区别 let 、 const 是ES6新增的命令。其中le...
扫描右侧二维码阅读全文
08
2016/04

ES6的变量和常量

let 和 const 命令

let、const与var区别

let 、 const 是ES6新增的命令。其中let用来声明变量,const用来声明常量
let、const的作用域为块级作用域,而var为全局作用域

let命令

在使用var声明变量时,会发生“变量提升”现象,而使用let则不会有这个问题
let不允许在同一个作用域内重复声明同一个变量

// 报错
function func(){
    let a = 0;
    let a = 10;
}

// 报错
function func(){
    let a = 0;
    var a = 10;
}

因此不能在函数内部重新声明函数

function func(arg) {
  let arg; // 报错
}

function func(arg) {
  {
    let arg; // 不报错
  }
}

块级作用域

为什么要使用块级作用域
ES5只有全局作用域和函数作用域,没有块级作用域的情况下很容易发生以下问题:

1.内层变量覆盖外层变量

var tmp = new Date();

function f() {
  console.log(tmp);
  if (false) {
    var tmp = 'hello world';
  }
}

f(); // undefined

2.计数变量泄露为全局变量

var s = 'hello';

for (var i = 0; i < s.length; i++) {
  console.log(s[i]);
}

console.log(i); // 5

注意1:避免在块级作用域内声明函数,如果需要,应该写成函数表达式,而非函数声明语句

// 函数声明语句(不推荐)
{
    let a = 'secret';
    function f(){
        return a;
    }
}

// 函数表达式(推荐)
{
    let a = 'secret';
    let f = function (){
        return a;
    };
}

注意2:块级作用域允许函数声明的规则,但必须要在使用大括号的情况下才能成立

// 不报错
'use strict';
if (true) {
  function f() {}
}

// 报错
'use strict';
if (true)
  function f() {}

const命令

const命令用来声明一个只读的常量,该常量被赋值后就不允许改变

和var的不同点

  • const只能用于声明常量
  • const不允许改变值
  • const不允许只声明不赋值,必须声明后立即初始化
  • const声明常量同样有存在暂时性死区的特性

    与let的共同点

  • 不允许重复声明

ES6声明变量的方法

  • var命令
  • function命令
  • let命令
  • const命令
  • import命令
  • class命令

顶层对象的属性

在浏览器中,顶层对象指的是windows对象;而在Node中指的是global对象
在ES5中,顶层对象的属性和全局变量等价

顶层对象属性和全局变量挂钩带来的缺点

  • 编译Compiler时不会报出变量未声明的错误,只有在运行时才能得知
  • 编写程序时可能由于失误创建全局变量
  • 顶层对象属性是全局作用,不利于模块化编程
  • windows对象有实体含义,顶层对象也是有实体含义的对象

    ES6的解决方案

  • varfunction命令声明全局变量,依旧拥有顶层对象的属性
  • let命令、const命令、class命令声明的全局变量不属于顶层对象的属性
    
    var a = 1;
    windows.a // 1

let b = 1;
window.b // undefined


## global对象
### ES5的顶级对象实现不统一所产生的问题
* 浏览器中顶级对象是`window`,但node和Web Worker没有`window`这个对象
* 在浏览器和Web Worker中,`self`也指向顶级对象,而Node却没有
* Node的顶级对象是`global`,而其他环境都不支持

因此目前为了能在各种环境中都能获取顶级对象,一般是使用`this`变量,但是会有局限性

* 在全局环境中,`this`会返回顶层对象。而在Node和ES6模块中,返回的是当前模块
* 函数如果不是作为对象方法运行,其内部的`this`也会指向顶层对象,而在严格模式下,`this`会返回`undefined`
* 无论严格和普通模式,`new Function('return this'){}`总是返回全局对象。若浏览器使用了CSP(Content Security Policy,内容安全政策),那么`eval`、`new Function`这些方法都可能无法使用

### 解决方法
在语言标准层面,引入`global`作为顶层对象(目前为提案)

// CommonJS 的写法
var global = require('system.global')();

// ES6 模块的写法
import getGlobal from 'system.global';
const global = getGlobal();


---

## 变量的解构赋值
### 数组的解构赋值
**基本用法**
ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,称为解构(destructuring)

// 以前赋值
let a = 1;
let b = 2;
let c = 3;

// ES6允许数组或对象提取值
let [a,b,c] = [1,2,3];

本质上,这种写法属于“模式匹配”。如果解构不成功,变量的值将会等于`undefined`。而不完全成功,即等号左边只匹配一部分等号右边的数组,这种情况下解构依然成功。
但是,如果等号右边不是数组,则会报错

// 报错
let [foo] = 1;
let [foo] = false;
let [foo] = NaN;
let [foo] = undefined;
let [foo] = null;
let [foo] = {};


**默认值**
解构赋值允许指定默认值

let [foo = true] = [];
foo // true

let [x, y = 'b'] = ['a']; // x='a', y='b'
let [x, y = 'b'] = ['a', undefined]; // x='a', y='b'


若ES6内部使用严格相等运算符(`===`)时,判断一个位置是否有值。所以,只有当一个数组成员严格等于`undefined`,默认值才会生效
最后修改:2018 年 09 月 12 日 09 : 21 PM

コメントする

Home
Change
Photo
About
Hide