es6------------------------------学习笔记

import { Agent } from "http";

 

// es6新增块作用域 声明变量const和 let作用于块

// const声明的常量不可以重新赋值,但是对象可以发生改变

function test() {

const PI = 3.14;

const k = {

a: 1

}

k.b = 3;

// 输出为object:{a:1 ,b:2}

}

 

// 解构赋值 左右结构不一相互赋值 分类:数组、对象、字符串、布尔值、函数参数、数值等解构赋值

{

let a, b, rest;

[a, b] = [1, 2];

console.log(a, b);

// 输出1 2

}

{

let a, b, rest;

[a, b, ...rest] = [1, 2, 3, 4, 5, 6];

console.log(a, b, rest);

// 输出1 2 [3,4,5,6]

}

// 对象解构赋值

{

let a, b;

({ a, b } = { a: 1, b: 2 })

console.log(a, b);

// 输出1 2

}

{

let a, b, c, rest;

[a, b, c = 3] = [1, 2];

console.log(a, b, c);

// 输出1 2 3 解构元素没有配对时为undefined

}

{

let a = 1;

let b = 2;

[a, b] = [b, a]

console.log(a, b);

// 输出2 1 解构赋值方便两个变量值的交换

}

{

function f() {

return [1, 2]

}

let a, b;

[a, b] = f();

console.log(a, b);

// 输出1 2

}

{

function f() {

return [1, 2, 3, 4, 5]

}

let a, b, c;

[a, , , b] = f();

console.log(a, b);

// 输出1 4 选择性接受变量

}

// 对象解构

{

let o = { p: 42, q: true };

let { p, q } = o;

console.log(p, q);

}

{

let { a = 10, b = 5 } = { a: 3 };

console.log(a, b);

// 输出3 5 后覆盖前

}

{

let metaData = {

title: 'abc',

test: [{ title: 'test', desc: 'description' }]

}

let { title: esTitle, test: [{ title: cnTitle }] } = metaData;

console.log(esTitle, cnTitle);

//输出'abc''test'

}

 

//正则扩展 构造函数的变化 正则方法的扩展 u修饰符 y修饰符 s修饰符

{

let regex = new RegExp('xyz', 'i');//es5

let regex2 = new RegExp(/xyz/i);//es5 正则表达式,该写法只能有一个参数

console.log(regex.test('xyz123'), regex2.test('xyz1223'));//true

let regex3 = new RegExp(/xyz/ig, 'i');//es6可以有两个参数,后面的修饰符会覆盖前面的

console.log(regex3.flags);//输出i,flags用来获取正则表达式的修饰符

}

// y修饰符 与g一样都是全局匹配符,g从上次匹配到的位置开始找下一个匹配的,g就是上次匹配的位置开始就要求匹配

{

let s = 'bbb_bb_b';

let a1 = /b+/g;

let a2 = /b+/y;

console.log('one', a1.exec(s), a2.exec(s));//bbb,bbb

console.log('one', a1.exec(s), a2.exec(s));//bb,null(_)

console.log(a1.sticky, a2.sticky);//false,true判断是否开启y修饰符

}

//u特征值 识别unicode编码

{

console.log('u-1', /^\uD83D/.test('\uD83D/\uDC2A/'));//true 两个字符

console.log('u-1', /^\uD83D/u.test('\uD83D/\uDC2A/'));//false 一个字符

 

console.log(/\u{61}/.test('a'));//false

console.log(/\u{61}/u.test('a'));//true

 

console.log('\u{20887}');

let s = '?';

console.log('u', /^.$/.test(s));//false ‘.’只能匹配小于两个字节,且不能识别/t,/n加s修饰符

console.log('u-2', /^.$/u.test(s));//true 大于两字节则需要u修饰符

 

console.log('test', /?{2}/.test('??'));//false

console.log('test', /?{2}/u.test('??'));//true

}

 

// 字符串扩展 新增特性 Unicode表示法 遍历接口 模板字符串 新增方法(10种)

// npm install babel-polyfill --save-dev 安装补丁库

{

console.log('a', '\u0061');//a a

console.log('s', "\u20BB7");// ₻7 大于#0xffff,分开显示

console.log('s', "\u{20BB7}");// ?

}

//

{

let s = '?';

console.log("length", s.length);//length 2

console.log("0", s.charAt(0));//0 �

console.log("1", s.charAt(1));//1 �

console.log("0", s.charCodeAt(0));//0 55362 es6新增,取码值,只取2字节

console.log("1", s.charCodeAt(1));//1 57271

 

let s1 = '?a';

console.log('length', s1.length);//length 3

console.log("0", s1.codePointAt(0));//0 134071

console.log("0", s1.codePointAt(0).toString(16));//0 20bb7

console.log("1", s1.codePointAt(1));//1 57271

console.log("1", s1.codePointAt(1).toString(16));//1 dfb7

console.log("2", s1.codePointAt(2));//97

}

{

console.log(String.fromCharCode("0x20bb7"));//es5 ஷ乱码

console.log(String.fromCodePoint("0x20bb7"));//es6 ?

}

{

let str = '\u{20bb7}abc';

for (let i = 0; i < str.length; i++) {

console.log('es5', str[i]);

}//es5 � 3 es5 � es5 a es5 b es5 c

for (let code of str) {

console.log('es6', code);

}//es6 ? es6 a es6 b es6 c

}

//判断起始字符串和截至字符串

{

let str = 'string';

console.log("include", str.includes("r"));//true 包含

console.log("start", str.startsWith("str"));//true 开始

console.log("start", str.endsWith("ng"));//true 截至

}

//重复

{

let str = 'string';

console.log(str.repeat(2));//stringstring

}

//es7草案

{

let name = "list";

let info = "hello world"

let m = `i am $(name),$(info)`;

console.log(m);

}

//补白,padStart(2---位数, '0'----补白替代字)

{

console.log('1'.padStart(2, '0'));//01 往前面补白

console.log('1'.padEnd(2, '0'));//10 往后面补白

}

//标签模板 1.过滤字符串,防止xss攻击;2.处理多语言转换的时候

{

let user = {

name: 'list',

info: 'hello world'

};

abc`i am $(user.name),$(user.info)`;

console.log(abc`i am $(user.name),$(user.info)`)

function abc(s, v1, v2) {

console.log(s, v1, v2);

return s + v1 + v2

}

}

{

console.log(String.raw`Hi\n$(1+2)`);//Hi\n$(1+2)

console.log(`Hi\n$(1+2)`);//Hi $(1+2)

}

 

//数值扩展 1.新增方法 2.方法调整

{

//不区分大小写

console.log(0b111110111);//503 二进制

console.log(0o767);//503 八进制

}

{//Number.isFinite 是否有尽

console.log('15', Number.isFinite(15));//15 true

console.log('NaN', Number.isFinite(NaN));//15 false 不是数

console.log('1/0', Number.isFinite(1 / 0));//1/0 false

// Number.isNaN 判断是不是数字

console.log('0', Number.isNaN(0));//false

// Number.isInteger判断是不是整数 接受的参数必须是数字

console.log('0.0', Number.isInteger(0.0));//true

console.log('0.1', Number.isInteger(0.1));//false

}

{

// 判断数字是否在-2的53次方,2的53次方

console.log(Number.MAX_SAFE_INTEGER, Number.MIN_SAFE_INTEGER);

console.log('10', Number.isSafeInteger(10));//true

console.log('a', Number.isSafeInteger(a));//false

}

{

// Math.trunc分离,取整

console.log('4.1', Math.trunc(4.1));//4

console.log('4.1', Math.trunc(4.9));//4

}

{

//Math.sign判断正数负数还是零,返回 1,0,-1

console.log('-5', Math.sign(-5));//-1

console.log('-5', Math.sign('-5'));//-1

console.log('a', Math.sign('a'));//NaN

}

{

// 计算立方根

console.log('-1', Math.cbrt(-1));//-1

console.log('8', Math.cbrt(8));//2

}

 

// 数组扩展 Array.from Array.of copyWithin find\findIndex fill entries\keys\values includes

{

let arr = Array.of(3, 4, 7, 9, 11);

console.log('arr=', arr);//arr= (5) [3, 4, 7, 9, 11]

let empty = Array.of();

console.log('empty=', empty);//empty= []

}

{// 数组扩展 Array.from 伪数组,集合转化为数组 ;映射

{/* <p></p>

<p></p> */}

let p = document.querySelectorAll('p');

let pArr = Array.from(p);

pArr.forEach(function (item) {

console.log(item.textContent);

})

 

console.log(Array.from([1, 3, 5], function (item) { return item * 2 }))//(3) [2, 6, 10]

}

{

//填充数组

console.log('fill-7', [1, 'a', undefined].fill(7));//fill-7 (3) [7, 7, 7]

// 第一个开始换到三个

console.log('fill,pos', ['a', 'b', 'c'].fill(7, 2, 3));//fill,pos (3) ["a",'b', 7]

console.log('fill,pos', ['a', 'b', 'c', 'd'].fill(7, 1, 3));//fill,pos (4) ["a", 7, 7, "d"]

}

{//entries\keys\values

for (let index of ['1', 'c', 'ks'].keys()) {//索引

console.log('keys', index);//keys 0 keys 1 keys 2

}

for (let value of ['1', 'c', 'ks'].values()) {//值

console.log('values', value);//values 1 values c values ks

}

for (let [index, value] of ['1', 'c', 'ks'].entries()) {//both

console.log('values', index, value);//values 0 1 values 1 c values 2 ks

}

}

{//从0开始 截止到4,即4之前(3,4】

console.log([1, 2, 3, 4, 5].copyWithin(0, 3, 4));//(5) [4, 2, 3, 4, 5]

}

{//只找到第一个

console.log([1, 2, 3, 4, 5].find(function (item) { return item > 3 }));//4

console.log([1, 2, 3, 4, 5].findIndex(function (item) { return item > 3 }));//3

}

{

console.log('number', [1, 2, NaN].includes(NaN));//number true

}

 

// 函数扩展 参数默认值 rest参数 扩展运算符 箭头函数 this绑定 尾调用

{//默认值后面不能有误默认值的变量参数

function test(x, y = 'world') {

console.log('默认值', x, y);

}

test('hello');//默认值 hello world

test('hello', 'kity');//默认值 hello kity

}

{

let x = 'test';

function test2(x, y = x) {

console.log('作用域', x, y);

}

test2('kity');//作用域 kity kity 这里

}

{//不确定参数都转化为数组 之后不能有别的参数

function test3(...arg) {

for (let v of arg) {

console.log('rest', v);

}

}

test3(1, 2, 3, 4, 'a');//rest 1 rest 2 rest 3 rest 4 rest a

}

{//将数组拆分成离散的值

console.log(...[1, 2, 4]);//1 2 4

console.log('a', ...[1, 2, 4]);//a 1 2 4

}

{//arrow函数名 v函数参数,无参用() v*2函数返回值

let arrow = v => v * 2;

console.log('arrow', arrow(3));//arrow 6

}

{//尾调用

function tail(x) {

console.log('tail', x);

}

function fx(x) {

return tail(x)

}

fx(123);//tail 123

}

 

// 对象扩展 函数新增特性 简洁表示、属性表达式、扩展运算符、Object新增方法

{

// 简洁表示法

let o = 1;

let k = 2;

let es5 = {

o: o,

k: k

}

let es6 = {

o, k

};

console.log(es5, es6);//{o: 1, k: 2} {o: 1, k: 2}

//对象里面有方法

let es5_method = {

hello: function () {

console.log('hello');

}

};

let es6_method = {

hello() {

console.log('hello');

}

};

console.log(es5_method.hello(), es6_method.hello());//hello hello

}

{//属性表达式

let a = 'b';

let es5_obj = {

a: 'c',

b: 'c'

}

let es6_obj = {

[a]: 'c'

}

console.log(es5_obj, es6_obj)//{a: "c", b: "c"} {b: "c"}

}

{//新增API Object.is相当于===

console.log('字符串', Object.is('abc', 'abc'));

console.log('数组', Object.is([], []));//false

//不会拷贝继承的属性,

console.log('拷贝', Object.assign({ a: 'a' }, { b: 'b' }));//拷贝 {a: "a", b: "b"}

let test = { k: 123, o: 456 };

for (let [key, value] of Object.entries(test)) {

console.log([key, value]);//["k", 123] ["o", 456]

}

}

{//扩展运算符

let { a, b, ...c } = { a: 'test', b: 'kill', c: 'ddd', d: 'ccc' };

console.log(c)//{c: "ddd", d: "ccc"}

}

 

// Symbol给该数据类型提供一个唯一的值

{

let a1 = Symbol();

let a2 = Symbol();

console.log(a1 === a2);//false

//a3是key值

let a3 = Symbol.for('a3');

let a4 = Symbol.for('a3');

console.log(a3 === a4);//true

}

{

let a1 = Symbol.for('abc');

let obj = {

[a1]: '123',

'abc': 345,

'c': 456

};

console.log('obj', obj);//obj {abc: 345, c: 456, Symbol(abc): "123"}

for (let [key, value] of Object.entries(obj)) {

console.log('let of', key, value);//let of abc 345 ,let of c 456

}

Object.getOwnPropertySymbols(obj).forEach(function (item) {

console.log(obj[item]);//123

})

Reflect.ownKeys(obj).forEach(function (item) {

console.log('ownkeys', item, obj[item]);//ownkeys abc 345,ownkeys c 456,ownkeys Symbol(abc) 123

})

}

 

// 数据结构 Set :WeakSet(当做数组,集合中的元素不能重复) ;Map: WeakMap(object,一个key一个value,object中key一定是字符串,map随意)

{

let list = new Set();

list.add(5);

list.add(7);

console.log('size', list.size);//size 2;size相当于length

}

{

let arr = [1, 2, 3, 4, 5];

let list = new Set(arr);

console.log('size', list.size);//size 5;

}

{//可以用来去重,但是不会做数据类型的转换

let list = new Set();

list.add(1);

list.add(2);

list.add(1);

console.log('list', list);//list Set(2) {1, 2}

let arr = [1, 2, 3, 1, 2, '2'];

let list2 = new Set(arr);

console.log('unique', list2);//unique Set(3) {1, 2, 3,'2}

}

{

let arr = ['add', 'delete', 'clear', 'has'];

let list = new Set(arr);

console.log('has', list.has('add'));//has true

console.log('delete', list.delete('add'), list);//delete true Set(3) {"delete", "clear", "has"}

console.log('clear', list.clear(), list);//clear undefined Set(0) {}

}

{

let arr = ['add', 'delete', 'clear', 'has'];

let list = new Set(arr);

for (let key of list.keys()) {

console.log('keys', key);//keys add;keys delete;keys clear;keys has

}

for (let value of list.values()) {

console.log('value', value);//value add;value delete;value clear;value has

}

for (let [key, value] of list.entries()) {

console.log('entries', key, value);//entries add add ;entries delete delete;entries clear clear;entries has has

}

 

list.forEach(function (item) { console.log(item); })//add delete clear has

}

{//WeakSet set支持的元素不同 ,WeakSet只能是对象,不能是数值、布尔值等;不会检测重复元素

let weakList = new WeakSet();//没有size属性

let arg = {}

weakList.add(arg);

console.log('', weakList);//WeakSet {{…}}

}

{//map添加元素用set(key,value) ;set添加元素用add

let map = new Map();

let arr = ['123'];

map.set(arr, 456);

console.log('map', map, map.get(arr));//map Map(1) {Array(1) => 456} 456

}

{//遍历同set

let map = new Map([['a', 123], ['b', 456]]);

console.log('map args', map);//map args Map(2) {"a" => 123, "b" => 456}

console.log('size', map.size);//size 2

console.log('delete', map.delete('a'), map);//delete true Map(1) {"b" => 456}

console.log('clear', map.clear(), map);//clear undefined Map(0) {}

}

{//必须是对象,没有size,不能clean

let weakmap = new WeakMap();

 

let o = {}

weakmap.set(o, 123);

console.log(weakmap.get(o));//123

}

 

// 数据结构 map与array的对比 set与array的对比

{//map与array的对比

let map = new Map();

let array = [];

//增

map.set('t', 1);

array.push({ t: 1 });

console.info('map-array', map, array);//map-array Map(1) {"t" => 1} [{…}]

// 查

let map_exist = map.has('t');

let array_exist = array.find(item => item.t);

console.info('exist', map_exist, array_exist);//exist true {t: 1}

// 改

map.set('t', 2);

array.forEach(item => item.t ? item.t = 2 : '');//遍历是否存在,再修改

console.info('map-array', map, array);//map-array Map(1) {"t" => 2} [{t:2}]

// 删

map.delete('t');

let index = array.findIndex(item => item.t);

array.splice(index, 1);//必须查到索引后删除

console.log('map-array', map, array);//map-array Map(0) {} []

}

{//set与array的对比

let set = new Set();

let array = [];

//增

set.add({ t: 1 });

array.push({ t: 1 });

console.log('set-array', set, array);//set-array Set(1) {{…}}size: 1__proto__: Set[[Entries]]: Array(1)0: Objectlength: 1 [{…}]

// 改

set.forEach(item => item.t ? item.t = 2 : '');

array.forEach(item => item.t ? item.t = 2 : '');

console.log('set-array', set, array);//set-array Set(1) {{…}}size: 1__proto__: Set[[Entries]]: Array(1)0: Objectlength: 1 [{…}]

// 查

let set_exist = set.has({ t: 1 });

let array_exist = array.find(item => item.t);

console.log('set-array', set_exist, array_exist);//set-array false {t: 2}

// 删

set.forEach(item => item.t ? set.delete(item) : '');

let index = array.findIndex(item => item.t);

array.splice(index, 1);//必须查到索引后删除

console.log('set-array', set, array);//set-array Set(0) {} []

}

 

//数据结构 map与object set 与object

{

let item = { t: 1 };

let map = new Map();

let set = new Set();

let obj = {};

//add

map.set('t', 1);

set.add(item);

obj['t'] = 1;

console.info('map-set-ob', obj, map, set);//map-set-ob {t: 1} Map(1) {"t" => 1} Set(1) {{…}}

//check

console.log({

map_exist: map.has('t'),

set_exist: set.has(item),

obj_exist: 't' in obj

})//{map_exist: true, set_exist: true, obj_exist: true}

//change

map.set('t', 2);

item.t = 2;

obj['t'] = 2;

console.info('map-set-ob', obj, map, set);//map-set-ob {t: 2} Map(1) {"t" => 2} Set(1) {{…}}

//delete

map.delete('t');//成本最低

set.delete('t');

delete obj['t'];

console.info('map-set-ob', obj, map, set);//map-set-ob {} Map(0) {} Set(1) {{…}}

}//总结,优先使用map,如果对数据要求严格(唯一性)使用set放弃object和传统的数组

 

// Proxy 代理(连接用户和对象) 和 Reflect(反射),两者方法相同

{

let obj = {//供应商,原始对象

time: '2017-03-11',

name: 'net',

_r: 123

};

// 代理商

let monitor = new Proxy(obj, {

// 方法 target指的是obj对象;key修改哪个属性;value指的是值设置为什么

// 拦截(代理)对象属性的读取

get(target, key) {

return target[key].replace('2017', '2018')

},

//拦截对象设置属性

set(target, key, value) {

if (key === 'name') {

return target[key] = value;

} else {

return target[key];

}

},

//拦截key in object操作

has(target, key) {//只暴露name属性

if (key === 'name') {

return target[key]

} else {

return false;

}

},

// 拦截delete

deleteProperty(target, key) {

if (key.indexOf('_') > -1) {

delete target[key];

return true;

} else {

return target[key]

}

},

// 拦截 Object.keys;Object.getOwnPropertySymbols;Object.getOwnPropertyNames

ownKeys(target) {

return Object.keys(target).filter(item => item != 'time')

}

});

// 用户操作

console.log('get', monitor.time);//get 2018-03-11

monitor.time = '2019';

monitor.name = 'hello'

console.log('set', monitor.time, monitor);//set 2018-03-11 Proxy {time: "2017-03-11", name: "hello", _r: 123}

console.log('has', 'name' in monitor, 'time' in monitor);//has true false

delete monitor.time;

console.log('deleter', monitor);//deleter Proxy {time: "2017-03-11", name: "hello", _r: 123}

delete monitor._r;

console.log('deleter', monitor);//deleter Proxy {time: "2017-03-11", name: "hello"}

console.log('ownKeys', Object.keys(monitor));//ownKeys (2) ["name", "_r"]

}

{

let obj = {//供应商,原始对象

time: '2017-03-11',

name: 'net',

_r: 123

};

console.log('Reflect get', Reflect.get(obj, 'time'));//Reflect get 2017-03-11

Reflect.set(obj, 'name', 'hello');

console.log(obj);//{time: "2017-03-11", name: "hello", _r: 123}

console.log('has', Reflect.has(obj, 'name'));//has true

}

{//解耦

function validator(target, validator) {

return new Proxy(target, {

_validation: validator,

set(target, key, value, proxy) {

if (target.hasOwnProperty(key)) {

let va = this._validation[key];

if (!!va(value)) {

return Reflect.set(target, key, value, proxy)

} else {

throw Error('不能设置$(key)到$(value)')

}

} else {

throw Error('$(key)不存在')

}

}

})

}

const personValidators = {

name(val) {

return typeof val === 'string'

},

age(val) {

return typeof val === 'number' && val > 18

}

}

class Person {

constructor(name, age) {

this.name = name;

this.age = age;

return validator(this, personValidators)

}

}

const person = new Person('lilei', 30);

console.info(person);//Proxy {name: "lilei", age: 30}

// person.name = 48;//Uncaught Error: 不能设置$(key)到$(value)

}

 

//类与对象 类:基本语法;类的继承;静态方法;静态属性;getter;setter;

{

// 基本定义和生成实例 class关键字定义类,constructor定义属性

class Parent {

constructor(name = 'laowang') {

this.name = name;

}

}

let v_parent = new Parent('v');//实例

console.log('构造函数和实例', v_parent);//构造函数和实例 Parent {name: "v"}

}

{

// 继承

class Parent {

constructor(name = 'laoli') {

this.name = name;

}

}

class Child extends Parent {

 

}

console.log('继承', new Child());//继承 Child {name: "laoli"}

}

{

// 继承传递参数

class Parent {

constructor(name = 'laoli') {

this.name = name;

}

}

class Child extends Parent {

constructor(name = 'child') {

super(name);//super一定放在构造函数的第一行

this.type = 'child';

}

}

console.log('继承', new Child('hello'));//继承 Child {name: "hello", type: "child"}

}

{//getter,setter

class Parent {

constructor(name = 'laoli') {

this.name = name;

}

get longName() {//并不是方法,是属性

return 'mk' + this.name

}

set longName(value) {

this.name = value;

}

}

let v = new Parent();

console.log('getter', v.longName);//getter mklaoli

v.longName = 'hello';

console.log('setter', v.longName);//setter mkhello

}

{//静态方法

class Parent {

constructor(name = 'laoli') {

this.name = name;

}

static tell() {//静态方法通过类去调用,而不是类的实例去调用

console.log('tell');

}

}

Parent.tell();//tell

}

{//静态属性

class Parent {

constructor(name = 'laoli') {

this.name = name;

}

static tell() {//静态方法通过类去调用,而不是类的实例去调用

console.log('tell');

}

}

//静态属性定义没有关键词

Parent.type = 'test';

console.log('静态属性', Parent.type);//静态属性 test

}

 

// Promise 异步:a执行完后b执行:1.回调;2.事件触发(Promise区别于这两种更适用于异步操作)

{//回调方式,基本定义,难以维护

let ajax = function (callback) {

console.log('执行');

setTimeout(function () {

callback && callback.call()

}, 1000);

};

ajax(function () {

console.log('timeout1');

})

}

{//resolve执行操作; reject中断操作

let ajax = function () {

console.log("执行2");

return new Promise(function (resolve, reject) {

setTimeout(function () {

resolve()

}, 1000);

})

}

ajax().then(function () {

console.log('promise', 'timeout2');

})

}

{

let ajax = function () {

console.log("执行2");//第一步

return new Promise(function (resolve, reject) {

setTimeout(function () {

resolve()

}, 1000);

})

}

ajax().then(function () {

console.log("执行3");//第二步

return new Promise(function (resolve, reject) {

setTimeout(function () {

resolve()

}, 2000);

}).then(function () {

console.log('timeout3')//第三步

})

})

}

{//异常报错

let ajax = function (num) {

console.log('执行4');

return new Promise(function (resolve, reject) {

if (num > 5) {

resolve()

} else {

throw new Error('出错了')

}

})

}

ajax(5).then(function () {

console.log('log', 6);

}).catch(function (err) {

console.log('catch', err);

})

}

// 这里是一个实战啊

{//所有图片加载完之后再添加到页面

function loadImg(src) {

return new Promise((resolve, reject) => {

let img = document.createElement('img');

img.src = src;

img.onload = function () {

resolve(img);

},

img.onerror = function (err) {

reject(err);

}

})

}

function showImg(imgs) {

imgs.forEach(function (img) {

document.body.appendChild(img);

})

}

//all将多个Promise实例当做一个实例

Promise.all([

loadImg('http://i4.buimg.com/567571/df1ef0720bea6803.png'),

loadImg('http://i4.buimg.com/567751/2b07ee25b08930ba.png'),

loadImg('http://i4.buimg.com/567571/df1ef0720bea6803.png')

]).then(showImg)

}

{//有一个图片加载完就显示到页面

function loadImg(src) {

return new Promise((resolve, reject) => {

let img = document.createElement('img');

img.src = src;

img.onload = function () {

resolve(img);

},

img.onerror = function (err) {

reject(err);

}

})

}

function showImg(img) {

let p = document.createElement('p');

p.appendChild(img);

document.body.appendChild(p)

}

// race只要有一个改变,其他都不在响应

Promise.race([

loadImg('http://i4.buimg.com/567571/df1ef0720bea6803.png'),

loadImg('http://i4.buimg.com/567751/2b07ee25b08930ba.png'),

loadImg('http://i4.buimg.com/567571/df1ef0720bea6803.png')

]).then(showImg)

}

 

// Iterator 和 for...of循环

{//Iterator

let arr = ['hello', 'world'];

let map = arr[Symbol.iterator]();

console.log(map.next());//{value: "hello", done: false}

console.log(map.next());//{value: "world", done: false}

console.log(map.next());//{value: undefined, done: true}

}

{//对象

let obj = {

start: [1, 3, 2],

end: [1, 8, 9],

[Symbol.iterator]() {//声明接口方法

let self = this;

let index = 0;

let arr = self.start.concat(self.end);

let len = arr.length;

return {

next() {

if (index < len) {

return {

value: arr[index++],

done: false

}

} else {

return {

value: arr[index++],

done: true

}

}

}

}

}

}

for (let key of obj) {

console.log(key);//132189

}

}

{

let arr = ['hello', 'world'];

for (let value of arr) {

console.log('value', value);//value hello ;value world

}

}

 

//Generator异步编程解决方案

// 遍历器生成函数,可以直接赋值给iterator接口。

{//基本定义 是一个函数,返回的是iterator接口,执行一次next,调用一次yield

let tell = function* () {

yield 'a';

yield 'b';

return 'c';

};

let k = tell();

console.log(k.next());//{value: "a", done: false}

console.log(k.next());//{value: "b", done: false}

console.log(k.next());//{value: "c", done: true}

console.log(k.next());//{value: undefined, done: true}

}

// 使用Generator做遍历器

{

let obj = {};

obj[Symbol.iterator] = function* () {

yield 1;

yield 2;

yield 3

}

for (let value of obj) {//遍历

console.log(value);// 1 2 3

}

}

{//状态机(Generator最大的优势) 这里:三种状态循环

let state = function* () {

while (1) {

yield 'A';

yield 'B';

yield 'C';

}

}

let status = state();

console.log(status.next());//A

console.log(status.next());//B

console.log(status.next());//C

console.log(status.next());//A

}

{

let state = async function () {

while (1) {

await 'A';

await 'B';

await 'C';

}

}

let status = state();

console.log(status.next());//A

console.log(status.next());//B

console.log(status.next());//C

console.log(status.next());//A

}

{//实例:抽奖次数限制

let draw = function (count) {

//具体抽奖逻辑

console.info('剩余${count}次')

}

let residue = function* (count) {

while (count > 0) {

count--;

yield draw(count);

}

}

let star = residue(5);

let btn = document.createElement('button');

btn.id = 'start';

btn.textContent = '抽奖';

document.body.appendChild(btn);

document.getElementById('start').addEventListener('click', function () {

star.next();

}, false)

}

{

//长轮询,Generator结合Promise

let ajax = function* () {

yield new Promise(function (resolve, reject) {

setTimeout(function () {

resolve({ code: 0 })

}, 200);

})

}

//轮询过程

// 补充,服务端http是一个无状态的过程,获取服务端的状态变化websocket(浏览器兼容性不好)和长轮询

let pull = function () {

let generator = ajax();

let step = generator.next();

step.value.then(function (d) {

if (d.code != 0) {

setTimeout(function () {

console.log('wait');

pull()

}, 1000);

} else {

console.log(d);

}

})

}

pull();

}

 

// Decorator修饰器是一个函数,用来修改类的行为(扩展类的功能)

//npm babel-plugin-transform-decorators-legacy --save-dev

{//参数 1.类本身 2.名称 3.该属性的描述对象

let readonly = function (target, name, descriptor) {

descriptor.writable = false;

return descriptor

};

class Test {

@readonly

time() {

return '2017-03-11'

}

}

let test = new Test();

test.time = function () {

console.log('reset time');//这里会报错,不允许修改

}

console.log(test.time());

}

{

let typename = function (target, name, descriptor) {

target.myname = 'hello';//类的静态属性

}

@typename

class Test {

 

}

console.log('类修饰符', Test.myname);

//第三方库修饰器的js库,core-decorators

}

{//案例:日志系统

let log = (type) => {

return function (target, name, descriptor) {

let src_method = descriptor.value;

descriptor.value = (...arg) => {

src_method.apply(target, arg);

console.info(`log $(type)`);//模拟买点,new image.src="接口"

}

}

}

class AD {

@log('show')

show() {

console.info('ad is show')

}

@click('click')

click() {

console.info('ad is click');

}

}

let ad = new AD();

ad.show();

ad.click();

}

 

// 模块化 import引入 export导出

{//方式一

export let A = 123;

export function test() {

console.log('test');

}

export class Hello {

test() {

console.log('class')

}

}

 

import { A, test, hello } from './'

import * as lesson from './'//导入所有

console.log(lesson.A, lesson.test)

}

{//方式二

{

let A = 123;

function test() {

console.log('test');

}

class Hello {

test() {

console.log('class')

}

}

export default {

A,

test,

Hello

}

import lesson17 from './' //无需命名与前面相同

}

}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值