ECMAScript6快速入手攻略


Posted in Javascript onJuly 18, 2016

简介

ECMAScript 6 是JavaScript的下一个标准,正处在快速开发之中,ECMAScript 6 的目标,是使得JavaScript可以用来编写复杂的应用程序、函数库和代码的自动生成器(code generator)。最新的浏览器已经部分支持ECMAScript 6 的语法,ECMAScript 6 目前基本成为业界标准,它的普及速度比 ES5 要快很多,主要原因是现代浏览器对 ES6 的支持相当迅速,尤其是 Chrome 和 Firefox 浏览器,已经支持 ES6 中绝大多数的特性。

1. let、const 和 block 作用域

let 允许创建块级作用域,ES6 推荐在函数中使用 let 定义变量,而非 var:

var a = 2;
{
 let a = 3;
 console.log(a); // 3
}
console.log(a); // 2

同样在块级作用域有效的另一个变量声明方式是 const,它可以声明一个常量。ES6 中,const 声明的常量类似于指针,它指向某个引用,也就是说这个「常量」并非一成不变的,如:

{
 const ARR = [5,6];
 ARR.push(7);
 console.log(ARR); // [5,6,7]
 ARR = 10; // TypeError
}

有几个点需要注意:

let 关键词声明的变量不具备变量提升(hoisting)特性

let 和 const 声明只在最靠近的一个块中(花括号内)有效

当使用常量 const 声明时,请使用大写变量,如:CAPITAL_CASING

const 在声明时必须被赋值

2. 箭头函数(Arrow Functions)

ES6 中,箭头函数就是函数的一种简写形式,使用括号包裹参数,跟随一个 =>,紧接着是函数体:

var getPrice = function() {
 return 4.55;
};
 
// Implementation with Arrow Function
var getPrice = () => 4.55;

需要注意的是,上面栗子中的 getPrice 箭头函数采用了简洁函数体,它不需要reture 语句,下面这个栗子使用的是正常函数体:

let arr = ['apple', 'banana', 'orange'];
 
let breakfast = arr.map(fruit => {
 return fruit + 's';
});
 
console.log(breakfast); // apples bananas oranges

当然,箭头函数不仅仅是让代码变得简洁,函数中 this 总是绑定总是指向对象自身。具体可以看看下面几个栗子:

function Person() {
 this.age = 0;
 
 setInterval(function growUp() {
 // 在非严格模式下,growUp() 函数的 this 指向 window 对象
 this.age++;
 }, 1000);
}
var person = new Person();

我们经常需要使用一个变量来保存 this,然后在 growUp 函数中引用:

function Person() {
 var self = this;
 self.age = 0;

 setInterval(function growUp() {
 self.age++;
 }, 1000);
}

而使用箭头函数可以省却这个麻烦:

function Person(){
 this.age = 0;
 
 setInterval(() => {
 // |this| 指向 person 对象
 this.age++;
 }, 1000);
}
 
var person = new Person();

3. 函数参数默认值

ES6 中允许你对函数参数设置默认值:

let getFinalPrice = (price, tax=0.7) => price + price * tax;
getFinalPrice(500); // 850

4. Spread / Rest 操作符

Spread / Rest 操作符指的是 ...,具体是 Spread 还是 Rest 需要看上下文语境。

当被用于迭代器中时,它是一个 Spread 操作符:

function foo(x,y,z) {
 console.log(x,y,z);
}
 
let arr = [1,2,3];
foo(...arr); // 1 2 3

当被用于函数传参时,是一个 Rest 操作符:

function foo(...args) {
 console.log(args);
}
foo( 1, 2, 3, 4, 5); // [1, 2, 3, 4, 5]

5. 对象词法扩展

ES6 允许声明在对象字面量时使用简写语法,来初始化属性变量和函数的定义方法,并且允许在对象属性中进行计算操作:

function getCar(make, model, value) {
 return {
 // 简写变量
 make, // 等同于 make: make
 model, // 等同于 model: model
 value, // 等同于 value: value
 
 // 属性可以使用表达式计算值
 ['make' + make]: true,
 
 // 忽略 `function` 关键词简写对象函数
 depreciate() {
 this.value -= 2500;
 }
 };
}
 
let car = getCar('Barret', 'Lee', 40000);
 
// output: {
// make: 'Barret',
// model:'Lee',
// value: 40000,
// makeBarret: true,
// depreciate: function()
// }

6. 二进制和八进制字面量

ES6 支持二进制和八进制的字面量,通过在数字前面添加 0o 或者 0O 即可将其转换为二进制值:

let oValue = 0o10;
console.log(oValue); // 8
 
let bValue = 0b10; // 二进制使用 `0b` 或者 `0B`
console.log(bValue); // 2

7. 对象和数组解构

解构可以避免在对象赋值时产生中间变量:

function foo() {
 return [1,2,3];
}
let arr = foo(); // [1,2,3]
 
let [a, b, c] = foo();
console.log(a, b, c); // 1 2 3
 
function bar() {
 return {
 x: 4,
 y: 5,
 z: 6
 };
}
let {x: x, y: y, z: z} = bar();
console.log(x, y, z); // 4 5 6

8. 对象超类

ES6 允许在对象中使用 super 方法:

var parent = {
 foo() {
 console.log("Hello from the Parent");
 }
}
 
var child = {
 foo() {
 super.foo();
 console.log("Hello from the Child");
 }
}
 
Object.setPrototypeOf(child, parent);
child.foo(); // Hello from the Parent
  // Hello from the Child

9. 模板语法和分隔符

ES6 中有一种十分简洁的方法组装一堆字符串和变量。

${ ... } 用来渲染一个变量
` 作为分隔符

let user = 'Barret';
console.log(`Hi ${user}!`); // Hi Barret!

10. for...of VS for...in

for...of 用于遍历一个迭代器,如数组:

let nicknames = ['di', 'boo', 'punkeye'];
nicknames.size = 3;
for (let nickname of nicknames) {
 console.log(nickname);
}
Result: di, boo, punkeye

for...in 用来遍历对象中的属性:

let nicknames = ['di', 'boo', 'punkeye'];
nicknames.size = 3;
for (let nickname in nicknames) {
 console.log(nickname);
}
Result: 0, 1, 2, size

11. Map 和 WeakMap

ES6 中两种新的数据结构集:Map 和 WeakMap。事实上每个对象都可以看作是一个Map。

一个对象由多个 key-val 对构成,在 Map 中,任何类型都可以作为对象的 key,如:

var myMap = new Map();
 
var keyString = "a string",
 keyObj = {},
 keyFunc = function () {};
 
// 设置值
myMap.set(keyString, "value 与 'a string' 关联");
myMap.set(keyObj, "value 与 keyObj 关联");
myMap.set(keyFunc, "value 与 keyFunc 关联");
 
myMap.size; // 3
 
// 获取值
myMap.get(keyString); // "value 与 'a string' 关联"
myMap.get(keyObj); // "value 与 keyObj 关联"
myMap.get(keyFunc); // "value 与 keyFunc 关联"

WeakMap

WeakMap 就是一个 Map,只不过它的所有 key 都是弱引用,意思就是 WeakMap 中的东西垃圾回收时不考虑,使用它不用担心内存泄漏问题。

另一个需要注意的点是,WeakMap 的所有 key 必须是对象。它只有四个方法delete(key),has(key),get(key) 和 set(key, val):

let w = new WeakMap();
w.set('a', 'b'); 
// Uncaught TypeError: Invalid value used as weak map key
 
var o1 = {},
 o2 = function(){},
 o3 = window;
 
w.set(o1, 37);
w.set(o2, "azerty");
w.set(o3, undefined);
 
w.get(o3); // undefined, because that is the set value
 
w.has(o1); // true
w.delete(o1);
w.has(o1); // false

12. Set 和 WeakSet

Set 对象是一组不重复的值,重复的值将被忽略,值类型可以是原始类型和引用类型:

let mySet = new Set([1, 1, 2, 2, 3, 3]);
mySet.size; // 3
mySet.has(1); // true
mySet.add('strings');
mySet.add({ a: 1, b:2 });

可以通过 forEach 和 for...of 来遍历 Set 对象:

mySet.forEach((item) => {
 console.log(item);
 // 1
 // 2
 // 3
 // 'strings'
 // Object { a: 1, b: 2 }
});
 
for (let value of mySet) {
 console.log(value);
 // 1
 // 2
 // 3
 // 'strings'
 // Object { a: 1, b: 2 }
}

Set 同样有 delete() 和 clear() 方法。

WeakSet

类似于 WeakMap,WeakSet 对象可以让你在一个集合中保存对象的弱引用,在WeakSet 中的对象只允许出现一次:

var ws = new WeakSet();
var obj = {};
var foo = {};
 
ws.add(window);
ws.add(obj);
 
ws.has(window); // true
ws.has(foo); // false, foo 没有添加成功
 
ws.delete(window); // 从结合中删除 window 对象
ws.has(window); // false, window 对象已经被删除

13. 类

ES6 中有 class 语法。值得注意是,这里的 class 不是新的对象继承模型,它只是原型链的语法糖表现形式。

函数中使用 static 关键词定义构造函数的的方法和属性:

class Task {
 constructor() {
 console.log("task instantiated!");
 }
 
 showId() {
 console.log(23);
 }
 
 static loadAll() {
 console.log("Loading all tasks..");
 }
}
 
console.log(typeof Task); // function
let task = new Task(); // "task instantiated!"
task.showId(); // 23
Task.loadAll(); // "Loading all tasks.."

类中的继承和超集:

class Car {
 constructor() {
 console.log("Creating a new car");
 }
}
 
class Porsche extends Car {
 constructor() {
 super();
 console.log("Creating Porsche");
 }
}
 
let c = new Porsche();
// Creating a new car
// Creating Porsche

extends 允许一个子类继承父类,需要注意的是,子类的 constructor 函数中需要执行 super() 函数。

当然,你也可以在子类方法中调用父类的方法,如 super.parentMethodName()。

在 这里 阅读更多关于类的介绍。

有几点值得注意的是:

类的声明不会提升(hoisting),如果你要使用某个 Class,那你必须在使用之前定义它,否则会抛出一个 ReferenceError 的错误
在类中定义函数不需要使用 function 关键词

14. Symbol

Symbol 是一种新的数据类型,它的值是唯一的,不可变的。ES6 中提出 symbol 的目的是为了生成一个唯一的标识符,不过你访问不到这个标识符:

var sym = Symbol( "some optional description" );
console.log(typeof sym); // symbol

注意,这里 Symbol 前面不能使用 new 操作符。

如果它被用作一个对象的属性,那么这个属性会是不可枚举的:

var o = {
 val: 10,
 [ Symbol("random") ]: "I'm a symbol",
};
 
console.log(Object.getOwnPropertyNames(o)); // val

如果要获取对象 symbol 属性,需要使用 Object.getOwnPropertySymbols(o)。

15. 迭代器(Iterators)

迭代器允许每次访问数据集合的一个元素,当指针指向数据集合最后一个元素是,迭代器便会退出。它提供了 next() 函数来遍历一个序列,这个方法返回一个包含 done 和value 属性的对象。

ES6 中可以通过 Symbol.iterator 给对象设置默认的遍历器,无论什么时候对象需要被遍历,执行它的 @@iterator 方法便可以返回一个用于获取值的迭代器。

数组默认就是一个迭代器:

var arr = [11,12,13];
var itr = arr[Symbol.iterator]();
 
itr.next(); // { value: 11, done: false }
itr.next(); // { value: 12, done: false }
itr.next(); // { value: 13, done: false }
 
itr.next(); // { value: undefined, done: true }

你可以通过 [Symbol.iterator]() 自定义一个对象的迭代器。

16. Generators

Generator 函数是 ES6 的新特性,它允许一个函数返回的可遍历对象生成多个值。

在使用中你会看到 * 语法和一个新的关键词 yield:

function *infiniteNumbers() {
 var n = 1;
 while (true){
 yield n++;
 }
}
 
var numbers = infiniteNumbers(); // returns an iterable object
 
numbers.next(); // { value: 1, done: false }
numbers.next(); // { value: 2, done: false }
numbers.next(); // { value: 3, done: false }

每次执行 yield 时,返回的值变为迭代器的下一个值。

17. Promises

ES6 对 Promise 有了原生的支持,一个 Promise 是一个等待被异步执行的对象,当它执行完成后,其状态会变成 resolved 或者 rejected。

var p = new Promise(function(resolve, reject) { 
 if (/* condition */) {
 // fulfilled successfully
 resolve(/* value */); 
 } else {
 // error, rejected
 reject(/* reason */); 
 }
});

每一个 Promise 都有一个 .then 方法,这个方法接受两个参数,第一个是处理 resolved 状态的回调,一个是处理 rejected 状态的回调:

p.then((val) => console.log("Promise Resolved", val),
 (err) => console.log("Promise Rejected", err));

以上就是为大家整理的ECMAScript6快速入手的简介,需要的朋友们可以学习参考。

Javascript 相关文章推荐
40个有创意的jQuery图片和内容滑动及弹出插件收藏集之三
Jan 03 Javascript
JS实现页面超时后自动跳转到登陆页面
Jan 19 Javascript
JavaScript基础知识及常用方法总结
Jan 10 Javascript
JavaScript实现给定时间相加天数的方法
Jan 25 Javascript
Treegrid的动态加载实例代码
Apr 29 Javascript
深入理解JQuery循环绑定事件
Jun 02 Javascript
jquery无法为动态生成的元素添加点击事件的解决方法(推荐)
Dec 26 Javascript
浅谈JS如何实现真正的对象常量
Jun 25 Javascript
async/await地狱该如何避免详解
May 10 Javascript
Vue.js实现的表格增加删除demo示例
May 22 Javascript
webpack 动态批量加载文件的实现方法
Mar 19 Javascript
js实现网页随机验证码
Oct 19 Javascript
JavaScript读二进制文件并用ajax传输二进制流的方法
Jul 18 #Javascript
JavaScript暂停和继续定时器的实现方法
Jul 18 #Javascript
jquery+CSS3实现3D拖拽相册效果
Jul 18 #Javascript
完美实现八种js焦点轮播图(下篇)
Apr 20 #Javascript
完美实现八种js焦点轮播图(上篇)
Jul 18 #Javascript
jQuery实现根据滚动条位置加载相应内容功能
Jul 18 #Javascript
JS HTML5拖拽上传图片预览
Jul 18 #Javascript
You might like
用PHP实现维护文件代码
2007/06/14 PHP
PHP连接和操作MySQL数据库基础教程
2014/09/29 PHP
php四种定界符详解
2017/02/16 PHP
thinkphp3.2实现跨控制器调用其他模块的方法
2017/03/14 PHP
PHP操作MySQL中BLOB字段的方法示例【存储文本与图片】
2017/09/15 PHP
jQuery 使用个人心得
2009/02/26 Javascript
扩展jQuery 键盘事件的几个基本方法
2009/10/30 Javascript
javascript 的Document属性和方法集合
2010/01/25 Javascript
jquery下将选择的checkbox的id组成字符串的方法
2010/11/28 Javascript
基于JQuery实现鼠标点击文本框显示隐藏提示文本
2012/02/23 Javascript
JS Loading功能的简单实现
2013/11/29 Javascript
JS根据变量保存方法名并执行方法示例
2014/04/04 Javascript
jquery+ajax验证不通过也提交表单问题处理
2014/12/12 Javascript
JS基于面向对象实现的拖拽库实例
2015/09/24 Javascript
JavaScript中有关一个数组中最大值和最小值及它们的下表的输出的解决办法
2016/07/01 Javascript
微信jssdk用法汇总
2016/07/16 Javascript
快速理解 JavaScript 中的 LHS 和 RHS 查询的用法
2017/08/24 Javascript
微信小程序实现倒计时调用相机自动拍照功能
2018/06/10 Javascript
在微信小程序中使用图表的方法示例
2019/04/25 Javascript
layui实现数据表格隐藏列的示例
2019/10/25 Javascript
vue 实现click同时传入事件对象和自定义参数
2021/01/29 Vue.js
react项目从新建到部署的实现示例
2021/02/19 Javascript
[52:41]OG vs IG 2018国际邀请赛小组赛BO2 第二场 8.18
2018/08/20 DOTA
利用Python的Twisted框架实现webshell密码扫描器的教程
2015/04/16 Python
python gensim使用word2vec词向量处理中文语料的方法
2019/07/05 Python
python中提高pip install速度
2020/02/14 Python
Python selenium使用autoIT上传附件过程详解
2020/05/26 Python
HTML5应用之文件上传
2016/12/30 HTML / CSS
Canvas系列之滤镜效果
2019/02/12 HTML / CSS
应聘编辑自荐信范文
2014/03/12 职场文书
关于保护环境的建议书
2014/05/13 职场文书
2014年人事工作总结范文
2014/11/19 职场文书
《老人与海鸥》教学反思
2016/02/16 职场文书
golang 比较浮点数的大小方式
2021/05/02 Golang
如何用PHP实现分布算法之一致性哈希算法
2021/05/26 PHP
python处理json数据文件
2022/04/11 Python