javascrip原有的表现集合概念的数据结构:
Array-数组
Object-对象
es6:四种集合概念的数据结构
Array-数组
Object-对象
Map
Set
Iterator遍历器
1 提供一种通用的遍历不同数据结构的方法
2 拥有Symbol.iterator属性的数据结构,都可以使用for...of来进行遍历
3 原生具备Iterator接口的数据结构如下
3.1 Array
3.2 String
3.3 Set
3.4 Map
3.5 TypedArray
3.6 函数的arguments对象(箭头函数中没有arguments对象)
3.7 NodeList
4 所以其他的结构如果要使用for...of的话,需要加上Symbol.iterator属性,比如Object默认是没有的,可以加上,但不是很有必要
Promise对象的好处:
1 可以将异步操作以同步的流程表达出来,不会出现层层嵌套的情况
2 Promise对象提供统一的接口,使得控制异步操作更加容易
Promise对象的缺点:
1 无法取消Promise,一旦新建它就会立即执行,无法中途取消
2 如果不设置回调函数,Promise内部抛出的错误,不会反应到外部
3 当处于pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)
字符串的扩展:
1 模板字符串
2 新增了一些方法:
2.1 之前判断内容会否存在这个字符串只有indexOf(),现在新增了3个方法:
includes(); 是否包含
startWith(); 是否以它开头
endWith(); 是否以它结尾
2.2 将一个字符串重复
let h = 'hello'.repeat(3); //h="hellohellohello"a
参数只能是正数,不能为负数,可以为小数,但只会取整数部分,如:2.9->2
如果参数为负数会报错,注:如果是小数会在取整数部分之后判断是否为负数,因为如:-0.1 取整数部分-> -0 ->0 所以这里不会报错,因为取整之后就等于0了,不是负数了
2.3 trim() 消除前后字符串前后的空格
这里新增了2个方法:
trimStart() 清除头部
trimEnd() 清除尾部
数值的扩展:JavaScript 所有数字都保存成 64 位浮点数
1 ES6 将全局方法parseInt()和parseFloat(),移植到Number对象上面,行为完全保持不变。
1.1 parseInt() 这是原来的使用方式
1.2 Number.parseInt() 现在的使用方式
2 判断是否为整数
Number.isInteger();
3 Math的扩展:
3.1 Math.trunc() 返回一个数的整数部分(+-号保留)
如:Math.trunc(12.9)->12
Math.trunc(-12.9)->-12
3.2 Math.pow(n,m) n的m次方(这个不是新增的)
4 es6新增了一个数据类型-BigInt(大整数,类似Java中的大数BigDecimal),可以计算超出Number范围的数值
函数的扩展:
1 参数可以设置默认值
指定默认值后,这个参数就不计算在函数的length属性上了,比如:
(function func(x,y=1){}).length //1,如果y没有设置默认值,则length=2
2 rest参数,可以将多余的参数放到rest中
如:function func(x,...arr){} arr是个数组
func(1,2,3,4,5);
则这个时候arr=[2,3,4,5]
3 函数的name属性:返回函数名
function func(){};
func.name; //func
4 箭头函数:
写法:
let f = value=>value+1;
等同于:
let f = function(value){
return value+1;
}
如果有多个参数并且多条语句,则如下:相当于省略了function
let f = (v1,v2)=>{
console.log(v1);
return v1+v2;
}
注:箭头函数中的this和非箭头函数的this指向不同
普通函数:this指向当时调用这个函数的对象
箭头函数:this指定当时声明这个箭头函数所在的对象的this对象所指
数组的扩展:
1 spread 扩展运算符 (任何定义了 Iterator 接口的对象,都可以用扩展运算符转为真正的数组)
对数组使用扩展运算符
1.1 基本描述
console.log(...[1,2,3]) 只有函数调用时,扩展运算符外面才能包一层括号使用,否则会报错,比如直接 (...[1,2,3]) 回车会报错,
和函数的rest参数是相反的
function func(...arr){
//这是把外面的多个参数接成一个数组
}
1.2 替代apply()方法
spread可以替代es5中的apply方法,因为扩展运算符可以直接展开数组
es5:
function func(a,b,c){}
let param = [1,2,3];
func.apply(null,param);
es6:
function func(a,b,c){}
let param = [1,2,3];
func(...param);
1.3 复制数组
let arr1 = [1,2,3];
let arr2;
使用原来的方法:
方法1:for循环一个个给arr2.push();
方法2:arr2 = arr1.concat(); //通过连接,返回一个新数组,而concat又没有传参数,所以返回的就是arr1数组的内容
使用es6中的扩展运算符:
arr2 = [...arr1];
1.4 合并数组
同样,合并数组也可以使用扩展运算符:
let arr3 = [...arr1,...arr2];
对字符串也可以使用扩展运算符
let strs = [..."hello"]; //["h", "e", "l", "l", "o"]
上面发现对数组可以使用 扩展运算符;对字符串也可以使用扩展运算符,那到底什么时候能使用扩展运算符呢?
任何定义了遍历器(Iterator)接口的对象(参阅 Iterator 一章),都可以用扩展运算符转为真正的数组。
2 Array.of方法用于将一组值,转换为数组
let arr = Array.of(1,2,4); //[1,2,4]
其实也可以这样:let arr = [];
arr.push(1,2,4); //[1,2,4]
3 数组的find()和findIndex()方法
3.1 find(); 返回第一个符合条件的数据
[-9,-5,0,2-7].find((value,index,arr)=>{ //value:循环的每一项值;index:当前下标;arr:该数组
return value>0;
})
//结果是2
3.2 findIndex(); 返回符合条件的第一个数据的index
[-9,-5,0,2-7].findIndex((value,index,arr)=>{ //value:循环的每一项值;index:当前下标;arr:该数组
return value>0;
})
//结果是3
4 includes()等
对象的扩展:
1 属性和方法的简写:
1.1 属性的简写:
let foo = "bar";
let obj = {foo};
相当于:
let foo = "bar";
let obj = {foo:foo};
1.2 方法的简写:
let obj = {
add(x,y){
return x+y;
}
}
等同于:
let obj = {
add:function(x,y){
return x+y;
}
}
2 方法的name属性:
不管是不是对象的方法,都有name属性,返回方法名
obj.add.name; //add
3 属性的遍历:
ES6 一共有 5 种方法可以遍历对象的属性
3.1 for...in
循环遍历对象自身的和继承的可枚举属性(不含 Symbol 属性)
3.2 Object.keys(obj)
返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含 Symbol 属性)的键名
3.3 Object.getOwnPropertyNames(obj)
返回一个数组,包含对象自身的所有属性(不含 Symbol 属性,但是包括不可枚举属性)的键名
3.4 Object.getOwnPropertySymbols(obj)
返回一个数组,包含对象自身的所有 Symbol 属性的键名
3.5 Reflect.ownKeys(obj)
返回一个数组,包含对象自身的(不含继承的)所有键名,不管键名是 Symbol 或字符串,也不管是否可枚举
以上的 5 种方法遍历对象的键名,都遵守同样的属性遍历的次序规则。
首先遍历所有数值键,按照数值升序排列。
其次遍历所有字符串键,按照加入时间升序排列。
最后遍历所有 Symbol 键,按照加入时间升序排列。
4 加入了super 关键字
当前对象的原型对象
5 对象的解构赋值
let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
5 扩展运算符:对象的扩展运算符(...)用于取出参数对象的所有可遍历属性,拷贝到当前对象之中
let z = { a: 3, b: 4 };
let n = { ...z };
n // { a: 3, b: 4 }
由于数组是特殊的对象(key值为下标值),所以对象的扩展运算符也可以用于数组
let foo = { ...['a', 'b', 'c'] };
Symbol类型
Symbol类型的值是独一无二的
基本类型有:undefined,null,number,string,boolean,Object+新增的Symbol
Symbol值的定义:(基本上,它是一种类似于字符串的数据类型)
let s = Symbol();
这个s就是个Symbol值
可以给它加描述信息,便于区分:
let s = Symbol("s");
Set和Map
1 Set
1.1 Set类似于数组,但是Set中的元素不允许重复,都是唯一的
添加成员:
let set = new Set();
set.add(1);
1.2 Set可以接收有Iterator接口的数据结构,所以这里就可以接受:string,Array等
new Set([1,2,2,3]); //{1,2,3}
new Set("hello"); //{"h", "e", "l", "o"}
1.3 利用Set给数组/字符串去重
let array = [.....];
let set = new Set(array);
let arr = [...set];
1.4 Set不能加入重复元素的判断类似于 “===” 的比较,即类型和值都要相同,
因为Set.add()时不会发生类型转换,所以"1",和 1 是不相同的,都能加进去
1.5 Set上的方法
长度:size; 不是方法
是否存在:has(value);
添加:add(value); 返回操作完之后的整个Set
删除:delete(value) 返回boolean值
清除:clear(); 将里面的元素都清掉,size为0
遍历:有四个方法
keys();返回键名的遍历器 由于Set没有键名,所以key和value的值是一样的(这里注意key不是和数组一样的下标值)
new Set("hello"); //第一个元素的key和value都是"h"
values();返回键值的遍历器
entries();返回键值对的遍历器
forEach();返回每个元素
前面3个方法都返回的是遍历器,因此可以直接使用for...of遍历返回的值
let set = new Set([1,2,3,4,5,5,43]);
let keys = set.keys();
for(k of keys){
console.log(k);
}
最后一个forEach()
set.forEach((value,key,set)=>{
console.log(`${key},${value}`);
})
2 Map
2.1 Map结构类似Object,是键值对的形式
Object的key只能是字符串,值的类型没有限制
Map的key和value都可以是任意类型
2.2 基本使用
let map = new Map(); //也可以给参数:new Map([{"name:":"jack"},{"age",12}])
长度:size; //不是方法
是否存在:has(value);
添加(设置):set(key,value);
删除:delete(key);
获取:get(key);
清除所有成员:clear();
遍历:和Set一样,只是keys和values的值不一样,因为Map是有键名的