ES6总结

扩展 运算符

用处代码解释
数组

[...[],1];  // [1]

arr=[1,2,3],arr1=[4,5,6]

[...arr] //复制数组

[...arr,...arr2] //合并数组

...后跟一个空数组,无任何效果
函数

const args = [0, 1];

const f = v => console.log(v);
f(...args);

函数调用时...才能用在扩展()中
字符串(有Interator)

//转化为数组

[...'hello']  //['h','e','l','l','o']

//正确返回Unicode字符串长度

[...'x\uD83D\uDE80y'].length

将字符串转化为数组

凡涉及四个字节的字符串操作,都要用...改写

有Interator的对象

//Nodelist转化为数组

 let nodeList = document.querySelectorAll('div');
let array = [...nodeList];

//Map/Set转化为数组

const map = new Map([1,2],[3,4]);

let arr = [...map.keys()];

//Generator函数转化为数组

const go = function*(){

yield 1;}

[...go()]   // [1]

将有Inerator接口的对象转化为真正的数组

 

字符串的扩展

字:? 

码点Unicode(16进制的):20BB7 ,js看作两个字节

length:2(大于FFFF)

十进制:134071

utf-16:0xD842 0xDF87 

十进制:55362 57271

内容代码

解释

String.fromCodePoint()

Unicode转为字符串并返回

String.fromCodePoint(0x20BB7)
// "?"
String.fromCodePoint(0x78, 0x1f680, 0x79) === 'x\uD83D\uDE80y'
// true

可以返回大于0xFFFF的字符(即优化String.fromCharCode()),接受三个参数,会被合并成一个字符串返回

String.raw()

斜杠前加斜杠

String.raw`Hi\\n`  // 返回 "Hi\\\\n"

String.raw({raw:'abc'},1,2,3) //a1b2c3 

将有斜杠的字符加转义斜杠:String.raw``;

处理字符串:String.raw({raw:' '}),第一个参数必须是带raw属性的方法

 

 

codePointAt()

返回Unicode的十进制值

let s = '?';

s.codePointAt(0)  //134071:Unicode的十进制值

s.codePointAt(0).toString(16) //20BB7:Unicode

'\u20BB7'  //?

let s = '?a'

s.codePointAt(0) //134071:?的Unicode十进制

s.codePointAt(1) //57271:?中后两字节的Unicode十进制 

s.codePointAt(2) //97:a的Unicode十进制

let s = '?a'

for(let ch of s){

console.log(ch.codePointAt(0))  

}

判断字符的字节数

let function(x => {

if(x.codePointAt(0)>0xFFFF){

console.log('四字节')}else{console.log('二字节')}

})

charAt():无法读取4字节字符

charCodeAt():四字节时,分别返回前后两个字节的Unicode的十进制

codePointAt():正确返回四字节字符的Unicode的十进制

normalize()

字符统一

\u01D1===\u004f\u030c //false

\u01D1.normalize()===\u004f\u030.normalize() //true

将字符的不同表示方法同一为同一形式

ǒ可以表示为

\u01D1(ǒ)

\u004f\u030c(o+ˇ)

includes()

判断是否包含字符

includes(value,n)

let s = 'Hello world!';

s.includes('world', 6) // true

n:从该位置开始

startsWith()

判断字符是否在头部

startsWith(value,n)

let s = 'Hello world!';

s.startsWith('world', 6) // true

n:从该位置开始

endsWith()

判断字符是否在尾部

endsWith(value,n)

let s = 'Hello world!';

s.endsWith('world', 6) // true

n:在该位置前结束

repeat()

重复

'a'.repeat(3); //aaa

将字符串重复输出并返回新的字符串

padStart()

头部补全

'x'padStart(4) 

'x'.padStart(4,ab)  //abax

第二个参数不填,默认用空格补全

用ab在被补全字符x的前面补全,直到长度为4

padEnd()

尾部补全

'x'.padStart(4,ab) //xaba用ab在被补全字符x的后面补全,直到长度为4

trimStart()

消除头部空格

const s = '  abc  ';

s.trim() // "abc"
s.trimStart() // "abc  "
s.trimEnd()

trim()用作消除空格

trimEnd()

消除尾部空格

正则的扩展

 

数值的扩展

内容代码解释

0b(0B),0o(0O)

二进制数,八进制数

Number(0b111); //7

Number(0o10); //8

Number将数值转化为十进制数

 

Number.EPSILON

极小常量

Number.EPSILON===0.00...01(小数点后51个零)===Math.pow(-2,-52) 

//应用

function re = (x,y) => {

return Math.abs(x-y)<Number.EPSILON*Math.pow(2,2) //误差小于-2的-50次方

}

re(0.2,0.3) //ture

浮点数计算不精确,如0.2+0.1====0.3 //false

0.2+0.1=0.30000000000000004()

引入极小常量可以设置误差范围

Number.EPSILON等于-2的-52次方

 

 

 Number.MIN_SAFE_INTEGER

最小安全整数

Number.MIN_SAFE_INTEGER===Math.pow(-2,53) +1

 

Number.MIN_SAFE_INTEGER为-2的53次方加1

Number.MAX_SAFE_INTEGER

最大安全整数

Number.MIX_SAFE_INTEGER===Math.pow(2,53) -1Number.MIN_SAFE_INTEGER为2的53次方减1

Number.isFinite() 

判断是否有限

Number.isFinite(15); //true

Number.isFinite('15'); //false

Number.isFinite(ture); //false

非数值false

Number.isNaN()

判断数值是否是NaN

Number.isNaN(NaN); //true

Number.isNaN(NaN/9) //true

Number.isNaN('true'/0) //true

Number.isNaN('true'/'true') //true

Number.isNaN('NaN'); //false

Number.isNaN('15'/0) //false

只有NaN返回true

Number.isInteger()

判断是否为整数

Number.isInteger(15) //true

Number.isInteger(15.0) //true

Number.isInteger(15.0000000000000002) //ture

Number.isInteger(5E-325) //true

Number.isInteger(5E-324) //false

Number.isInteger() //false

非数值全返回false

javascript能分辨的最小值(Number.MIN_VALUE)是5E-324

当数值小于5E-324,归零

Number.isSafeInteger()

判断是否是安全数

Number.isSafeInterger(12) //true

Number.isSafeInterger(Number.MIN_SAFE_INTEGER) //true

整数在-2^53~2^53为安全数

非数值全返回false

Number.parseInt()

转换为整数

Number.parseInt('12.34') // 12

相当于parseInt('12.34') //2

Number.parseFloat()

转换为浮点数

Number.parseFloat('123.45#') // 123.45相当于parseFloat('123.45#') //123.45

 

Math对象的扩展

内容代码解释代码模拟

**

指数运算(^)

2**2     // 4

2**2**3   // 2**(2**3)

a**=2   //a=a**2

2**2==2^2

和Math.pow差不多但有细微差别,在大数值运算中,结果不同

Math.trunc()

去除小数部分

Math.trunc(4.1); //4

Math.trunc('4.1'); //4

Math.trunc(true); //1

Math.trunc(false); //0

Math.trunc(null); //0

Math.trunc(); //NaN

Math.trunc('foo'); //NaN

Math.trunc(NaN); //NaN

Math.trunc(undefined); //NaN

非数值,可以转化为数值的,如true,false,null,‘123’,先转化为数值

非数值,不能转化为数值的,如NaN,undefine,‘foo’返回NaN

Math.trunc = Math.trunc || function(x) {
  return x < 0 ? Math.ceil(x) : Math.floor(x);
};

Math.sign()

判断数值类型

Math.sign(5) //1

Math.sign(0) //0

Math.sign('5') //1

Math.sign('foo') //NaN

返回值

正数:1

负数:-1

+0:0

-0:-0

其他:NaN

非数值,可以转化为数值的,如true,false,null,‘123’,先转化为数值

非数值,不能转化为数值的,如NaN,undefine,‘foo’返回NaN

Math.sign = Math.sign || function(x) {
  x = +x; // convert to a number
  if (x === 0 || isNaN(x)) {
    return x;
  }
  return x > 0 ? 1 : -1;
}; 

Math.cbrt()

计算立方根

Math.cbrt(8)  //2

Math.cbrt('8')  //2

Math.cbrt(‘foo’)  //NaN

非数值,可以转化为数值的,如true,false,null,‘123’,先转化为数值

非数值,不能转化为数值的,如NaN,undefine,‘foo’返回NaN

 Math.cbrt = Math.cbrt || function(x) {
  var y = Math.pow(Math.abs(x), 1/3);
  return x < 0 ? -y : y;
};

Math.clz32()

转为32位无符号整数,返回前导0

Math.clz32(1)  //31

Math.clz32(true)  //31

Math.clz32([])  //32

000..01:1前面有31个零

非数值,可以转化为数值的,如true,false,null,‘123’,先转化为数值

非数值,不能转化为数值的,如NaN,空,undefine,‘foo’返回32

 

Math.imul()

转为32位带符号整数,返回相乘结果

Math.imul(-1, 8)  // -8

Math.imul(0x7fffffff, 0x7fffffff) // 1

超出-2^53~2^53的也可以正确结算

Math.fround()

返回32位单精度浮点数形式

 

 

 

Math.hypot()

返回平方和相加的平方根

Math.hypot(3,4) //5

Math.hypot(3,4,5) 

Math.hypot(3,4,NaN) //NaN 

3^3+4^4再开平方,结果为5

3^3+4^4+5^5再开平方

非数值,可以转化为数值的,如true,false,null,‘123’,先转化为数值

非数值,不能转化为数值的,如NaN,空,undefine,‘foo’返回NaN

Math.fround = Math.fround || function (x) {
  return new Float32Array([x])[0];
};

Math.expm1(x)

e^x-1

Math.expm1(-1) //e^(-1)-1Math.expm1(x)返回e^x-1,相当于Math.exp(x)-1

 Math.expm1 = Math.expm1 || function(x) {
  return Math.exp(x) - 1;
};

Math.log1p(x)

1+x的自然对数

Math.log1p(1)  

n<-1返回NaN

n=-1返回-Infinity

Math.log1p(x)返回1+x的自然对数,相当于Math.log(1+x)

 

Math.log1p = Math.log1p || function(x) {
  return Math.log(1 + x);
}; 

Math.log10(x)

以10为底的x的对数

Math.log10(1)  //0

log10(1)==0

x小于0返回NaN

Math.log10 = Math.log10 || function(x) {
  return Math.log(x) / Math.LN10;
}; 

Math.log2()

以2为底的x的对数

Math.log2(2)  //1

log2(2)==1

x小于0返回NaN

 Math.log2 = Math.log2 || function(x) {
  return Math.log(x) / Math.LN2;
};

数组的扩展

内容代码解释空位

...

扩展运算符

let arr1 = [0, 1];
let arr2 = [2, ,3];

[...arr2]  //[2,undefined ,3]
arr1.push(...arr2);

push参数不能为数组但和...结合使用可以实现在尾部添加空位转为undefine

Array.from()

转化为数组

//转化为数组(有Interator)

const map = new Map([[1,2],[3,4]]);

const arr = Array.from(map);

兼容写法

const toArraya = ((obj) => {Array.from?Array:obj => [].slice.call(obj)})()

所有类似数组的对象(有length属性)都能用此方法转化为数组,

转化为数组的方法还有

[...]  //有Interator接口

Array.prototype.slice //无部署Array的浏览器

空位转为undefine

//处理元素

 Array.from([1, 2, 3], (x) => x * x);

 Array.from(map, (x) => x * x);

相当于Map遍历,先将前一个参数转化为数组,再将元素进行处理

Array()

一组值转化为数组

Array() // []
Array(3) // [, , ,]
Array(3, 11) // [3, 11] 

参数不同表现不同:

无参数:空数组

一个参数:空数组,长度为该参数

两个以上参数:参数全为数组元素

 

Array.of()

一组值转化为数组

Array.of() // []
Array.of(undefined) // [undefined]
Array.of(1) // [1]
Array.of(1, 2) // [1, 2] 

弥补Array()的不足,参数不同表现相同

Array.of总是返回参数值组成的数组,参数为空总是

 

copyWithin()

复制成员

格式:

Array.prototype.copyWithin(target, start = 0, end = this.length) 

无部署copyWithin写法

[].copyWithin.call(new IntArray(arr,target,start,end));

target:从该位置开始替换元素,负数表示倒数(必须)

star:从该位置开始读取数据(可选)

end:从该位置前停止读取数据(可选)

连空位一起拷贝

例子:

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

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

[].copyWithin.call(new IntArray([1,2,3,4,5],0,3,4));

//IntArray  [4,2,3,4,5]

find()

查找

一参数:

[1,2,3].find((n) => n>1); //2

[0,5,10,15].find((value,index,arr) =>  {return value>5}) //10

两参数:

function f = (n) =>{

n>this.age}

let v = {age:2,name:anny}

[1,2,3,4]find(f,v)

找到第一个符合的元素,返回元素

value:当前值

index:当前位置

arr:原数组

 

f中的this指向find的v

 

findIndex()

查找

[1,NaN,3].findIndex(n =>Object.is(NaN,n)); // 1

查找第一个符合的元素的索引,返回元素的索引

indexOf不能查找数组中的NaN成员,findIndex可以

 

includes()

查找

格式

include(value,start)

兼容性写法

const ins = (() => Array.prototype.includes?(arr,value) =>arr.includes(value):(arr,value) =>arr.some(el => el===value))()

ins([1,2],2) //true

例子

 [1, 2, NaN].includes(NaN)  //true

value:给定值

start:从该位置开始查找,可选,如果不填则从头开始查找

判断是否包含给定值,包含则返回true

 

fill()

填充

格式:

.fill(value,start,end)

例子:

//一个参数:全覆盖

new Array(3).fill(7)    // [7,7,7]

[1,2,3].fill(7)     // [7,7,7]

//三个参数

['a', 'b', 'c'].fill(7, 1, 2);   // ['a',7,'c']

//一个参数,为对象

let arr = new Array(2).fill({name:tom});   //{name:tom,name:tom}

arr[0].name=jack;       //{ name:jack,name:jack} 

value:替换的值

start:从该位置开始替换

end:在该位置前停止替换

 

fill填充的value为对象(包括数组)时,被赋值的是同一个内存地址对象,当改变任意一个元素是,所有元素都会被改变

将空位看作正常位置

遍历

keys()

values()

entries()

 

for(k of [a,b].keys());

let arr = [a,b];

for(k of arr.keys());

[...[,a].keys()] //[0,1]

values:遍历值

keys:遍历键

entries:遍历键值

for...of会遍历空位

values,keys,entries都会将空位处理成undefine

for(v of [a,b].values());

[...[,a].values()]  //[undefine,a]

for([k,v] of [a,b].entries());

[...[,a].entries()] //[[0,undefine],[1,a]]

flat()

多维数组拉平

.flat(times)

[1,2,[3,[4]],5].flat();   // [1,2,3,[4],5]

[1,2,[3,[4]],5].flat(2);   // [1,2,3,4,5]

[1,2,[3,[4]],5].flat(Infinity);   // [1,2,3,4,5]

[1, ,2,[3,[4]],5].flat(2);   // [1,2,3,4,5]

用于将嵌套的数组拉平,返回新数组,不影响原数组

times:拉平的次数,默认为1,当参数为Infinity时,不管多少层都拉成一维数组

如果数组有空元素,会跳过空元素

 

flatMap()

操作+拉平

.flatMap(() =>  {})

[1,2,3].flatMap(x =>  [x,x*x])  //[1,1,2,4,3,9]

[1,2,3].flatMap(x =>[[x]]) //[[1],[2],[3]]

对数组成员执行函数后做falt拉平一次,返回新数组,不影响原数组

 

解构赋值

从对象和数组中提取值,并赋值给变量

数组

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

let [a, ,c]=[1,2,3]; //c为3

let [a,...b]=[1,2,3]; //b为[2,3]

let [a,b,c]=[1,[2,3],4] //b为2,c为4

let [a,b,c]=new Set([1,2,3]) 

...只能放数组最后一位
对象  
字符串  
数值和布尔值  
函数参数  
   
   
   
   
   

对象

1.对象和属性的写法

 ES5ES6
属性const obj = {val:'123'}简洁表达法

function(x,y){

{x,y}

}

function(x,y){

{x:x,y:y}

}

const val = '123';

const obj = {val}

var obj = {

abc:123

foo:true

}

属性名为表达式

obj.['a'+'bc']=123;

let obj = {

['a'+'bc']=123

}

属性名为标识符

obj.foo=true;

let pkey=foo;

let obj = {

[pkey]:true

}

方法

const obj = {

method:function(){ //

}

}

方法简写

const obj = {

method(){ // } 

}

 

方法名为Symbol

const obj = {

[mySymbol](){ // }

}

方法名为表达式

const obj ={

['method'+'1'](){ // }  

}

方法为Generator函数

const obj = {

* method(){ // } 

}

2.对象方法的name属性,返回函数的名称

对象方法的类型方法举例name使用解释
普通方法

 const obj= {
  foo() { // },
};

obj.foo.name // 'foo'对象.方法.name
取值/存值函数

 const obj = {
  get foo() {},
  set foo(x) {}

};

const a=Object.getOwnPropertyDiscription(obj,foo);

a.set.name(); // 'set foo'

a.get.name(); // 'get foo'

name属性在描述对象的get和set方法上
构造函数(new Function()).name//anonymous构造函数name属性返回anonymous
bind()创建的函数var foo=function(){ // }foo.bind().namename属性在bind方法上

 

3.属性 的可枚举

属性>枚举性>操作

const obj={a:1}; //属性
Object.getOwnPropertyDescriptior(); //描述

//常见不可枚举属性
toString
length
Symbol

//四种操作忽略不可枚举属性
for...in //遍历
Object.keys() //获取键
Object.assign() //拷贝
JSON.stringify() //转化为字符串

 4.属性遍历

遍历方法遍历范围图示
for...in

遍历包含

自身可枚举+继承可枚举

Reflect.ownkeys

返回数组

自身可枚举+自身不可枚举+Symbol

属性的键

Object.getOwnPropertyName()

返回数组

自身可枚举+自身不可枚举(不包含Symbol)

Object.getOwnPropertySymbol()

返回数组

所有Symbol类型属性

Object.keys()

返回数组

自身可枚举属性

5.方法中使用super

用于继承原形链上属性,注意:只能在对象的方法中使用,不能用于属性的赋值

const father = {foo:123};
const child = {
a(){return super.foo}
};
Object.setPrototypeOf(child,father);
child.a();

6.新增方法

包括比较两对象Object.is(),拷贝对象,合并对象,普通数据类型转换成对象(Object.assign()),有Interator接口的数据转化为对象(Object.formEntries()),原形链上属性读取和设置

方法举例解释

比较

Object.is()

Object.is({},{}) //false

Object.is(+0,-0) //false

Object.is(NaN,NaN) //true

== 会自动转换类型

=== 中NaN不等于自身,+0不等于-0

合并,浅拷贝,转换成

Object.assign()

//对象

const obj1={x:1,a:{b:1}}

const obj2={x:2,z:3}

obj1.a.b=2

obj3=Object.assign({},obj1) //克隆对象

Object.assign(obj1); //浅拷贝,obj1.a.b为2

Object.assign(target,obj1,obj2); //合并

//为对象添加属性

class Point{

constructor(x,y){

Object.assign(this,{x,y})

}}

//为对象添加方法

Object.assign(SomeClass.prototype,{

foo(){ // }

})

用于对象的合并,对象拷贝,为对象添加属性和方法

 

 

注意:浅拷贝:如果源对象的属性值是对象,拷贝得到的是对象的引用

 

 

对象合并时,重复属性会被后面的覆盖,

 

 

为Point类的实例添加属性

 

 

在SomeClass的原形链上添加方法

//基本数据类型转换成对象

Object.assign(‘123’);  

Object.assign({},null);   //object

Object.assign({},undefine); //object

转换成对象,null和undefine不能直接转,要用这种方式

//数组合并

Object.assign([1,2,3],[5]); //[5,2,3]

用做数组合并,会将数组也当成对象,相同下标会被覆盖

//取值函数

const obj1={get foo(){return 1}};

Object.assign({},obj1) //{foo:1}

 取值函数拷贝时,不会直接拷贝函数,只会拿到值后拷贝

键转化为数组

Object.keys()

格式

Object.keys(obj)

配合for...of使用

for(k of Object.keys(obj)){ // }

返回数组,包含参数对象自身可遍历的属性的键名

值转化为数组

Object.values()

格式

Object.values(obj)

配合for...of使用

for(k of Object.values(obj)){ // }

返回数组,包含参数对象自身可遍历的属性的键值

键值对转化为数组和Map

Object.entries()

格式

const obj = {x:1,y:2}

Object.entries(obj)

配合for...of遍历(对象转化为数组)

for(let [k,v] of Object.entries(obj)){ // } //遍历键值对

将对象转化为Map结构

const map=new Map(Object.entries(obj))

返回数组,包含参数对象自身可遍历的属性的键值对

可用于将对象转化为数组

转化为对象

Object.formEntries()

数组>对象

Object.formEntries([

[x,1],[y,2]

])

Map>对象

const map =new Map().set('x',true)

Object.formEntries(map) 

查询字符串>对象

Object.fromEntries(new URLSearchParams('foo=bar&baz=qux')) 

将键值对数组转化为对象

 

 

 

将Map结构转化为对象

 

 

 

将查询字符转化为对象

 

对象属性的描述对象

Object.getOwnPropertyDescriptior()

const source = {
  set foo(value) {
    console.log(value);
  }
};

const target2 = {};
Object.defineProperties(target2, Object.getOwnPropertyDescriptors(source));
Object.getOwnPropertyDescriptor(target2, 'foo')

 

返回自身属性的描述对象

可以配合defineProperties实现正确的存值和取值函数的拷贝

创建

Object.create()

 创建对象

写操作

Object.setOwnPrototypeOf()

格式 

Object.setOwnPrototypeOf(object,prototype)

例子

Object.setOwnPrototypeOf(obj,proto); //将proto设置为obj的原形,obj可读取proto的属性

设置当前对象的prototype对象,返回参数对象本身

读操作

Object.getOwnPrototypeOf()

格式

Object.getOwnPrototypeOf(obj)

读取一个对象的原形对象

 

Symbol

 

Symbol代码解释

创建

Symbol()

let s = Symbol();

let s1 = Symbol('foo'); //创建+添加描述

let s2 = Symbol.for('foo'); //创建+添加描述+登记

(可以在不同Iframe或service worker中取到同一个值)

调用Symbol函数,注意:不用new

若参数是对象,则先调用对象中toString方法将对象转化为字符串

Symbol('foo')===Symbol('foo')  //false

Symbol.for('foo') ===Symbol.for('foo') //true

返回描述

discription

s1.discription;返回Symbol的描述

返回key

keyFor()

Symbol.keyFor(s2);只有Symbol.for创建的才能用这个方法
转化String(s1); 
Boolean(s); //转化为布尔值,返回ture
转化为字符串,返回'Symbol(foo)'

作为对象的属性名(三种写法)

[Symbol]

obj[Symbol]

defineProperty()

let s = Symbol();
let obj = {
[s]:’helllo‘
}

创建对象时直接添加属性

let s2 = Symbol();

let obj2 = {};
obj[s2]='hello';

obj.s2='hello'; //报错

对象[Symbol]方法添加,注意:不能用点运算符
let obj3 = {};
let s3 = Symbol();
Object.defineProperty(obj3,s3,{value:'hello'});
用defineProperty添加
使用场景

const obj={case1:Symbol()}; //将魔术字符case1值设为Symbol

function getArea(shape){

  switch(shaoe){

    case obj.case1

    //代码块

    break;}

}

getArea(obj.case1);

消除魔术字符(代码中多次出现,与代码形成强耦合的字符串或数值)

 Singleton 模式(调用类时,任何时候都返回同一个实例)

 

 

 

 

Set和Map数据结构

Set

关注值,值唯一

类似于集合的数据结构,类似于数组,但是成员值是唯一的,没有重复的,因此Set可以用作去除字符串和数组中重复的成员,Set 内部,两个NaN是相等,两个对象总是不相等。Set的key和value相等

//1.生成
new Set()
//2.添加成员
//可接收有Interator接口的数据结构,包括数组,NodeList,字符串
const s=new Set([1,2,2,3]); //数组去除重复值
const s=new Set(document.querySelectorAll('p')); //NodeList
const s=new Set('12344'); //字符串去除重复值
//3.属性和方法
s.size; //返回Set实例成员总数
s.has(value); //检查实例中是否存在该value值,存在则返回ture
s.add(value); //添加value值,返回实例
s.delete(value); //删除value值,删除成功返回ture
s.clear(); //删除所有成员,无返回值
//4.遍历
for(let a of s.keys()){alert(a)} //遍历并返回键
for(let a of s.values()){alert(a)} //遍历并返回值(value()可省略)
for(let a of s.entries()){alert(a)} //遍历并返回键和值
s.forEach((value,key) => {alert(value+','+key)})
//5.Set结构转换成数组
Array.from(new Set('123'));
[...new Set('123345')];
//实现数组并集,交集,差集(数组filter方法和Set的has方法)
let a = new Set([1,2,3]);
let b = new Set([1,2,3]);
let c = new Set([...a,...b]);//并集
let c = new Set([...a].filter(x => b.has(x)));//交集
let c = new Set([...a].filter(x => !b.has(x)));


Map

关注键,键唯一

Map(键-值)是类似对象(键-值)的数据结构,但是Map中键不一定要是字符串,Map中除NaN外,键和键严格相等(+0,-0严格相等)才看作是同一键且键唯一存在,Map中两个对象(包括数组)作为键总是不相等

//生成
new Map();
//性质
const map = new Map([[NaN,111],[NaN,222]]); //NaN为相同键,重新赋值
const map = new Map([[{},111],[{},222]]) //对象总为不同键,对象的写法{a:1},{'a',1},{}
const map = new Map([[[],111],[[],222]]);//数组总为不同键
//添加成员
//可以接受二维数组,Set,Map作为参数(条件有Iterator接口且成员都为双元素)
const map = new Map([['ture',1],[NaN,1],[NaN,2]],[{p:'value'},'content']); 
const map = new Map(new Set([['a',1],['b',2]]));
const map = new Map(new Map([['a',1],['b',2]])); 
//属性和方法
map.size;//
map.set(key,value); //key若为对象和数组,无论如何都成为新成员,
map.get(key); //key为对象和数组时,value都为undefine
map.has(key); //按键查询,返回ture/false
map.delete(key);//按键删除,返回ture/false
map.clear(); //清除所有成员,没有返回值
//遍历
for(item of map.keys){console.log(item)}; //遍历键
for(item of map.values){console.log(item)}; //遍历值
for(item of map.entries){console.log(item[0]+item[1]+[2])}; //遍历键和值
map.forEach((value,key,map) => {console.log(value+key+map)})

Promise

获取异步操作的消息,相当于一个异步调用的容器,可以监听调用结果(成功或失败)

创建实例

new Promise()

const promise = new Promise( (resolve,reject) => {

   function(){ 

       if( // 成功 ){

           resolve(value,times);

        }else{

            reject(error,times);}

       };

    //代码块

})

new Promise接收一个函数作为参数,这个函数又接受resolve和reject函数作为参数

成功:调用resolve函数(并传参 times:回调延迟执行时间,可不写)

失败:调用reject函数(并传参 times:回调延迟执行时间,可不写)

指定回调函数

.then()

.catch()

.finally()

promise.then(value => { //成功 },error => { //失败 });promise原形链上的的then方法指定resolve和reject函数的回调函数

promise.then(value => { //成功 }).catch(err => { //出错 });

相当于

promise.then(value => { //成功 }).then(null,(err) => { //出错 })

promise原形链上的catch方法指定发生错误时(reject对应的回调函数)的回调函数相当于

.then(null,rejection)或.then(null,rejection)

promise.finally(() => { //无论如何都执行 })

相当于

promise.then(value => { //成功 return value },error => { //失败  return error});

promise原形链上的finally方法指定promise执行后无论如何都调用的函数(成功和失败都调用它)

 

resolve后代码块

const promise = new Promise( (resolve,reject) => {

    resolve(1);  

    console.log(2);

}).then( r =>  console.log(r) )  

没有return时 resolve后代码块会执行,并且会比resolve先执行

先打印出2再打印出1

const promise = new Promise( (resolve,reject) => {

    return resolve(1);  

    console.log(2);

}).then( r =>  console.log(r) ) 

return时 resolve后代码块不会执行

只打印出1

Promise实例

实现异步加载图片

function loadImageAsync(url) {
  return new Promise(function(resolve, reject) {
    const image = new Image();

    image.onload = function() {
      resolve(image);
    };

    image.onerror = function() {
      reject(new Error('Could not load image at ' + url));
    };

    image.src = url;
  });
}

 

实现Ajax

const getJSON = function(url){

    //异步容器promise

    const promise = new Promise(resolve,reject){

       //判断是否成功

       const handler = function(){

           if (this.readyState !== 4){ return; } //失败

           if (this.state === 200){  resolve(this.response) }

           else{ reject( new Error(this.statusText() ) ; }

       };

       //Ajax实例

       const ajax1 = new XML.HttpRequest();

       ajax1.open('GET',url);

       ajax1.setRequestHeader('Accept','application/json');

       ajax1.responseType='json';

       ajax1.onreadystatechange=handler;

       ajax.send();

    };

    return promise;

};

getJSON('/posts.json').then(json => { console.log(json) },error => { console.log(error) });

结构:

const getJSON = function(url){

    const promise = new Promise(resolve,reject){

       const handler = function(){

       //获取异步操作,调用resolve和reject

       };

       //Ajax实例(代码块)

    };

    return promise;

};

getJSON('/posts.json').then(,);

function getUsername(userId)

{ return database.users.get({id: userId}) .then(function(user) { return user.name; }); }

database.users.get({id: userId}返回一个Promise实例

包装多个promise

.all()

.race()

const p1 = new Promise((resolve,reject) => {

}).then()

const p2 = new Promise((resolve,reject) => { }).then().catch 

Promise.all([p1,p2]).then().catch()

Promise实例p2有自己的catch函数,Promise中的catch不会被执行,如果p2没有catch,才可能会被执行,当实例全为resolve,执行all后then,若有其中一个为reject,执行catch
.race()类似.all().race()类似.all()

.resolve()

//不带参数

const promise = Promise.resolve(); //生成Promise实例

//参数为Promise实例

const promise = Promise.resolve(p1);//返回实例

//参数为thenable(有then)

let thenable = {then : () => { resolve(42) } }

const promise = Promise.resolve(thenable).then(value=>{

console.log(value)

})

//参数是对象但无then方法,或不是对象

const promise = Promise.resolve(“123”);

p.then(val => console.log(val)); //123

 

无参数时,相当于const promise = new

Promise((resolve,reject) => resolve() )

 

 

 

 

参数是thenable时,立即执行thenable中then

 

 

参数是无then方法的对象,或不是对象,生成新的Promise对象,状态为成功resolve

.reject()

//无参数

const promise = Promise.reject();

//参数为thenable(有then)

let thenable = {then : () => { reject(42) } }

Promise.reject(thenable).catch(e=>{

console.log(e === thenable)

})

无参数时,相当于const promise = new

Promise((resolve,reject) => reject() )

 

 

参数为thenable是,thenable返回给catch的参数是thenable本身,而不是其抛出的42

.try()

const f = () => { // }    //f是函数

Promise.try(f)  

//捕获同步和异步错误

Promise.try(() => database.users.get({id:userId})) 

             .then(...)

             .catch(...)  //捕获同步和异步异常

//实例

var Promise = require("bluebird");

function getUsername(userId)

{ return Promise.try(function() { return database.users.get({id: userID}); })

.then(function(user) { return user.name; }); }

同步函数同步操作,异步函数异步操作

 

 

database.users.get()返回Promise对象

 

异步错误:reject

同步错误:如数据库连接错误

Generator

异步编程解决方案,是一个状态机,封装了多个状态,还会返回一个遍历器对象

 

 

 

 

有Interator接口的数据结构

NodeList,数组,字符串,Set结构,Map结构,TypeArray,函数argument对象

那些场合会调用Interator:数组和Map的解构赋值;扩展运算符;yield*;for...of遍历;Array.from转换为数组;Map(), Set(), WeakMap(), WeakSet();Promise.all();Promise.race();

for...of

对数组,对象,Map和Set进行遍历

数据类型数据遍历for...of
数组let arr = [1,2,3];

for(let v in arr){ // }  //获取键名(少用)

for(let k of arr){ // }; //获取键值

for(let k of arr.keys(obj)){ // } //获取键

for(let v of map.values(obj)){ // } //获取键值

for(let k of map.entries(obj)){ // } //获取键值对

 对象

//普通对象

const obj = {x:1,y:1};
 

//普通对象

for(let v in obj){ // }  //获取键名

for(let k of Object.keys(obj)){ // } //获取键

for(let v of Object.values(obj)){ // } //获取键值

for(let k of Object.entries(obj)){ // } //获取键值对

类似数组对象

//有Interator接口

let paras = document.querySelectAll("p"); //NodeList对象

let str = "hello"; //字符串

//函数中arguments对象

function a(){

for(let x of arguments){ // }

}

for(let v of paras){ // }

for(let v of str){ // }

//无Interator接口

const obj2 = {length:2,0:'x',1:'y'}

for(let x of Array.from(obj2)){ // }

Mapconst map = new Map([[x,1],[y,2]])

for(let k of map.keys()){ // } //获取键

for(let v of map.values()){ // } //获取键值

for(let k of map.entries()){ // } //获取键值对

Setconst map =new Set([a,b,c])

for(let k of set.keys()){ // } //获取键

for(let v of set.values()){ // } //获取键值

for(let k of set.entries()){ // } //获取键值对

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值