|

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);

类似文章