30分钟快速上手ES6(上)
狗年春节刚过,今天第一天上班。新的技术总是很快的占到主导地位。快到你觉得他仿佛就是昨天推出来的。15年来,一直主动或被动地去学习这些新技术。只为了自己不落伍。转眼看,ES6已是两年前的东西了。
1.箭头函数
[1, 2, 3, 4, 5].map(function(v){ return v + 1 }) // 使用箭头函数更改 [1, 2, 3, 4, 5].map(v => v + 1)
function Person(){ this.name = 'Person' this.hello = () => { console.log(this.name) } } var xiaoming = new Person xiaoming.hello.bind({name: 'xiaoming'})() //Person
通俗地讲:
特性一:
箭头前面是一个函数的参数,箭头后面是一个函数的主表达式。
特性二:
this被锁死,不会因上下文的修改而改变。
2.Default + Rest + Spread
语法糖
a.表达式做默认值(参数)
function f(x, y=12) { // y is 12 if not passed (or passed as undefined) return x + y; } f(3) == 15
看那个参数Y,在传入时直接给了默认值
b.Rest(省略号引进参数, 可以把传的参数直接用做数组)接合spread更好理解
function add(...values) { var sum = 0; for (var val of values) { sum += val; } return sum; } add(2, 5, 3) // 10
c.spread 展开运算符(spread)是三个点(…)
可以将数组转为用逗号分隔的参数序列
实战案例:
Math.max(...[14, 3, 77])
等价表达
function func(x, y, z) { } var args = [0, 1, 2]; // ES5写法 func.apply(null, args); // ES6写法 func(...args);
3.Destructuring 解构赋值
通俗来讲就是相同的结构下,方便赋值
// 数组匹配赋值 var [a, , b] = [1, 2, 3]; // 对象匹配赋值 var { foo, bar } = { foo: "aaa", bar: "bbb" }; // 支持带默认值的解构赋值 var [a = 1] = []; a === 1; var {a = 1} = {}; a === 1;
从对象中提取相应的键值尤其方便
// 从对象中提取键值 var jsonData = { id: 42, status: "OK", data: [867, 5309] } // 把键名data更改为number let { id, status, data: number } = jsonData; console.log(id, status, number) // 42, OK, [867, 5309]
4.Template strings 模板字符串取代连接字符串
function authorize(user, action) { if (!user.hasPrivilege(action)) { throw new Error( `用户 ${user.name} 未被授权执行 ${action} 操作。`); } }
ES6引入了一种新型的字符串字面量语法,我们称之为模板字符串(template strings)。除了使用反撇号字符 ` 代替普通字符串的引号 ‘ 或 ” 外,它们看起来与普通字符串并无二致。
5.Enhanced Object Literals
var obj = { handler, toString() { return "d " + super.toString(); }, [ 'prop_' + (() => 42)() ]: 42 };
它允许了对象字面量的键名使用变量定义,关键是使用中括号[]就可以激活这个语法糖了
6.Let + Const
function printName() { if(true) { var name = "hello"; } console.log(name); // hello }
function printName() { if(true) { let name = "hello"; } console.log(name); // 此处应有报错 }
没错,你的眼睛木有看错,ES6所提供的新标识符let让我们在定义变量的时候,在块级代码中具有作用域的效果,而在使用let定义的变量是不会带来变量提升的问题。这个对于Javascript来说是具有非常重大的意义,在前端的一些开发准则里面都提及,在定义变量的时候,需要把所使用的函数、变量在最开头先定义,都是为了避免变量提升所带来的副作用。而ES6从语法上去规限我们的代码,而不需要人为的约定。
7.Map + Set
好在ES6里面给我们提供了一个原生的字典数据结构Map,它的使用方法非常简单,请看代码,嗷嗷:
// Map
var m = new Map();
m.set(‘hello’, 42);
m.get(‘hello’); //42
Map顾名思义是一个k-v存储的数据结构,类似Object,但是它更具有语义性,并且提供了内置的getter/setter,迭代器等方法:
ajax.cache = new Map;
ajax.getDict = function(key, fn){
let cache = this.cache.get(key);
if(cache){
return fn(cache)
}
else{
// ajax code
}
}
// Set
var s = new Set();
s.add(“hello").add("goodbye").add("hello");
s.size === 2;
s.has("hello") === true;
set 相当于一个可以天然去重复的数组。
-
Maps类似Object,更适合KV结构
-
Sets类似Array,但是不允许有重复值
8.Classes
// 动物Sample万年梗DEMO // 以下是用传统得不能再传统的方式来展示如何创建类,在原型上定义方法 function Animal (word){ this.word = word; } Animal.prototype.speak = function(){ console.log(this.word) } var cat = new Animal('喵'); cat.speak()
ES6 中 Class 语法糖的做法:
class Animal{ constructor(word) { this.word = word; } speak() { console.log(this.word); } } var cat = new Animal('喵'); cat.speak()
省了好几行代码
9.Subclassable Built-ins
可子类化的内建对象
“ES6可以自定义原生数据结构(比如Array、String等)的子类,而ES5却无法做到。”
// Pseudo-code of Array // Array伪代码 class Array { constructor(...args) { /* ... */ } static [Symbol.create]() { // Install special [[DefineOwnProperty]] // to magically update 'length' } } // User code of Array subclass // Array子类的用户代码 class MyArray extends Array { constructor(...args) { super(...args); } } // Two-phase 'new': // 1) Call @@create to allocate object // 2) Invoke constructor on new instance // 两阶段的'new': // 1) 调用@@create来为对象分配空间 // 2) 在新实例上调用构造函数 var arr = new MyArray(); arr[1] = 12; arr.length == 2
10.Modules 模块
ES6 在语言层面上支持使用模块来进行组件定义,将流行的JavaScript模块加载器(AMD、CommonJS)中的模式固化到了语言中。运行时行为由宿主定义的默认加载器定义,隐式异步模型 – 直到(全部)请求的模块均可用且经处理后,才会执行(当前模块内的)代码。
// lib/math.js export function sum(x, y) { return x + y; } export var pi = 3.141593; // app.js import * as math from "lib/math"; alert("2π = " + math.sum(math.pi, math.pi)); // otherApp.js import {sum, pi} from "lib/math"; alert("2π = " + sum(pi, pi)); // lib/mathplusplus.js export * from "lib/math"; export var e = 2.71828182846; export default function(x) { return Math.log(x); } // app.js import ln, {pi, e} from "lib/mathplusplus"; alert("2π = " + ln(e)*pi*2);