ES6 介绍 及 变量基础知识

Posted Mr.隐士

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ES6 介绍 及 变量基础知识相关的知识,希望对你有一定的参考价值。

一、ES6 简介

  • ECMAScript 6.0(以下简称 ES6)是 javascript 语言的下一代标准,已经在 2015 年 6 月正式发布了。它的目标,是使得 JavaScript 语言可以用来编写复杂的大型应用程序,成为企业级开发语言

  • ES6 是 5.1 版以后的 JavaScript 的下一代标准,涵盖了 ES2015、ES2016、ES2017 等等;而 ES2015 则是正式名称,特指该年发布的正式版本的语言标准

二、ES6 转码

  • Node 是 JavaScript 的服务器运行环境(runtime),它对 ES6 的支持度更高,但有些执行环境不能完全支持 ES6 语法

  • ES6 转码器 可以将 ES6 代码转为 ES5 代码,从而在现有环境执行。

三、ES6 新特性汇总(待更新)

  • 增加块级作用域

四、变量的 声明

1. 块级作用域

  • ES6的块级作用域,是通过 letconst 声明变量,来体现的

  • 只要一个代码块 { } 中存在 letconst ,就形成了一个封闭的作用域(块级作用域);每一个 { } 都是一层块级作用域

  • 块级作用域的出现,实际上使得获得广泛应用的立即执行函数表达式(IIFE)不再必要了

// IIFE 写法
(function () {
    var tmp = ...;
    ...
}());

// 块级作用域写法
{
    let tmp = ...;
    ...
}

2. let 、const 声明变量,详解

(1)通过 letconst 声明的变量,不是全局变量, 不能通过 window 访问
  • 只能在当前块级作用域 及 子作用域内能够被访问到
(2)let 声明变量,允许被修改
(3)const 声明一个只读的常量不允许被修改
  • 意味着:const 一旦声明变量,就必须立即初始化,不能留到以后赋值
const foo; // SyntaxError: Missing initializer in const declaration
  • 本质:并不是变量的值不得改动,而是变量指向的那个内存地址不得改动;
    • 简单数据类型:值就保存在变量指向的那个内存地址,所以不能有任何改变

    • 复杂数据类型:const 声明的变量 指向内存地址,const 只能约束 指针指向的内存地址不变;不能约束 内存地址中 的数据结构

// 所以:const 声明复杂数据类型,其数据结构是可变的
const foo = {};

// 为 foo 添加一个属性,可以成功
foo.prop = 123;
ondole.log(foo.prop); // 123

3. let 、const 声明变量,不存在变量提升

  • letconst 声明变量,不存在变量提升
// var 的情况
console.log(foo); // 输出undefined
var foo = 2;

// let 的情况
console.log(bar); // 报错ReferenceError
let bar = 2;

4. let 、const 声明变量,造成暂时性死区(TDZ)

  • letconst 声明变量,不允许 在变量声明之前 使用,造成暂时性死区

  • letconst 声明变量,形成块级作用域,在声明变量之前的区域,都是 变量的死区(不允许 使用变量,使用会报错)

var tmp = 123;

if (true) {
    // TDZ开始
    tmp = ‘abc‘; // ReferenceError
    console.log(tmp); // ReferenceError
    
    let tmp; // TDZ结束
    console.log(tmp); // undefined
    
    tmp = 123;
    console.log(tmp); // 123
}

// 上面代码中,在let命令声明变量tmp之前,都属于变量tmp的“死区”
  • 比较隐蔽的死区
function bar(x = y, y = 2) {
    return [x, y];
}

console.log(bar()); // 报错

5. let 、const 声明变量,不允许重复声明

  • 对比:var 声明的变量,重复声明 无效,不会报错
if (true) {
    const a = 10;
    const a = 1;
}
  • 函数直接作用域内 使用 let 重新声明形参,会报错
function func(arg) {
    let arg; // 报错
}
  • 内层作用域可以定义外层作用域的同名变量
function func(arg) {
    {
        let arg; // 不报错
    }
}

6. let 、 const 声明的全局变量,不属于顶层对象的属性

  • ES5 败笔之一:顶层对象的属性与全局变量是等价的;很容易不知不觉的创建多个全局变量,读写困难,维护困难

  • ES6 规定:
    • var命令和function命令声明的全局变量,依旧是顶层对象的属性

    • let命令、const命令、class命令声明的全局变量,不属于顶层对象的属性

var a = 1;
console.log(window.a);  // 1

let b = 1;
console.log(window.b);  // undefined

五、变量的 解构赋值

1. 概念

  • ES6 允许按照一定模式,从数组 和 对象中提取值,对变量进行赋值,这被称为解构赋值(Destructuring)

2. 解构赋值 --- 数组

  • 模式匹配 内部机制:数组的元素是按次序排列的,相同位置 数据结构相同,才能成功的解构赋值

  • 分为:存在完全结构赋值,和不完全结构赋值

// 完全结构赋值
let [foo, [[bar], baz]] = [1, [[2], 3]];
console.log(foo);   // 1
console.log(bar);   // 2
console.log(baz);   // 3

// 不完全结构赋值
let [x, y] = [1, 2, 3];
console.log(x);     // 1
console.log(y);     // 2
// `...a` 代表定义数组
let arr = [1, 2, 3, 4];
let [a, b, ...c] = arr;

console.log(c);   // [3, 4]
  • 结构赋值 数组的长度(因为数组 有 length 属性)
let arr = [1, 2, 3];
let {length: leg} = arr;

console.log(leg);   // 3

2. 解构赋值 --- 对象

  • 模式匹配 内部机制:先在已有对象中找到同名属性,然后再将已有对象中同名属性的值 赋给 定义变量的属性值
// 定义的变量名 与 属性名一致
let { bar, foo } = { foo: "aaa", bar: "bbb" };
foo // "aaa"
bar // "bbb"

let { baz } = { foo: "aaa", bar: "bbb" };
baz // undefined
// 定义的变量名 与 属性名不一致
let { foo: baz } = { foo: ‘aaa‘, bar: ‘bbb‘ };
console.log(baz);   // "aaa"

3. 解构赋值 --- 指定默认值

  • 默认值生效的条件是,数组 / 对象 的属性值 严格等于 undefined
let [x = 1] = [undefined];
console.log(x);     // 1

let [y = 1] = [null];
console.log(y);     // null
  • 如果默认值是一个表达式,那么这个表达式是惰性求值的(只有在用到的时候,才会求值)
function f() {
    console.log(‘aaa‘);
}

let [x = f()] = [1]; // 无输出
let [x = f()] = [];  // aaa
  • 默认值可以引用解构赋值的其他变量,但该变量必须已经声
let [x = 1, y = x] = [];     // x=1; y=1
let [x = 1, y = x] = [2];    // x=2; y=2
let [x = 1, y = x] = [1, 2]; // x=1; y=2
let [x = y, y = 1] = [];     // ReferenceError

4. 解构赋值 --- 函数 参数

function move({x = 0, y = 0} = {}) {
  return [x, y];
}

move({x: 3, y: 8}); // [3, 8]
move({x: 3}); // [3, 0]
move({}); // [0, 0]
move(); // [0, 0]

5. 解构赋值 的用途

交换变量
let x = 1;
let y = 2;

[x, y] = [y, x];
函数 设置默认参数
function(n = 1) {
    return n;
}
函数 参数为对象 设置默认值
function foo({
    x = 10,
    y = 5
}) {
    console.log(x, y);
}

foo({})       // undefined 5
foo({x: 1})   // 1 5
foo()         // TypeError: Cannot read property ‘x‘ of undefined
function foo({
    x = 10,
    y = 5
} = {}) {
    console.log(x, y);
}

foo({})       // undefined 5
foo({x: 1})   // 1 5
foo()         // 1 5
提取 对象 / json 中的数据
let jsonData = {
    id: 42,
    status: "OK",
    data: [867, 5309]
};

let { id, status, data: number } = jsonData;

console.log(id, status, number);
// 42, "OK", [867, 5309]

以上是关于ES6 介绍 及 变量基础知识的主要内容,如果未能解决你的问题,请参考以下文章

ES6 介绍

ES6之常用开发知识点:入门

ES6介绍

es6简单介绍

ES6学习 第一章 let 和 const 命令

ES6