资讯专栏INFORMATION COLUMN

ES6的常用语法

gougoujiang / 1786人阅读

摘要:和命令和类似于中的的使用都是用来声明变量的,只是都存在各自的特殊用法。解构数组和对象是中最常用也是最重要表示形式。实例生成以后,可以用方法分别指定状态和状态的回调函数。这个迭代器对象拥有一个叫做的方法来帮助你重启函数并得到下一个值。

let和const命令

let和const类似于javascript中的var的使用,都是用来声明变量的,只是都存在各自的特殊用法。

在javascript中只有全局作用域和函数作用域,例如:

var name = "one";//全局变量
while(true){
     name  = "two";
     console.log(name);//two,内层变量覆盖了外层变量
     break;
}
console.log(name);//two,

不出意料,两次输出结果都是two。

而ES6带来的一个新特性:

let:为javascript添加一个块级作用域

使用let声明的变量,只作用于使用了let命令的代码块:

var name = "one";//全局变量
while(true){
     let name  = "two";
     console.log(name);//two,
     break;
}
console.log(name);//one

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

const PI = Math.PI;
console.log(PI); //3.141592653589793
PI = 666; //报错Module build failed: SyntaxError: "PI" is read-only
模板字符串

es6模板字符简直是开发者的福音,解决了ES5在字符串功能上的痛点。

基本的字符串格式化,将表达式嵌入字符串中进行拼接。用${}来界定。例如:

 //es5 
var name = "Archer"
console.log("hello" + name)

//es6
const name = "Archer"
console.log(`hello ${name}`) //hello Archer

在ES5时我们通过反斜杠()来做多行字符串或者字符串一行行拼接。ES6反引号(``)直接搞定。

// es5
var msg = "Hi 
Archer!
"

// es6
const template = `
hello Archer
`

对于字符串es6当然也提供了很多厉害的方法,列举几个常用的:

// includes:判断是否包含然后直接返回布尔值
let str = "hahay"
console.log(str.includes("y")) // true

// repeat: 获取字符串重复n次
let s = "ha"
console.log(s.repeat(3)) // "hahaha"
箭头函数

ES6很有意思的一部分就是函数的快捷写法,也就是箭头函数,箭头函数最直观的三个特点:

不需要function关键字来创建函数

省略return关键字

继承当前上下文的 this 关键字

let arr = [1,2,3];

arr.map(item => item + 1)
//等同于
arr.map(function(item){
    return item + 1
})

当函数有且仅有一个参数的时候,是可以省略掉(),当函数返回有且仅有一个表达式的时候可以省略{};例如:

//参数name就没有括号
var people = name => "hello" + name
函数的默认值

ES6 之前,不能直接为函数的参数指定默认值,只能采用变通的方法。例如:

function log(x, y) {
    y = y || "Archer";
    console.log(x, y);
}

log("Hello") // Hello Archer
log("Hello", "China") // Hello China
log("Hello", "") // Hello Archer

上面代码检查函数log的参数y有没有赋值,如果没有,则指定默认值为Archer。这种写法的缺点在于,如果参数y赋值了,但是对应的布尔值为false,则该赋值不起作用。就像上面代码的最后一行,参数y等于空字符,结果被改为默认值。

现在 ES6 允许为函数的参数设置默认值,即直接写在参数定义的后面,为赋值提供了简便的方法。例如:

function log(x, y = "Archer") {
    console.log(x, y);
}

log("Hello") // Hello Archer
log("Hello", "China") // Hello China
log("Hello", "") // Hello

可以看到,ES6 的写法比 ES5 简洁许多,而且非常自然。下面是另一个例子。

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

const p = new Point();
p // { x: 0, y: 0 }
展开运算符

...展开运算符,有两种层面

展开运算符(spread operator)作用是和字面意思一样,就是把东西展开。可以用在array和object上都行。例如:

let a = [1,2,3];  
let b = [0, ...a, 4]; // [0,1,2,3,4]  
  
let obj = { a: 1, b: 2 };  
let obj2 = { ...obj, c: 3 }; // { a:1, b:2, c:3 }  
let obj3 = { ...obj, a: 3 }; // { a:3, b:2 }  

剩余操作符(rest operator)是解构的一种,意思就是把剩余的东西放到一个array里面赋值给它。一般只针对array的解构。例如:

let a = [1,2,3];  
let [b, ...c] = a;  
b; // 1  
c; // [2,3]  
  
// 也可以  
let a = [1,2,3];  
let [b, ...[c,d,e]] = a;  
b; // 1  
c; // 2  
d; // 3  
e; // undefined  
  
// 也可以  
function test(a, ...rest){  
  console.log(a); // 1  
  console.log(rest); // [2,3]  
}  
  
test(1,2,3) 
对象的扩展

对象初始化简写

ES5我们对于对象都是以键值对的形式书写,是有可能出现键值对重名的。例如:

function people(name, age) {
    return {
        name: name,
        age: age
    };
}

键值对重名,ES6可以简写如下:

function people(name, age) {
    return {
        name,
        age
    };
}

ES6 同样改进了为对象字面量方法赋值的语法。ES5为对象添加方法:

const people = {
    name: "lux",
    getName: function() {
        console.log(this.name)
    }
}

ES6通过省略冒号与 function 关键字,将这个语法变得更简洁:

const people = {
    name: "lux",
    getName () {
        console.log(this.name)
    }
}

ES6 对象提供了Object.assign()这个方法来实现浅复制。Object.assign()可以把任意多个源对象自身可枚举的属性拷贝给目标对象,然后返回目标对象。第一参数即为目标对象。在实际项目中,我们为了不改变源对象。一般会把目标对象传为{}。

const obj = Object.assign({}, objA, objB)
解构

数组和对象是JS中最常用也是最重要表示形式。为了简化提取信息,ES6新增了解构,这是将一个数据结构分解为更小的部分的过程。

ES5我们提取对象中的信息形式如下:

const people = {
    name: "Archer",
    age: 28
}

const name = people.name
const age = people.age
console.log(name + " --- " + age) //"Archer --- 28"

在ES6之前我们就是这样获取对象信息的,一个一个获取。现在,解构能让我们从对象或者数组里取出数据存为变量。例如:

 //对象
const people = {
    name: "Archer",
    age: 28
}
const { name, age } = people
console.log(`${name} --- ${age}`)
//数组
const color = ["red", "blue"]
const [first, second] = color
console.log(first) //"red"
console.log(second) //"blue"
import 和 export

import导入模块、export导出模块

//全部导入
import people from "./example"

//有一种特殊情况,即允许你将整个模块当作单一对象进行导入
//该模块的所有导出都会作为对象的属性存在
import * as example from "./example.js"
console.log(example.name)
console.log(example.age)
console.log(example.getName())

//导入部分
import {name, age} from "./example"

// 导出默认, 有且只有一个默认
export default App

// 部分导出
export class App extend Component {};

导入的时候有没有大括号的区别是什么。下面是我在工作中的总结:

当用export default people导出时,就用 import people 导入(不带大括号)

一个文件里,有且只能有一个export default。但可以有多个export。

当用export name 时,就用import { name }导入(记得带上大括号)

当一个文件里,既有一个export default people, 又有多个export name 或者 export
age时,导入就用 import people, { name, age }

当一个文件里出现n多个 export 导出很多模块,导入时除了一个一个导入,也可以用import * as example

Promise

在promise之前代码过多的回调或者嵌套,可读性差、耦合度高、扩展性低。通过Promise机制,扁平化的代码机构,大大提高了代码可读性;用同步编程的方式来编写异步代码,保存线性的代码逻辑,极大的降低了代码耦合性而提高了程序的可扩展性。

Promise对象有以下两个特点:

对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。

一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为
resolved(已定型)。如果改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。

说白了就是用同步的方式去写异步代码,下面代码创造了一个Promise实例:

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

Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject。它们是两个函数,由 JavaScript 引擎提供,不用自己部署。

resolve函数的作用是,将Promise对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;reject函数的作用是,将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。

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

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

下面是一个Promise对象的简单例子,timeout方法返回一个Promise实例,表示一段时间以后才会发生的结果。过了指定的时间(ms参数)以后,Promise实例的状态变为resolved,就会触发then方法绑定的回调函数。:

function timeout(ms) {
    return new Promise((resolve, reject) => {
        setTimeout(resolve, ms, "done");
    });
}

timeout(100).then((value) => {
    console.log(value);
});
Generators

生成器( generator)是能返回一个迭代器的函数。生成器函数也是一种函数,最直观的表现就是比普通的function多了个星号*,在其函数体内可以使用yield关键字,有意思的是函数会在每个yield后暂停。

这里生活中有一个比较形象的例子。咱们到银行办理业务时候都得向大厅的机器取一张排队号。你拿到你的排队号,机器并不会自动为你再出下一张票。也就是说取票机“暂停”住了,直到下一个人再次唤起才会继续吐票。

说说迭代器。当你调用一个generator时,它将返回一个迭代器对象。这个迭代器对象拥有一个叫做next的方法来帮助你重启generator函数并得到下一个值。next方法不仅返回值,它返回的对象具有两个属性:done和value。value是你获得的值,done用来表明你的generator是否已经停止提供值。继续用刚刚取票的例子,每张排队号就是这里的value,打印票的纸是否用完就这是这里的done。

// 生成器
function *createIterator() {
    yield 1;
    yield 2;
    yield 3;
}

// 生成器能像正规函数那样被调用,但会返回一个迭代器
let iterator = createIterator();

console.log(iterator.next().value); // 1
console.log(iterator.next().value); // 2
console.log(iterator.next().value); // 3

那生成器和迭代器又有什么用处呢?

围绕着生成器的许多兴奋点都与异步编程直接相关。异步调用对于我们来说是很困难的事,我们的函数并不会等待异步调用完再执行,你可能会想到用回调函数,(当然还有其他方案比如Promise比如Async/await)。

生成器可以让我们的代码进行等待。就不用嵌套的回调函数。使用generator可以确保当异步调用在我们的generator函数运行一下行代码之前完成时暂停函数的执行。

那么问题来了,咱们也不能手动一直调用next()方法,你需要一个能够调用生成器并启动迭代器的方法。就像这样子的:

function run(taskDef) { //taskDef即一个生成器函数
    // 创建迭代器,让它在别处可用
    let task = taskDef();

    // 启动任务
    let result = task.next();

    // 递归使用函数来保持对 next() 的调用
    function step() {

        // 如果还有更多要做的
        if (!result.done) {
            result = task.next();
            step();
        }
    }

    // 开始处理过程
    step();

}

生成器与迭代器最有趣、最令人激动的方面,或许就是可创建外观清晰的异步操作代码。你不必到处使用回调函数,而是可以建立貌似同步的代码,但实际上却使用 yield 来等待异步操作结束。

总结

ES6的特性远不止于此,但对于我们日常的开发开说,这已经是够够的了,还有很多有意思的方法。比如for of,Iterator...等等。

来都来了点一下赞吧,你的赞是对我最大的鼓励^_^

希望更全面了解es6伙伴们可以去看阮一峰所著的电子书ECMAScript 6入门

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/94914.html

相关文章

  • ES6常用语法整合

    摘要:说到肯定是先介绍了,据阮一峰老师介绍到,是一个广泛使用的转码器,可以将代码转为代码,从而在现有环境执行。输出其他还有等可以查看阮一峰的入门 ES6也出来有一会时间了,他新增的语法糖也的确大大提高了开发者的效率,今天就总结一些自己用到最多的。 说到ES6肯定是先介绍Babel了,据阮一峰老师介绍到,Babel是一个广泛使用的转码器,可以将ES6代码转为ES5代码,从而在现有环境执行。这意...

    张迁 评论0 收藏0
  • ES6-7

    摘要:的翻译文档由的维护很多人说,阮老师已经有一本关于的书了入门,觉得看看这本书就足够了。前端的异步解决方案之和异步编程模式在前端开发过程中,显得越来越重要。为了让编程更美好,我们就需要引入来降低异步编程的复杂性。 JavaScript Promise 迷你书(中文版) 超详细介绍promise的gitbook,看完再不会promise...... 本书的目的是以目前还在制定中的ECMASc...

    mudiyouyou 评论0 收藏0
  • [ ES6 ] 快速掌握常用 ES6 (二)

    摘要:本系列文章适合快速掌握入门语法,想深入学习的小伙伴可以看看阮一峰老师的入门本篇文章是对之前文章的一个补充,可以使代码更简洁函数参数默认值在传统语法中如果想设置函数默认值一般我们采用判断的形式在新的语法中我们可以在参数声明的同时赋予默认值参数 本系列文章适合快速掌握 ES6 入门语法,想深入学习 ES6 的小伙伴可以看看阮一峰老师的《ECMAScript 6 入门》 本篇文章是对之前文章...

    hidogs 评论0 收藏0
  • 工作中常用es6+特性

    摘要:结合工作中使用情况,简单对进行一些复习总结,包括常用的语法,等,以及短时间内要上手需要重点学习的知识点不同工作环境可能有一些差别,主要参考链接是阮一峰的博客以及外文博客阮老师大部分文章是直接翻译的这个博客简介先说一下,是一个标准化组织,他们 结合工作中使用情况,简单对es6进行一些复习总结,包括常用的语法,api等,以及短时间内要上手需要重点学习的知识点(不同工作环境可能有一些差别),...

    xcold 评论0 收藏0
  • es6常用语法

    摘要:革命伴随着到来的是一场语法革命请忘记,统一使用声明变量和函数解构解构带来了简洁的赋值方式,在任何声明变量的地方都可以使用解构赋值。 革命 伴随着es6到来的是一场语法革命! let const 请忘记var,统一使用let,const声明变量和函数 let foo = `new` let bar = function(){} 解构 解构带来了简洁的赋值方式,在任何声明变量的地方都可以使...

    Bmob 评论0 收藏0
  • 实例感受-es6常用语法和优越性

    摘要:在重写完了的时候,就个人总结了一下常用的一些常用的语法和比优越的方面。参数字符串是否在原字符串的尾部返回布尔值。第一个大于的成员的索引方法,用于某个数组是否包含给定的值,返回一个布尔值。 1.前言 前几天,用es6的语法重写了我的一个代码库,说是重写,其实改动的并不多,工作量不大。在重写完了的时候,就个人总结了一下es6常用的一些常用的语法和比es5优越的方面。下面提到的语法可能也就是...

    fsmStudy 评论0 收藏0

发表评论

0条评论

gougoujiang

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<