ES6进修笔记

简介

  • ECMAScript(ECMA或ES) 是范例, JavaScript的是其范例的完成
  • ECMAScript 2015 = ES2015 ≈ ES6

ECMAScript 的汗青

时刻ECMAJS诠释
1996.11ES 1.0JS稳固Netscape将JS提交给ECMA组织,ES正式涌现
1998.06ES 2.0ES2正式宣布
1999.12ES 3.0ES3被普遍支撑
2007.10ES 4.0ES4过于激进,被废了
2008.07ES 3.14.0退化为严峻缩水版的3.1<br/>由于吵得太凶猛,所以ES 3.1代号为Harmony(调和)
2009.12ES 5.0ES 5.0正式宣布<br/>同时宣布了JavaScript.next也就是厥后的ES 6.0
2011.06ES 5.1ES 5.1成为了ISO国际规范
2013.03ES 6.0ES 6.0草案定稿
2013.12ES 6.0ES 6.0草案宣布
2015.06ES 6.0ES 6.0估计宣布正式版<br/>JavaScript.next最先指向ES 7.0

语法提案同意流程

Stage 0 - Strawman(展现阶段)
Stage 1 - Proposal(征求意见阶段)
Stage 2 - Draft(草案阶段)
Stage 3 - Candidate(候选人阶段)
Stage 4 - Finished(定案阶段)

由TC39 委员会同意

Let、const

  • 块级作用域
  • 不存在变量提拔

暂时性死区(temporal dead zone,简称 TDZ):在代码块内,声明变量之前,该变量都是不可用的。

  • 雷同作用域内,不许可反复声明
  • 辨别:

    • let声明变量
    • const声明只读常量,常量指向的谁人内存地址不得修改,且一旦声明变量,就必需马上初始化。

解构赋值

ES6 许可根据肯定情势,从数组和对象中提取值,对变量举行赋值,这被称为解构(Destructuring)。
适用于数组(这里泛指具有Iterator接口的数据组织)、对象、字符串、数值和布尔值,可设置默认值。

//数组
let [x, y = 'b', z='c'] = ['a', undefined, null];// x='a', y='b' z=null
//对象
let { bar, foo } = { foo: "aaa", bar: "bbb" };//foo = "aaa"; bar = "bbb"
//字符串,先转为数组
const [a, b, length : len] = 'ho';//a="h";b= "o";len = 2
//数值与布尔值,先转为对象
let {toString: s} = 123;//s = Number.prototype.toString
let {toString: s} = true;//s = Boolean.prototype.toString
  • 假如解构不胜利,变量的值就即是undefined
  • 只需当成员严厉即是undefined,默认值才会见效
  • 双方的组织要一致
  • 组织完马上赋值,组织和赋值不能离开举行
  • 运用于对象时,键对键,值对值;且大括号不能在行首(会明白成语法块),可用小括号包裹
  • 解构赋值的规则是,只需等号右侧的值不是对象或数组,就先将其转为对象

字符串扩大

查找

  • includes(String):是不是找到参数字符串。
  • startsWith(String):是不是以参数字符串开首。
  • endsWith(String):是不是以参数字符串末端。
let s = 'Hello world!';
s.includes('o') // true
//都可接收第二个位置参数

反复

  • repeat(Number)
'x'.repeat(3) // "xxx"

模板字符串

  • 支撑变量、表达式、函数挪用,许可嵌套
  • 反引号需运用反斜杠转义
  • trim消弭空格和换行
$('#result').append(`
  There are <b>${basket.count}</b> items
   in your basket, <em>${basket.onSale}</em>
  are on sale!
`);
//trim
$('#list').html(`
<ul>
  <li>first</li>
  <li>second</li>
</ul>
`.trim());

数值的扩大

  • Number.isFinite()-只对数值返回true
  • Number.isNaN()-只对NaN返回true
  • Number.isInteger()-只对整数返回true
  • Number.isSafeInteger()-只对平安整数(-2^53到2^53,不含端点)返回true
  • Number.MAX_SAFE_INTEGER,Number.MIN_SAFE_INTEGER平安整数的上下限常量
Number.isInteger(25) // true
Number.isInteger(25.0) // true
Number.isInteger(25.1) // false

Math对象扩大:http://es6.ruanyifeng.com/#do…

函数的扩大

  • 参数默认值,发起用于尾参数,不可在函数内再次声明
function log(x, y = 'World') {}
  • length:从第一个参数到首个指定默认值参数间参数的个数
(function (a, b = 1, c) {}).length // 1
  • rest:猎取函数的过剩参数,须用于尾参数
function add(...values) {}
add(2, 5, 3)
  • name:函数的名字
function f() {}
//或许
var f = function () {};
f.name // "f"

箭头函数

  • 只需一个参数,可省略参数的小括号,无参数时不可省略
  • 假如只需一条语句且无return,可以省略语句块的大括号
  • 假如只需一条语句且有return,可以省略大括号和return,唯一return(即return后无参数)时不可省略
  • 直接返回对象,须运用小括号包裹
let getTempItem = id => ({ id: id, name: "Temp" });
  • 可以运用解构赋值,可以嵌套
const full = ({ first, last }) => first + ' ' + last;
const pipeline = (...funcs) =>
  val => funcs.reduce((a, b) => b(a), val);
  • 注重:

    • 函数体内的this对象,就是定义时地点的对象,而不是运用时地点的对象。
    • 不可以看成组织函数,也就是说,不可以运用new敕令,不然会抛出一个毛病。
    • 不可以运用arguments对象,该对象在函数体内不存在。假如要用,可以用 rest 参数替代。
    • 不可以运用yield敕令,因而箭头函数不能用作 Generator 函数。

数组的扩大

扩大运算符

用于数组赋值须放在参数的末了一名。

console.log(1, ...[2, 3, 4], 5) // 1 2 3 4 5
//复制数组
const a1 = [1, 2];
const a2 = [...a1];// 写法一
const [...a2] = a1;// 写法二
//兼并数组
const a2 = [3, 4];
[...a1, ...a2] //[1,2,3,4]
//合营解构赋值
const [first, ...rest] = [1, 2, 3, 4, 5];// first= 1;rest= [2, 3, 4, 5]
//字符串
[...'hello'] // [ "h", "e", "l", "l", "o" ]

新增要领

  • Array.from():将数组对象(有length属性)或可遍历的对象(包括 ES6 新增的数据组织 Set 和 Map)转为真正的数组,接收第二个参数(对每一个元素举行处置惩罚,处置惩罚值返回数组)。
let arrayLike = {
    '0': 'a',
    '1': 'b',
    '2': 'c',
    length: 3
};
let arr2 = Array.from(arrayLike); // ['a', 'b', 'c']
  • Array.of():将一组值转换为数组。
Array.of(3, 11, 8) // [3,11,8]
  • copyWithin(target[必需,替代最先位置,负值为倒数], start = 0[可选,读取最先位置,负值为倒数], end = this.length[可选,读取完毕位置,负值为倒数]):在当前数组内部,将指定位置的成员复制到其他位置(会掩盖原有成员),然后返回当前数组。
[1, 2, 3, 4, 5].copyWithin(0, 3) // [4, 5, 3, 4, 5]
  • find(fn)findIndex(fn):找出第一个相符前提的数构成员。假如无相符前提的成员,返回undefined。
//find要领的回调函数可以接收三个参数,依次为当前的值、当前的位置和原数组
[1, 5, 10, 15].find(function(value, index, arr) {
  return value > 9;
}) // 10
  • fill(text[必需,添补内容],start = 0[可选,最先位置,负值为倒数], end = this.length[可选,完毕位置,负值为倒数]): 运用给定值,添补一个数组。
['a', 'b', 'c'].fill(7, 1, 2) // ['a', 7, 'c']
  • includes(text[必需,内容],start = 0[可选,搜刮最先位置,负值为倒数], end = this.length[可选,搜刮完毕位置,负值为倒数]):搜刮数组是不是包括给定的值。
[1, 2, 3].includes(3, -1); // true

对象的扩大

  • 简约示意:对象的key和value一样时,可以省略key,要领可省略function
const foo = 'bar';
const baz = {
    foo,
   method() {
    return "Hello!";
  }
}
  • 属性名表达式: 不能运用简约示意
let propKey = 'foo';

let obj = {
  [propKey]: true,
  ['a' + 'bc']: 123
}
  • Object.is(): 推断两值是不是相称
//和===的辨别
+0 === -0 //true
NaN === NaN // false
Object.is(+0, -0) // false
Object.is(NaN, NaN) // true
  • Object.assign(target[目的对象], source1, source2,...): 将源对象一切可罗列属性复制兼并到目的对象。
const target = { a: 1, b: 1 };
const source1 = { b: 2, c: 2 };
const source2 = { c: 3 };
Object.assign(target, source1, source2);
target // {a:1, b:2, c:3}
  • Object.assign要领实行的是浅拷贝,而不是深拷贝。也就是说,假如源对象某个属性的值是对象,那末目的对象拷贝获得的是这个对象的援用。
  • 碰到同名属性,Object.assign的处置惩罚要领是背面替代前面的。
  • Object.assign可以用来处置惩罚数组,然则会把数组视为对象。
  • Object.assign只能举行值的复制,假如要复制的值是一个取值函数,那末将求值后再复制。

Set和Map数据组织

Set(鸠合)

鸠合:鸠合是由一组无序且唯一(即不能反复)的项构成的,可以设想成鸠合是一个既没有反复元素,也没有递次观点的数组

基础用法

ES6 供应了新的数据组织 Set。它相似于数组,然则成员的值都是唯一的,没有反复的值。
Set 自身是一个组织函数,用来天生 Set 数据组织。

const s = new Set();

[2, 3, 5, 4, 5, 2, 2].forEach(x => s.add(x));

for (let i of s) {
  console.log(i);
}
// 2 3 5 4
// 去除数组的反复成员
const set = new Set([1, 2, 3, 4, 4]);
[...set]
// [1, 2, 3, 4]

向 Set 到场值的时刻,不会发作范例转换。

属性和要领

Set 组织的实例有以下属性。

  • size:返回Set实例的成员总数。
实例操纵要领(用于操纵数据)
  • add(value):增加某个值,返回 Set 组织自身。
  • delete(value):删除某个值,返回一个布尔值,示意删除是不是胜利。
  • has(value):返回一个布尔值,示意该值是不是为Set的成员。
  • clear():消灭一切成员,没有返回值。
s.add(1).add(2).add(2);
// 注重2被到场了两次

s.size // 2

s.has(1) // true
s.has(2) // true
s.has(3) // false

s.delete(2);
s.has(2) // false
遍历要领(用于遍历成员)

Set 组织的实例有四个遍历要领,可以用于遍历成员。

  • keys():返回键名的遍历器
  • values():返回键值的遍历器
  • entries():返回键值对的遍历器
  • forEach():运用回调函数遍历每一个成员

须要迥殊指出的是,Set的遍历递次就是插进去递次。这个特征偶然异常有效,比方运用 Set 保留一个回调函数列表,挪用时就可以保证根据增加递次挪用。

let set = new Set(['red', 'green', 'blue']);

for (let item of set.keys()) {
  console.log(item);
}
// red
// green
// blue

for (let item of set.values()) {
  console.log(item);
}
// red
// green
// blue

for (let item of set.entries()) {
  console.log(item);
}
// ["red", "red"]
// ["green", "green"]
// ["blue", "blue"]

WeakSet

WeakSet 组织与 Set 相似,也是不反复的值的鸠合。然则,它与 Set 有两个辨别。

起首,WeakSet 的成员只能是对象,而不能是其他范例的值;

WeakSet 中的对象都是弱援用,即渣滓接纳机制不斟酌 WeakSet 对该对象的援用,也就是说,假如其他对象都不再援用该对象,那末渣滓接纳机制会自动接纳该对象所占用的内存。

语法

WeakSet 是一个组织函数,可以运用new敕令,建立 WeakSet 数据组织。

const a = [[1, 2], [3, 4]];
const ws = new WeakSet(a);
// WeakSet {[1, 2], [3, 4]}

要领

WeakSet 组织有以下三个要领。

  • add(value):向 WeakSet 实例增加一个新成员。
  • delete(value):消灭 WeakSet 实例的指定成员。
  • has(value):返回一个布尔值,示意某个值是不是在 WeakSet 实例当中。

Map(字典)

相似对象,唯一的辨别是key的局限不限于字符串,种种范例的值(包括对象)都可以看成键。重要用于数据存储

const map = new Map([
  ['name', '张三'],
  ['title', 'Author']
]);

map.size // 2
map.has('name') // true
map.get('name') // "张三"
map.has('title') // true
map.get('title') // "Author"

属性和要领

  • size:属性返回 Map 组织的成员总数。
  • set(key, value):

set要领设置键名key对应的键值为value,然后返回全部 Map 组织。假如key已经有值,则键值会被更新,不然就新天生该键。

const m = new Map();

m.set('edition', 6)        // 键是字符串
m.set(262, 'standard')     // 键是数值
m.set(undefined, 'nah')    // 键是 undefined
//或许
let map = new Map()
  .set(1, 'a')
  .set(2, 'b')
  .set(3, 'c');
  • get(key):

get要领读取key对应的键值,假如找不到key,返回undefined。

  • has(key):

has要领返回一个布尔值,示意某个键是不是在当前 Map 对象当中

  • delete(key):

delete要领删除某个键,返回true。假如删除失利,返回false。

  • clear():

clear要领消灭一切成员,没有返回值。

遍历:

供应三个遍历器天生函数和一个遍历要领。Map 的遍历递次就是插进去递次

  • keys():返回键名的遍历器。
  • values():返回键值的遍历器。
  • entries():返回一切成员的遍历器。
  • forEach():遍历 Map 的一切成员。

数据组织转换

  • Map 转为数组
const myMap = new Map()
  .set(true, 7)
  .set({foo: 3}, ['abc']);
[...myMap]
// [ [ true, 7 ], [ { foo: 3 }, [ 'abc' ] ] ]
  • 数组 转为 Map
new Map([
  [true, 7],
  [{foo: 3}, ['abc']]
])
// Map {
//   true => 7,
//   Object {foo: 3} => ['abc']
// }
  • Map 转为对象
function strMapToObj(strMap) {
  let obj = Object.create(null);
  for (let [k,v] of strMap) {
    obj[k] = v;
  }
  return obj;
}

const myMap = new Map()
  .set('yes', true)
  .set('no', false);
strMapToObj(myMap)
// { yes: true, no: false }
  • 对象转为 Map
function objToStrMap(obj) {
  let strMap = new Map();
  for (let k of Object.keys(obj)) {
    strMap.set(k, obj[k]);
  }
  return strMap;
}

objToStrMap({yes: true, no: false})
// Map {"yes" => true, "no" => false}
  • Map 转为 JSON

Map 转为 JSON 要辨别两种状况。一种状况是,Map 的键名都是字符串,这时候可以挑选转为对象 JSON。

function strMapToJson(strMap) {
  return JSON.stringify(strMapToObj(strMap));
}

let myMap = new Map().set('yes', true).set('no', false);
strMapToJson(myMap)
// '{"yes":true,"no":false}'

另一种状况是,Map 的键名有非字符串,这时候可以挑选转为数组 JSON。

function mapToArrayJson(map) {
  return JSON.stringify([...map]);
}

let myMap = new Map().set(true, 7).set({foo: 3}, ['abc']);
mapToArrayJson(myMap)
// '[[true,7],[{"foo":3},["abc"]]]'
  • JSON 转为 Map

JSON 转为 Map,一般状况下,一切键名都是字符串。

function jsonToStrMap(jsonStr) {
  return objToStrMap(JSON.parse(jsonStr));
}

jsonToStrMap('{"yes": true, "no": false}')
// Map {'yes' => true, 'no' => false}

然则,有一种特殊状况,全部 JSON 就是一个数组,且每一个数构成员自身,又是一个有两个成员的数组。这时候,它可以一一对应地转为 Map。这往往是数组转为 JSON 的逆操纵。

function jsonToMap(jsonStr) {
  return new Map(JSON.parse(jsonStr));
}

jsonToMap('[[true,7],[{"foo":3},["abc"]]]')
// Map {true => 7, Object {foo: 3} => ['abc']}

WeakMap

WeakMap组织与Map组织相似,也是用于天生键值对的鸠合。
辨别:

  • WeakMap只接收对象作为键名(null除外),不接收其他范例的值作为键名。
  • WeakMap的键名所指向的对象,不计入渣滓接纳机制。

辨别

鸠合又和字典有什么辨别呢:

  • 共同点:鸠合、字典可以存储不反复的值
  • 差别点:鸠合是以[值,值]的情势存储元素,字典是以[键,值]的情势存储

Promise对象

Promise 是异步编程的一种解决计划,比传统的解决计划(回调函数和事宜),更合理和更壮大。

  • 特性:

    • 对象的状况[pending(举行中)、fulfilled(已胜利)和rejected(已失利)]不受外界影响
    • 一旦状况转变,就不会再变,任何时刻获得的都是这个效果
const promise = new Promise(function(resolve, reject) {
  // ... some code
  if (/* 异步操纵胜利 */){
    resolve(value); //将Promise对象的状况从“未完成”变成“胜利”,并将异步操纵的效果,作为参数通报出去
  } else {
    reject(error); //将Promise对象的状况从“未完成”变成“失利”,并将异步操纵报出的毛病,作为参数通报出去
  }
});
//挪用
promise.then(value=> {
  // success
}, error=> { //可选
  // failure
});
//或许
promise.then(value => {
  // success
}).catch(error => {
  // failure
});
  • Promise.all([p1, p2, ...]): 将多个 Promise 包装成一个新的 Promise ,状况和值取决于内里的实例(fulfilled:需均胜利,返回包括每一个实例返回值的数组;rejected:最少一个失利,返回第一个失利的实例返回值)
  • Promise.race([p1, p2, ...]): 将多个 Promise 包装成一个新的 Promise,状况和参数均由内里第一个转变的状况的实例决议
  • Promise.resolve():简写,将现有对象转为 状况为fulfilled的Promise 对象。
Promise.resolve('foo')
// 等价于
new Promise(resolve => resolve('foo'))
  • Promise.reject():简写,将现有对象转为 状况为rejected的Promise 对象。
const p = Promise.reject('出错了');
// 等同于
const p = new Promise((resolve, reject) => reject('出错了'))

Iterator(遍历器)

观点

数据鸠合:重如果Array,Object,Map,Set。
遍历器(Iterator)为上述数据鸠合供应了一致的接见机制。

Iterator 的作用有三个:
  • 一是为种种数据组织,供应一个一致的、轻便的接见接口;
  • 二是使得数据组织的成员可以按某种序次分列;
  • 三是 ES6 制造了一种新的遍历敕令for…of轮回,Iterator 接口重要供for…of消耗。

for…of 轮回

const arr = ['red', 'green', 'blue'];

for(let v of arr) {
  console.log(v); // red green blue
}
辨别:
  • for…in遍历键名,for…of遍历键值
var arr = ['a', 'b', 'c', 'd'];

for (let a in arr) {
  console.log(a); // 0 1 2 3
}

for (let a of arr) {
  console.log(a); // a b c d
}
  • for…of可以合营break、continue和return运用
for (var n of fibonacci) {
  if (n > 1000)
    break;
  console.log(n);
}

Generator

观点

Generator 函数是 ES6 供应的一种异步编程解决计划。
Generator 函数是一个状况机,封装了多个内部状况。

function* helloWorldGenerator() {
  yield 'hello';
  yield 'world';
  return 'ending';
}

var hw = helloWorldGenerator();
hw.next()
// { value: 'hello', done: false }
hw.next()
// { value: 'world', done: false }

hw.next()
// { value: 'ending', done: true }

Generator 函数的挪用要领与一般函数一样,也是在函数名背面加上一对圆括号。差别的是,挪用 Generator 函数后,该函数并不实行,必需挪用next()才会实行,返回的也不是函数运转效果,而是一个指向内部状况的指针对象(yield)。

yield 表达式

遍历器对象的next要领的运转逻辑以下。

  • (1)碰到yield表达式,就停息实行背面的操纵,并将紧跟在yield背面的谁人表达式的值,作为返回的对象的value属性值。
  • (2)下一次挪用next要领时,再继续往下实行,直到碰到下一个yield表达式。
  • (3)假如没有再碰到新的yield表达式,就一向运转到函数完毕,直到return语句为止,并将return语句背面的表达式的值,作为返回的对象的value属性值。
  • (4)假如该函数没有return语句,则返回的对象的value属性值为undefined。
  • yield其实是两个动作的合体:丢东西出去->等东西进来;

每次next()都会跑到yield丢东西出来的那个步骤

//输入输出:yield右侧为输出(next返回值的value,末了一次由return返回),左侧为输入(接收的是next的参数,第一次由函数参数传入),
function * input(){
    let array = [], i = 4;
    while(i) {
        array.push(yield array);
        i --;
    }
}

var gen = input();
console.log(gen.next("西")) // { value: [], done: false }
console.log(gen.next("部")) // { value: [ '部' ], done: false }
console.log(gen.next("世")) // { value: [ '部', '世' ], done: false }
console.log(gen.next("界")) // { value: [ '部', '世', '界' ], done: false }

next 要领的参数

yield表达式自身没有返回值,或许说老是返回undefined。next要领可以带一个参数,该参数就会被看成上一个yield表达式的返回值。

for…of 轮回

for…of轮回可以自动遍历 Generator 函数时天生的Iterator对象,且此时不再须要挪用next要领。

function* foo() {
  yield 1;
  yield 2;
  yield 3;
  yield 4;
  yield 5;
  return 6;
}

for (let v of foo()) {
  console.log(v);
}
// 1 2 3 4 5

next()、throw()、return() 的共同点

next()、throw()、return()这三个要领本质上是统一件事,可以放在一同明白。它们的作用都是让 Generator 函数恢复实行,而且运用差别的语句替代yield表达式。

  • next()是将yield表达式替代成一个值。
const g = function* (x, y) {
  let result = yield x + y;
  return result;
};

const gen = g(1, 2);
gen.next(); // Object {value: 3, done: false}

gen.next(1); // Object {value: 1, done: true}
// 相称于将 let result = yield x + y
// 替代成 let result = 1;
  • throw()是将yield表达式替代成一个throw语句。
gen.throw(new Error('出错了')); // Uncaught Error: 出错了
// 相称于将 let result = yield x + y
// 替代成 let result = throw(new Error('出错了'));
  • return()是将yield表达式替代成一个return语句。
gen.return(2); // Object {value: 2, done: true}
// 相称于将 let result = yield x + y
// 替代成 let result = return 2;

yield* 表达式

在 Generator 函数内部,挪用另一个 Generator 函数

function* bar() {
  yield 'x';
  yield* foo();
  yield 'y';
}

// 等同于
function* bar() {
  yield 'x';
  yield 'a';
  yield 'b';
  yield 'y';
}

// 等同于
function* bar() {
  yield 'x';
  for (let v of foo()) {
    yield v;
  }
  yield 'y';
}

for (let v of bar()){
  console.log(v);
}
// "x"
// "a"
// "b"
// "y"

作为对象属性的 Generator 函数

let obj = {
  * myGeneratorMethod() {
    ···
  }
};
//等价于
let obj = {
  myGeneratorMethod: function* () {
    // ···
  }
};

运用

  • ajax
function* main() {
  var result = yield request("http://some.url");
  var resp = JSON.parse(result);
    console.log(resp.value);
}

function request(url) {
  makeAjaxCall(url, function(response){
    it.next(response);
  });
}

var it = main();
it.next();

更多Generator 函数的异步运用:http://es6.ruanyifeng.com/#do…

http://jsfiddle.net/Yoghurts/…
ES7引入 async await,使其越发好用

应用ES6中的Generator完成并发编程

参考资料

ES6完成

// 停息
function sleep(numberMillis) {
    var now = new Date();
    var exitTime = now.getTime() + numberMillis;
    while (true) {
        now = new Date();
        if (now.getTime() > exitTime){
            return;
        }
    }
}

// 消耗者
function* consumer(name) {
    console.log(`${name}预备吃包子啦!`);
    while (true) {
        var baozi = yield;
        baozi += 1;
        console.log(`第${baozi}个包子来了,被分成了两份,一份被${name}吃了!`);
    }
}

// 临盆者
function producer(name) {
    c1 = consumer('A');
    c2 = consumer('B');
    console.log(`${name}:我最先预备做包子了!`);
    c1.next();
    c2.next();
    for (let i = 0; i < 10; i++) {
        sleep(1000);
        c1.next(i);
        c2.next(i);
    }
}

// 小明最先临盆包子,A和B同时最先吃包子
producer('小明')

运转效果

小明:我最先预备做包子了!
A预备吃包子啦!
B预备吃包子啦!
第1个包子来了,被分成了两份,一份被A吃了!
第1个包子来了,被分成了两份,一份被B吃了!
第2个包子来了,被分成了两份,一份被A吃了!
第2个包子来了,被分成了两份,一份被B吃了!
第3个包子来了,被分成了两份,一份被A吃了!
第3个包子来了,被分成了两份,一份被B吃了!
第4个包子来了,被分成了两份,一份被A吃了!
第4个包子来了,被分成了两份,一份被B吃了!
第5个包子来了,被分成了两份,一份被A吃了!
第5个包子来了,被分成了两份,一份被B吃了!
第6个包子来了,被分成了两份,一份被A吃了!
第6个包子来了,被分成了两份,一份被B吃了!
第7个包子来了,被分成了两份,一份被A吃了!
第7个包子来了,被分成了两份,一份被B吃了!
第8个包子来了,被分成了两份,一份被A吃了!
第8个包子来了,被分成了两份,一份被B吃了!
第9个包子来了,被分成了两份,一份被A吃了!
第9个包子来了,被分成了两份,一份被B吃了!
第10个包子来了,被分成了两份,一份被A吃了!
第10个包子来了,被分成了两份,一份被B吃了!

Class

定义类

//之前
function Point(x, y) {
  this.x = x;
  this.y = y;
}

Point.prototype.toString = function () {
  return '(' + this.x + ', ' + this.y + ')';
};

var p = new Point(1, 2);

ES6 的class可以看做只是一个语法糖,它的绝大部分功用,ES5 都可以做到,新的class写法只是让对象原型的写法越发清楚、更像面向对象编程的语法罢了。

//es6
class Point {
//组织要领
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }

  toString() {
    return '(' + this.x + ', ' + this.y + ')';
  }
}
var p = new Point(1, 2);

继续类

class Point {
}

class ColorPoint extends Point {
}

module

简介

在 ES6 之前,社区制订了一些模块加载计划,最重要的有 CommonJS 和 AMD 两种。前者用于服务器,后者用于浏览器。ES6 在言语规范的层面上,完成了模块功用,而且完成得相称简朴,完全可以庖代 CommonJS 和 AMD 范例,成为浏览器和服务器通用的模块解决计划。

严厉情势

ES6 的模块自动采纳严厉情势,不论你有无在模块头部加上"use strict";

严厉情势重要有以下限定:

  • 变量必需声明后再运用
  • 函数的参数不能有同名属性,不然报错
  • 不能运用with语句
  • 不能对只读属性赋值,不然报错
  • 不能运用前缀 0 示意八进制数,不然报错
  • 不能删除不可删除的属性,不然报错
  • 不能删除变量delete prop,会报错,只能删除属性delete global[prop]
  • eval不会在它的外层作用域引入变量
  • eval和arguments不能被从新赋值
  • arguments不会自动反应函数参数的变化
  • 不能运用arguments.callee
  • 不能运用arguments.caller
  • 制止this指向全局对象
  • 不能运用fn.caller和fn.arguments猎取函数挪用的客栈
  • 增加了保留字(比方protected、static和interface)

export 敕令

定义模块的对外接口。
一个模块就是一个自力的文件。该文件内部的一切变量,外部没法猎取。假如你愿望外部可以读取模块内部的某个变量,就必需运用export关键字输出该变量。
以下是几种用法:

//------输出变量------
export var firstName = 'Michael';
export var lastName = 'Jackson';
//等价于
var firstName = 'Michael';
export {firstName}; //引荐,能消灭晓得输出了哪些变量
//------输出函数或类------
export function multiply(x, y) {
  return x * y;
};
//------输出并as重命名------
var v1 = 'Michael';
function v2() { ... }
export {
  v1 as streamV1,
  v2 as streamV2
};
//------输出default------
export default function () { ... }

注重:export default在一个模块中只能有一个。

import 敕令

运用export敕令定义了模块的对外接口今后,其他 JS 文件就可以够经由过程import敕令加载这个模块。
以下是几种用法,必需和上面的export对应:

//------加载变量、函数或类------
import {firstName, lastName} from './profile.js';
//------加载并as重命名------
import { lastName as surname } from './profile.js';
//------加载有default输出的模块------
import v1 from './profile.js';
//------实行所加载的模块------
import 'lodash';
//------加载模块一切输出------
import  * as surname from './profile.js';

复合写法

假如在一个模块当中,先输入后输出统一个模块,import语句可以与export语句写在一同。

export { foo, bar } from 'my_module';

// 等同于
import { foo, bar } from 'my_module';
export { foo, bar };

Symbol

原始数据范例Symbol,示意举世无双的值。

let s = Symbol();

typeof s
// "symbol"

Symbol函数可以接收一个字符串作为参数,示意对 Symbol 实例的形貌,重如果为了在控制台显现,或许转为字符串时,比较轻易辨别。

let s1 = Symbol('foo');
let s2 = Symbol('bar');

s1 // Symbol(foo)
s2 // Symbol(bar)

s1.toString() // "Symbol(foo)"
s2.toString() // "Symbol(bar)"

Proxy

代办器(阻拦器),Proxy 可以明白成,在目的对象之前架设一层“阻拦”,外界对该对象的接见,都必需先经由过程这层阻拦,因而供应了一种机制,可以对外界的接见举行过滤和改写。

var proxy = new Proxy(target, handler);
  • target参数示意所要阻拦的目的对象
  • handler参数也是一个对象,用来定制阻拦行动。
var obj = new Proxy({}, {
  get: function (target, key, receiver) {
    console.log(`getting ${key}!`);
    return target.key;
  },
  set: function (target, key, value, receiver) {
    console.log(`setting ${key}!`);
    return target.key=value;
  }
});
    原文作者:BWrong
    原文地址: https://segmentfault.com/a/1190000013017048
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞