ES6 初识

ES6 是 ECMAScript 6.0 的简写,即 JavaScript 语言的下一代标准,已经在 2015年6月正式发布了,它的目标是让JS能够方便的开发企业级大型应用程序,因此,ES6的一些规范正在逐渐向Java、C# 等后端语言标准靠近。在 ES6 规范中,比较重大的变化有以下几个方面:

  • 新增 let、const 命令 来声明变量,和var 相比,let 声明的变量不存在变量提升问题,但没有改变JS弱类型的特点,依然可以接受任意类型变量的声明;const 声明的变量不允许在后续逻辑中改变,提高了JS语法的严谨性。
  • 新增解构赋值、rest 语法、箭头函数等,这些都是为了让代码看起来更简洁,而包装的语法糖。
  • 新增模块化机制,这是 JavaScript 走向规范比较重要的一步,让前端更方便的实现工程化。
  • 新增类和继承的概念,配合模块化,JavaScript 也可以实现高复用、高扩展的系统架构。
  • 新增模板字符串功能,高效简洁,结束拼接字符串的时代。
  • 新增 Promise 机制,解决异步回调多层嵌套的问题。

ES6 介绍

let和const

let

ES6新增了let命令,用于声明变量。其用法类似var,但是声明的变量只在let命令所在的代码块内有效。
{
let x = 10;
var y = 20;
} x // ReferenceError: x is not defined
y //

var声明变量存在变量提升。也就是在声明变量之前就可以使用该变量。

console.log(x)  // undefined,var声明变量之前可以使用该变量
var x = 10;

而let不会这样,let声明的变量不能在声明之前使用。

console.log(x)  // ReferenceError: x is not defined,let声明变量之前不可以使用该变量
let x = 10;

注意:
let不允许在相同的作用域内重复声明同一个变量。 
比如:
function foo(){
let x = 10;
var x = 20;
} // 报错

再比如:

function foo(){
let y = 10;
let y = 20;
} // 报错

ES5中只有全局作用域和函数作用域,并没有块级作用域。
请看下面的示例: 
var name = 'Q1mi'

function foo(){
console.log(name)
if (false){
var name = 'Bob'
}
}
foo() // undefined

出现上述现象的原因就是在函数内部,由于变量提升导致内存的name变量覆盖了外层的name变量。
类似的情况还出现在 for循环的计数变量最后会泄露为全局变量。 
for (var i=0;i<5;i++){
console.log('哈哈');
}
console.log(i); //

ES6中的let声明变量的方式实际上就为JavaScript新增了块级作用域。

var name = 'Q1mi'

function foo(){
console.log(name)
if (false){
let name = 'Bob'
}
}
foo() // Q1mi

此时,在foo函数内容,外层代码块就不再受内层代码块的影响。所以类似for循环的计数变量我们最好都是用let来声明。

最后再做个练习巩固下:

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

const

const用来声明常量。const声明变量必须立即初始化,并且其值不能再改变。
const声明常量的作用域与let相同,只在声明所在的块级作用域内有效。 
例如:
const PI = 3.14;

全局对象的属性:

ES6规定:var命令和function命令声明的全局变量依旧是全局对象的属性;let命令、const命令和class命令声明的全局变量不属于全局对象的属性。

查看下面的示例代码:

var x = 10;
let y = 20;
window.x //
window.y // undefined

变量的解构赋值

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

var [x, y, z] = [10, 20, 30]
x //
y //
z //

对象的解构赋值:

var {x, y} = {x: 10, y: 20}
x //
y //

字符串

include、startsWith、endsWith

在此之前,JavaScript中只有indexOf方法可用来确定一个字符串是否包含在另一个字符串中。

ES6中又提供了3种新方法:

includes():返回布尔值,表示是否找到了参数字符串。

stratsWith():返回布尔值,表示参数字符串是否在源字符串的开始位置。

endsWith():返回布尔值,表示参数字符串是否在源字符串的结尾位置。

示例:

var s = "Hello world!";

s.includes("o")  // true
s.startsWith("Hello") // true
s.endsWith("!") // true

这三个方法都支持第2个参数,表示开始匹配的位置。

示例:

s.includes("o", 8)  // false
s.startsWith("world", 6) // true
s.endsWith("Hello", 5) // true

模板字符串

模板字符串(template string)是增强版的字符串,用反引号(`)标识。它可以当做普通字符串使用,也可以用来定义多行字符串,或者在字符串中嵌入变量。在模板字符串中嵌入变量,需要将变量名写入${}中。

var name = 'Q1mi', age = 18;
`My name is ${name}, I’m ${age} years old.`

函数

箭头函数

箭头函数有个特点:

  1. 如果参数只有一个,可以省略小括号
  2. 如果不写return,可以不写大括号
  3. 没有arguments变量
  4. 不改变this指向
其中箭头函数中this指向被固定化,不是因为箭头函数内部有绑定this的机制。实际原因是箭头函数根本没有自己的this,导致内部的this就是外层代码块的this。
 
可以查看下面两段代码输出的区别:
var person = {
name: 'Q1mi',
age:18,
func:function(){
console.log(this);
}
}
person.func() // person对象

var person = {
name: 'Q1mi',
age:18,
func:()=>{
console.log(this);
}
}
person.func() // window对象

对象

属性简洁表示法

ES6允许直接写入变量和函数作为对象的属性和方法。
function (x, y){
return {x, y}
}

上面的写法等同于:

function(x, y){
return {x: x, y: y}
}

对象的方法也可以使用简洁表示法:

var o = {
method(){
return “Hello!”;
}
}

等同于:

var o = {
method: function(){
return “Hello!”;
}
}

Object.assign()

Object.assign方法用来将源对象(source)的所有可枚举属性复制到目标对象(target)。它至少需要两个对象作为参数,第一个参数是目标对象,第二个参数是源对象。

参数必须都是对象,否则抛出TypeError错误。

Object.assjgn只复制自身属性,不可枚举属性(enumerable为false)和继承的属性不会被复制。

简单示例:

var x = {name: "Q1mi", age: 18};
var y = x;
var z = Object.assign({}, x);
x.age = 20; x.age // y.age // z.age //

注意:

Object.assign方法的其他用处,可查看文末链接。

面向对象

ES5的构造对象的方式 使用构造函数来创造。构造函数唯一的不同是函数名首字母要大写。
function Point(x, y){
this.x = x;
this.y = y;
} // 给父级绑定方法
Point.prototype.toSting = function(){
return '(' + this.x + ',' + this.y + ')';
} var p = new Point(10, 20);
console.log(p.x)
p.toSting(); // 继承
function ColorPoint(x, y, color){
Point.call(this, x, y);
this.color = color;
}
// 继承父类的方法
ColorPoint.prototype = Object.create(Point.prototype);
// 修复 constructor
ColorPoint.prototype.constructor = Point;
// 扩展方法
ColorPoint.prototype.showColor = function(){
console.log('My color is ' + this.color);
} var cp = new ColorPoint(10, 20, "red");
console.log(cp.x);
console.log(cp.toSting());
cp.showColor()

ES6 使用Class构造对象的方式:

class Point{
constructor(x, y){
this.x = x;
this.y = y;
} // 不要加逗号
toSting(){
return `(${this.x}, ${this.y})`;
}
} var p = new Point(10, 20);
console.log(p.x)
p.toSting(); class ColorPoint extends Point{
constructor(x, y, color){
super(x, y); // 调用父类的constructor(x, y)
this.color = color;
} // 不要加逗号
showColor(){
console.log('My color is ' + this.color);
}
} var cp = new ColorPoint(10, 20, "red");
console.log(cp.x);
cp.toSting();
cp.showColor()

Promise

Promise 是异步编程的一种解决方案,比传统的解决方案(回调函数和事件)更合理、更强大。它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象。

使用Promise的优势是有了Promise对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。此外,Promise对象提供统一的接口,使得控制异步操作更加容易。

用法示例:

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

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

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

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

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

我们还可以将上面的代码写成下面这种方式:

promiseObj
.then(function(value) {
// success
})
.catch(function(error) {
// failure
});

其实Promise.prototype.catch方法是.then(null, rejection)的别名,用于指定发生错误时的回调函数。


注:

本文中的些许示例来自阮一峰的《ECMAScript 6 标准入门》

附:

想了解更多有关ES6标准内容,推荐阅读:阮一峰的ECMAScript 6 入门

多读书、多写码。世界很大,我们很小。

 

ES6 快速入门的更多相关文章

  1. ES6快速入门(二)数据结构

    ES6快速入门 一.解构 1. 对象解构 let person = { name: 'Tang', age: 28 }; //必须同名,必须初始化 let {name, age} = person; ...

  2. ES6快速入门(一)函数与作用域

    ES6快速入门 一.块级绑定 1.var声明与变量提升 使用var声明的变量,不论在何处都会被视为(声明)在函数级作用域顶部的位置发生. function getValue(condition) { ...

  3. python 全栈开发,Day88(csrf_exempt,ES6 快速入门,Vue)

    BBS项目内容回顾 1. 登陆页面 1. 验证码 1. PIL(Pillow) 2. io 2. ORM 1. 增删改查 3. AJAX $.ajax({ url: '', type: '', dat ...

  4. es6 快速入门 系列

    es6 快速入门(未完结,持续更新中...) 前言 为什么要学习es6 es6对于所有javaScript开发者来说,非常重要 未来,es6将构成javaScript应用程序的基础 es6中很多特性, ...

  5. es6 快速入门 —— 函数

    其他章节请看: es6 快速入门 系列 函数 函数是所有编程语言的重要组成部分,es6之前函数语法一直没什么变化,遗留了许多问题,javaScript开发者多年来不断抱怨,es6终于决定大力度更新函数 ...

  6. es6 快速入门 系列 —— 变量声明:let和const

    其他章节请看: es6 快速入门 系列 变量声明:let和const 试图解决的问题 经典的 var 声明让人迷惑 function demo1(v){ if(v){ var color='red' ...

  7. es6 快速入门 系列 —— promise

    其他章节请看: es6 快速入门 系列 Promise Promise 是一种异步编程的选择 初步认识Promise 用 Promise 来实现这样一个功能:发送一个 ajax,返回后输出 json ...

  8. es6快速入门 系列 - async

    其他章节请看: es6 快速入门 系列 async 前文我们已经知道 promise 是一种异步编程的选择.而 async 是一种用于执行异步任务更简单的语法. Tip:建议学完 Promise 在看 ...

  9. es6 快速入门 系列 —— 类 (class)

    其他章节请看: es6 快速入门 系列 类 类(class)是 javascript 新特性的一个重要组成部分,这一特性提供了一种更简洁的语法和更好的功能,可以让你通过一个安全.一致的方式来自定义对象 ...

  10. es6 快速入门 系列 —— 对象

    其他章节请看: es6 快速入门 系列 对象 试图解决的问题 写法繁杂 属性初始值需要重复写 function createPeople(name, age){ // name 和 age 都写了 2 ...

随机推荐

  1. Docker技术知识点总结

    Docker技术知识点总结 本文宿主机环境Centos7.4Docker version 18.09.2, build 6247962采用国内 Daocloud 加速器---------------- ...

  2. Qt之QComboBox定制(二)

    上一篇文章Qt之QComboBox定制讲到了qt实现自定义的下拉框,该篇文章主要实现了列表式的下拉框,这一节我还将继续讲解QComboBox的定制,而这一节我将会讲述更高级的用法,不仅仅是下拉列表框, ...

  3. 想在Java中实现Excel和Csv的导出吗?看这就对了

    前言 最近在项目中遇到一个需求,需要后端提供一个下载Csv和Excel表格的接口.这个接口接收前端的查询参数,针对这些参数对数据库做查询操作.将查询到的结果生成Excel和Csv文件,再以字节流的形式 ...

  4. SpringBoot读取yml中的配置,并分离配置文件

    前言 在项目中经常遇到需要读取配置文件中的配置信息,这些配置信息之所以不写在代码中是因为实际项目发布或者部署之后会进行更改,而如果写在代码中编译之后没有办法进行修改. 之前使用的是properties ...

  5. 是时候给你的产品配一个AI问答助手了!

    本文由云+社区发表 | 导语 问答系统是信息检索的一种高级形式,能够更加准确地理解用户用自然语言提出的问题,并通过检索语料库.知识图谱或问答知识库返回简洁.准确的匹配答案.相较于搜索引擎,问答系统能更 ...

  6. 为容器化的 Go 程序搭建 CI

    本文介绍如何使用 Jenkins 的声明式 pipeline 为一个简单的 Golang web 应用搭建 CI 环境.如果你还不太了解 Jenkins 及其声明式 pipeline,请先参考笔者的 ...

  7. 组合模式 合成模式 COMPOSITE 结构型 设计模式(十一)

    组合模式(合成模式 COMPOSITE) 意图 将对象组合成树形结构以表示“部分-整体”的层次结构. Composite使得用户对单个对象和组合对象的使用具有一致性.   树形结构介绍 为了便于理解, ...

  8. 第62章 EntityFramework支持 - Identity Server 4 中文文档(v1.0.0)

    为IdentityServer中的配置和操作数据扩展点提供了基于EntityFramework的实现.EntityFramework的使用允许任何EF支持的数据库与此库一起使用. 这个库的仓库位于这里 ...

  9. 学JAVA第三天,JAVA第二章《JAVA数据类型》

    ---恢复内容开始--- <JAVA数据类型> 我们一般都用int类型,因为int类行一般的日常生活的数据都能满足了. 当然,想李嘉诚,马云这种有钱人,int类行就不能满足帮他记钱的了,像 ...

  10. Win10系统简单开启热点

    介绍 笔记本电脑使用的都是无线网卡,我们可以通过这网卡来开启热点供手机使用,说起开热点,大家都是想到的使用360随身wifi或者是猎豹wifi来开启热点吧,我个人不太喜欢使用这些软件,原因因为有DNS ...