ES6 常用功能总结(箭头函数、let/const、解构赋值、模板字符串、Promise对象等)

let关键字

作用:与var类似,用于声明一个变量
与var不同:let所声明的变量,在块级作用域内有效,也就是只在它所在的代码块有效

{
  let a = 100;
  var b = 10;
}
console.log(a);  //undefined
console.log(b);  //10

不能重复声明
不能在相同作用域内重复声明同一个变量

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

不能在函数内部重新声明参数

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

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

不会预处理

for (let i = 0; i < 10; i++) {
  // ...
}

console.log(i);

上面代码中,计数器i只在for循环体内有效,在循环体外引用就会报错。

var a = [];
for (var i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[6](); // 10

上面的结果输出的是:10;变量i是一个全局变量,在全局范围内都有效,所以全局只有一个变量i。每一次循环,变量i的值都会发生改变,而循环内被赋给数组a的函数内部的 console.log(i),里面的i指向的是全局i。也就是说,所有数组a的成员里面的i。指向的都是同一个i,所以输出的是最后一次循环的结果:10。

var a = [];
for (let i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[6](); // 6

上面代码中,变量i是let声明的,当前的i只在本轮循环有效,所以每一次循环的i其实都是一个新的变量,所以最后输出的是6。
不存在变量提升
var命令会发生“变量提升”现象,也就是变量在声明之前就可以使用,值为undefined。而let命令改变了这种语法行为,它所使用的变量必须先声明,否则报错。

// var 的情况
console.log(foo); // 输出undefined
var foo = 2;

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

变量的解构赋值

理解:从数组和对象中提取数据并赋值给变量(可多个),根据下面的例子我们可以看到用了解构赋值之后代码更加简洁。
1.对象的解构赋值:
对象的解构赋值与数组有一个重要的不同。数组的元素是按次序排序的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。

//JS
var obj = {a:100, b:200}
var a = obj.a
var b = obj.b

//ES6
const obj = {a:10, b:10}
const {a,b} = obj
console.log(a)
console.log(b)

let { bar, foo } = { foo: “aaa”, bar: “bbb” };
foo // “aaa”
bar // “bbb”

let { baz } = { foo: “aaa”, bar: “bbb” };
baz // undefined
2.数组的解构赋值

 //JS
  var arr = ['aa','bb','cc']
  var x = arr[0]  //aa
  
  //ES6
  const arr = ['aa','bb','cc']
  const [a,b,c] = arr
  console.log(a) //aa
  console.log(b) //bb
  console.log(c) //cc

3.字符串的解构赋值

const [a, b, c, d, e] = 'hello';
a // "h"
b // "e"
c // "l"
d // "l"
e // "o"

4.数值和布尔值的解构赋值
解构赋值时,如果符号右边是数值和布尔值,则会先转为对象,undefined和null无法转为对象,所以不能对它们进行解构赋值。

let {toString: s} = 123;
s === Number.prototype.toString // true

let {toString: s} = true;
s === Boolean.prototype.toString // true

5.函数参数的解构赋值

function add([x, y]){
  return x + y;
}
add([1, 2]); // 3

上面代码中,函数 add 的参数表面上是一个数组,但在传入参数的那一刻,数组参数就被解构成变量x和y。对于函数内部的代码来说,它们能感受到参数就是x和y。
6.圆括号问题
不能使用圆括号的情况
以下三种解构赋值不得使用圆括号
(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; }
// 报错
function f([z,(x)]) { return x; }

(3)赋值语句的模式
下面代码将整个模式放在圆括号之中,导致报错。

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

下面代码将一部分模式放在圆括号之中,导致报错

[({ p: a }), { x: c }] = [{}, {}];

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

[(b)] = [3]; // 正确
({ p: (d) } = {}); // 正确
[(parseInt.prop)] = [3]; // 正确

7.解构赋值的用途
(1)交换变量的值
(2)从函数返回多个值
(3)函数参数的定义
(4)提取 JSON 数据
(5)函数参数的默认值
(6)遍历 M
(7)输入模块的指定方法ap 结构

模板字符串/模板变量

模板字符串:简化字符的拼接,模板字符串必须用反括号(``)包含,变化的部分使用${变化的部分}定义。

let obj = {
        name : 'anverson',
        age : 41
    };
    console.log('我叫:' + obj.name + ', 我的年龄是:' + obj.age);

    console.log(`我叫:${obj.name}, 我的年龄是:${obj.age}`);

块级作用域

ES5只有全局作用域和函数作用域,没有块级作用域,这样会出现一些我们不想要的结果
第一种可能出现的结果,内层变量可能会覆盖外层变量。由于变量提升,导致内层的tmp变量覆盖了外层的tmp变量。

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

f(); // undefined

第二种可能出现的结果,用来奇数的循环变量泄露为全局变量

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

上面代码中,变量i只用来控制循环,但是循环结束后,它并没有消失,泄露成了全局变量。
ES6的块级作用域

function f1() {
  let n = 5;
  if (true) {
    let n = 10;
  }
  console.log(n); // 5
}

上面的函数有两个代码块,都声明了你变量n,输出的结果为5。这表示外层代码不受内层代码块的影响。如果两次都使用var定义变量n,最后输出的值才是10。

const关键字

const声明一个只读的常量。一旦声明,常量的值就不能改变。

    const sex = '男';
    console.log(sex);
    sex = '女';  //不能修改
    console.log(sex);  // Uncaught TypeError: Assignment to constant variable

当重新定义变量时会报错,const一旦声明变量,就必须立即初始化,如只声明不赋值便会报错。const命令声明的常量,和let一样是不可以提升的,也不能重复声明。

简化的对象写法

简化的对象写法:可以省略同名属性值

    let x = 3;
    let y = 5;
    //普通额写法
   let obj = {
       x : x,
       y : y,
       getPoint : function () {
           return this.x + this.y
       }
   };
    //简化的写法
    let obj = {
        x,
        y,
        getPoint(){
            return this.x
        }
    };
    console.log(obj, obj.getPoint());

函数默认参数

ES6之前,不能直接给函数的参数指定默认值,下面的函数参数,当b为null时,给b赋值为0。而ES6之后,在函数声明时,可以直接指定参数的默认值

//JS
function(a,b){
if(b==null){
b =0
}

//ES6
function(a, b =0){}

箭头函数

没有形参,并且函数体只有一条语句,需要用一个圆括号代表参数部分

 var f = () => 5;
// 等同于
var f = function () { return 5 };

只有一个形参,并且函数体只有一条语句

    let fun2 = x => x;
    console.log(fun2(5));  //5

形参是一个以上,参数需要用圆括号括起来

    let fun3 = (x, y) => x + y;
    console.log(fun3(25, 39));//64

函数体有多条语句,就要使用大括号将它们括起来,并且使用return语句返回。

var sum = (num1, num2) => { return num1 + num2; }

函数体不用大括号:默认返回结果
函数体如果有多个语句,需要用{}包围,若有需要返回的内容,需要手动返回

let fun4 = (x, y) => {
        console.log(x, y);
        return x + y;
    };
    console.log(fun4(34, 48));//82

注意
(1)函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。

(2)不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。

(3)不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。

(4)不可以使用yield命令,因此箭头函数不能用作 Generator 函数。
**拓展理解:**箭头函数的this看外层的是否有函数,如果有,外层函数的this就是内部箭头函数的this,如果没有,则this是window。

Promise对象

Promise对象,代表了未来某个将要发生的事件(通常是一个异步操作),有了Promise对象,可以将异步操作以同步的流程表达出来,避免了层层嵌套的回调函数(俗称‘回调地狱’),ES6的Promise是一个构造函数,用来生成promise实例。
Promise对象有以下两个特点。
(1)对象的状态不受外界影响。 Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。
(2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变只有两种可能:从pending变为fulfilled和从pending变为rejected。只要这两种状况发生将不会再变。
**缺点:**首先,一旦新建了Promise它就会立即执行,无法中途取消。其次,若果不设置回调函数,Promise内部抛出的错误,不会反应到外部。最后,当处于pending状态时,无法得知目前进展到哪一个阶段。
使用Promise基本步骤:
1、创建Promise对象

lconst promise = new Promise(function(resolve, reject) {
  if (/* 异步操作成功 */){
    resolve(value);
  } else {
    reject(error);
  }
});

resolve和reject是两个函数,有JavaScript引擎提供,不需要自己部署。resolve函数的作用是,将Promise对象的状态从 pending 变为 resolved,在异步操作成功调用时,并将异步操作的结果作为参数传递出去;reject函数的作用是,将Promise对象状态从从 pending 变为 rejected,在异步操作失败时调用,并将异步操作报出的错误作为参数传递出去。

2、调用Promise的then()
Promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数。

   promise.then(function(value) {
  // success
}, function(error) {
  // failure
});

then方法可以接受两个回调函数作为参数。第一个回调函数是Promise对象的状态变为resolved时调用,第二个回调函数是Promise对象的状态变为rejected时调用。其中,第二个函数是可选的,不一定要提供。这两个函数都接受Promise对象传出的值作为参数。

Class

ES6 的class可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。下面代码对比了JavaScript和ES6的不同使用方法。

//JS
function Point(x, y) {
  this.x = x;
  this.y = y;
}

Point.prototype.toString = function () {
  return '(' + this.x + ', ' + this.y + ')';
};

var p = new Point(1, 2);

//ES6
//定义类
class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }

  toString() {
    return '(' + this.x + ', ' + this.y + ')';
  }
}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值