ES6——(一)

目录:

一、ECMAScript 和 JavaScript 的关系
二、ES6 与 ECMAScript 2015 的关系
三、Let
四、const
五、const & let
六、作用域
七、解构赋值

一、ECMAScript 和 JavaScript 的关系

ECMAScript 和 JavaScript 的关系是,前者是后者的规格,后者是前者的一种实现。

二、ES6 与 ECMAScript 2015 的关系

1.标准委员会制定的标准是,每年的6月份正式发布一次,作为当年的正式版本。接下来的时间,就在这个版本的基础上做改动,直到下一年的6月份,草案就自然变成了新一年的版本。这样一来,就不需要以前的版本号了,只要用年份标记就可以了。

2.ES6 的第一个版本,在2015年6月发布,正式名称是《ECMAScript 2015标准》,简称 ES2015。

3.ES6 既是一个历史名词,也是一个泛指,含义是5.1版以后的 JavaScript 的下一代标准,涵盖了ES2015、ES2016、ES2017等等。

三、Let

特点

1.没有预解析,不存在变量的提升,所以在一个代码块内,先使用let定义的变量再定义的话会报错;

2.在同一个作用域里,不能重复定义变量
   `let  a = 5;{  let a = 10;}`  //是正确的,因为是两个不同的作用域;

3.for 循环中,循环语句部分是一个父作用域,而循环体内部是一个单独的子作用域;
   则:
     for (let i = 0; i < 3; i++) {
            let i = 'abc';
            console.log(i);  // 输出三次 abc
       }

四、const

特点

1.const定义的变量不能修改;

2.const定义完变量,必须马上赋值,只能这么定义`const   csdn = ‘aa’,不能分开;`

3.const实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址不得改动。对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指针,const只能保证这个指针是固定的,至于它指向的数据结构是不是可变的,就完全不能控制了,即对象和数组里面的属性可以修改。

4.若想要使得对象不得修改,使用 Object.freeze(obj) 即可 ;

   <script >
        // const 定义的变量不能修改,但是对象的属性可以修改
         const arr1= ['a','b'];
         arr.push('c');
         console.log(arr1);

       // arr2 不能修改,
         const arr2= Object.freeze(['a','b']);
         console.log(arr2);
         arr.push('c'); // 错误,已经被冻结了,object is not extensible
         console.log(arr);
    </script>

五、const & let

注意:

如果区块中存在let和const命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域,凡是在声明之前就使用这些变量,就会报错,在语法上,这种情况称为“暂时性死区”(temporal dead zone,简称 TDZ)。

则:

var tmp = 123;

if (true) {
  tmp = 'abc'; // ReferenceError
  let tmp;
}

六、作用域

  1. ES5 只有全局作用域和函数作用域,没有块级作用域;

  2. ES6 新增块级作用域,通过let 来实现;


块级作用域与函数声明

1.允许在块级作用域内声明函数。

2.函数声明类似于var,即会提升到全局作用域或函数作用域的头部。

3.同时,函数声明还会提升到所在的块级作用域的头部。

 注意,上面三条规则只对 ES6 的浏览器实现有效,其他环境的实现不用遵守,还是将块级作用域的函数声明当作let处理。

应该避免在块级作用域内声明函数。如果确实需要,也应该写成函数表达式,而不是函数声明语句。

七、解构赋值

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

2.只要某种数据结构具有 Iterator 接口,都可以采用数组形式的解构赋值。
https://www.cnblogs.com/zczhangcui/p/6502836.html

3.非常有用,特别是在左数据交互的时候

4.注意两边的结构格式要保持一致 :

      let [a,b,c] = [1,3,6];
      console.log(a,c,b); //1,6,3

json :

      let {a,b,c} = {
          a:1, b:3,c:6
     };      
      console.log(a,c,b) //1,6,3

数组解构

1.如果解构不成功,变量的值就等于undefined。

2.等号左边的模式,只匹配一部分的等号右边的数组。这种情况下,解构依然可以成功

3.解构赋值允许指定默认值,,如果一个数组成员不严格等于undefined,默认值就不会生效。
let [x = 1] = [undefined];
x // 1  生效

let [x = 1] = [null];
x // null  失效

对象的解构赋值

  1. 对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。
let { bar, foo } = { foo: "aaa", bar: "bbb" };
foo // "aaa"
bar // "bbb"
baz // undefined 未定义

// 以上的代码实际上是下面形式的简写
let { foo: foo, bar: bar } = { foo: "aaa", bar: "bbb" };

// 则: foo是匹配的模式,baz才是变量。真正被赋值的是变量baz,而不是模式foo。
let { foo: baz } = { foo: "aaa", bar: "bbb" };
baz // "aaa"
foo // error: foo is not defined

2.声明和赋值不同时时:
let命令下面一行的圆括号是必须的,否则会报错。因为解析器会将起首的大括号,理解成一个代码块,而不是赋值语句。

let foo;
({foo} = {foo: 1}); // 成功

3.对象也可以指定默认值,与数组解构同


还有字符串的解构赋值、数值和布尔值的解构赋值、函数参数的解构赋值,这里就不多说了


解构的用途

(1)交换变量的值

let x = 1;
let y = 2;

[x, y] = [y, x];

上面代码交换变量x和y的值,这样的写法不仅简洁,而且易读,语义非常清晰。

(2)从函数返回多个值

函数只能返回一个值,如果要返回多个值,只能将它们放在数组或对象里返回。有了解构赋值,取出这些值就非常方便。

// 返回一个数组
function example() {
  return [1, 2, 3];
}
let [a, b, c] = example();

// 返回一个对象
function example() {
  return {
    foo: 1,
    bar: 2
  };
}
let { foo, bar } = example();

(3)函数参数的定义

解构赋值可以方便地将一组参数与变量名对应起来。

// 参数是一组有次序的值
function f([x, y, z]) { ... }
f([1, 2, 3]);

// 参数是一组无次序的值
function f({x, y, z}) { ... }
f({z: 3, y: 2, x: 1});

(4)提取JSON数据

解构赋值对提取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]

上面代码可以快速提取 JSON 数据的值。

(5)函数参数的默认值

jQ

uery.ajax = function (url, {
  async = true,
  beforeSend = function () {},
  cache = true,
  complete = function () {},
  crossDomain = false,
  global = true,
  // ... more config
}) {
  // ... do stuff
};

指定参数的默认值,就避免了在函数体内部再写var foo = config.foo || ‘default foo’;这样的语句。

(6)遍历Map结构

任何部署了Iterator接口的对象,都可以用for…of循环遍历。Map结构原生支持Iterator接口,配合变量的解构赋值,获取键名和键值就非常方便。

var map = new Map();
map.set('first', 'hello');
map.set('second', 'world');

for (let [key, value] of map) {
  console.log(key + " is " + value);
}
// first is hello
// second is world

如果只想获取键名,或者只想获取键值,可以写成下面这样。

// 获取键名
for (let [key] of map) {
  // ...
}

// 获取键值
for (let [,value] of map) {
  // ...
}

(7)输入模块的指定方法

加载模块时,往往需要指定输入哪些方法。解构赋值使得输入语句非常清晰。

const { SourceMapConsumer, SourceNode } = require(“source-map”);


圆括号问题

以下三种解构赋值不得使用圆括号。

(1)变量声明语句中,模式不能带有圆括号。

// 全部报错
let [(a)] = [1];

let {x: (c)} = {};
let ({x: c}) = {};
let {(x: c)} = {};
let {(x): c} = {};

let { o: ({ p: p }) } = { o: { p: 2 } };

(2)函数参数中,模式不能带有圆括号。

函数参数也属于变量声明,因此不能带有圆括号。

// 报错
function f([(z)]) { return z; }

(3)赋值语句中,不能将整个模式,或嵌套模式中的一层,放在圆括号之中。

// 全部报错
({ p: a }) = { p: 42 };
([a]) = [5];

可以使用圆括号的情况

可以使用圆括号的情况只有一种:赋值语句的非模式部分。

[(b)] = [3]; // 正确
({ p: (d) } = {}); // 正确
[(parseInt.prop)] = [3]; // 正确
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值