es6总结
var和let以及const区别?
var 没有块级作用域 变量提升;挂载到window let 块级作用域名 不会变量提升 不会通过window访问;不允许重复申明 const 一旦声明不允许更改 只针对基本类型null , undefined, mysbol, number, string, boolean
解构赋值
let obj={
name:"张三",
age:20
}
let {name,age}=obj;
console.log(name,age);
展开运算符 ...
let obj={
name:"张三",
age:20
}
let newObj={height:"190cm",...obj};
console.log(newObj);
不定参数
以前获取隐藏参数可以通过arguments
function test(){
console.log(arguments);
}
test(1,2,3);
es6获取隐藏参数(不定参数)
function test(...arg){
console.log(arg);
}
test(1,2,3);
ES6中的Map和Set详解
概览
本文主要介绍了 ES6新增的Set和Map 数据结构,对其特性和常见用法进行了梳理
一. Set
Set是ES6中新增的数据结构,它类似于数组,但是Set数据中的元素都是唯一的,没有重复值的;
Set构造函数参数:初始化参数的时候,参数必须是实现iterator接口的数据类型,否则会抛出异常;
const set = new Set([1,2,3]);
const set1 = new Set('1233');
const set2 = new Set(1);
//VM387:1 Uncaught TypeError: number 1 is not iterable (cannot read property Symbol(Symbol.iterator))
at new Set (<anonymous>)
at <anonymous>:1:12
属性和方法
- Set.prototype.add()方法
Set.prototype.add(value);
参数1 value:需要添加到set元素中的值,不能够添加重复值;
返回值:返回实例化对象Set本身;
var s1 = new Set([1, 2, 3]);
var s2 = s1.add(4);
console.log(s1); // Set {1, 2, 3, 4}
console.log(s1 === s2); // true
- Set.prototype.has()方法
Set.prototype.has(value);
参数1 value:必填项,测试该值是否存在Set对象中;
返回值:布尔值,false表示不存在,true表示存在;
var s1 = new Set([1, 2, 3, 4]);
s1.has(4); // true
- Set.prototype.size
size属性将返回Set对象的元素个数;
// add方法可以链式调用
var mySet = new Set();
mySet.add(1).add(2).add(3);
mySet.size; // 3
- Set.prototype.delete()方法
Set.prototype.delete(value);
参数1 value:需要删除的元素;
返回值:成功删除返回true,否则返回false;
- Set.prototype.clear()方法
clear()方法用来清空一个Set对象中的所有元素; - Set遍历的方法
Set.prototype.keys()方法,Set.prototype.values()方法,Set.prototype.entires()方法
var s1 = new Set([1, 2, 3]);
var iterator = s1.keys();
console.log(iterator);
var iterator = s1.values();
console.log(iterator);
var iterator = s1.entries();
console.log(iterator.next());
keys和values返回的结果相同,Set中的key等于value,这也是新增时add只传一个参数的原因
应用场景
- 数组去重
var arr = [1, 2, 3, undefined,undefined,null,null, NaN, 1, 2, 3, NaN],
set = new Set(arr);
console.log([...set]);
- 数组去重后的实现映射数组
set实例本身没有map,filter等数组方法
let set = new Set([1,2,3,4,5,6,7]);
let set2 = new Set([...set].map(value => value * 2));
let set = new Set([1,2,3]);
let set1 = new Set(Array.from(set, vlaue=>value * 2));
- 数组去重后,过滤返回新的数组
let set = new Set([1,2,3,4,5,6,7,1,2,3]); let set2 = new Set([...set].filter(x => (x%2) == 0));
Set循环递归调用会变成死循环
const s1 = new Set([1]) s1.forEach(item => {s1.delete(1);s1.add(1);console.log('end')})
会一直循环调用forEach里面代码,不断打印end
二. Msp
传统的对象属性键名为字符串,不能用对象做为键名;Map数据结构的出现,实现对象键名与键值一一对应的关系;
- 传统ES5中对象的属性名以字符串的形式存在
var m = {};
var x = {id:1}, y = {id:2};
m[x] = 'foo';
m[y] = 'bar';
console.log(m);
console.log(m[x]); // bar
console.log(m[y]); // bar
会将属性先执行toString方法
2.基本用法
Map构造函数参数:必须已经部署iterator接口的数据结构;
此时构造函数参数中的每一个参数必须拥有双元的数组结构;
两种声明方式
//1.
let map = new Map([['name', 'zhansan'], ['sex', 'male']]);
//2.
let items = [['name', 'zhansan'], ['sex', 'male']],
map = new Map();
items.forEach(function([key, value]){ map.set(key, value); });
- Map遍历的方法
const map = new Map([['name','zhangsan'],['sex','male'],['age',20]]);
console.log(map.keys());
console.log(map.values());
console.log(map.entries());
- Map.prototype.set()
set()方法为Map对象添加或者更新一个指定键(key)和值(value)的新键值对;
var myMap = new Map();
// 添加元素
myMap.set("bar", "foo");
myMap.set(1, "foobar");
console.log(myMap);
// 更新元素
myMap.set("bar", 'goo');
console.log(myMap);
Map.set()设置属性时,属性名相同时,后面覆盖前面的键值;
Map键名覆盖的问题: 本质上与全等的运算方式类型,只是对待NaN问题上不同
const map = new Map();
map.set(-0, 123);
console.log(map.get(+0)); // 123
map.set(true,1);
map.set('true',2);
console.log(map.get(true)); // 1
map.set(NaN,123);
map.set(NaN,456);
console.log(map.get(NaN)); // 456
- Map.prototype.get()方法
get()方法返回某一个Map对象中的一个指定键名;
如果找不到相关的键名,则返回undefined;
注意不同的引用值数据类型作为键名,获取的数据不同;
// 引用地址不同的情况;
const map = new Map();
map.set([5], 555);
map.get([5]); // undefined
map.set({}, 555);
console.log(map.get({})); // undefined
// 引用地址相同的情况
var obj = {id:1};
const map = new Map();
map.set(obj, 'foo');
console.log(map.get(obj)); // 'foo'
- 和Set 对比 Map.prototype上的clear()、has()、size、delete()方法与Set.prototype上相同;唯一不同的是,Set是不存在键名的,键值与键名相同,所以没有get和set的方法,只有add方法;而Map具有键名和键值,所以对应set和get方法;
什么是Symbol详解
Symbol是ES6中引入的一种新的基本数据类型,用于表示一个独一无二的值。它是JavaScript中的第七种数据类型,与undefined、null、Number(数值)、String(字符串)、Boolean(布尔值)、Object(对象)并列。 你可以这样创建一个Symbol值:
const a = Symbol();
console.log(a); //Symbol()
使用Symbol函数可以生成一个Symbol类型的值,但是你不能在调用Symbol时使用new关键字,因为Symbol是基本数据类型,而不是对象。比如下面的写法是错误的:
//报错,Symbol is not a constructor
const a = new Symbol();
使用Symbol()创建一个Symbol类型的值并赋值给a变量后,你就得到了一个在内存中独一无二的值。现在除了通过变量a,任何人在任何作用域内都无法重新创建出这个值。例如当你这样写:
const b = Symbol();
实际上,a变量拿到了内存中某块内存的唯一引用(这里所说的引用,其实就是该内存的地址)。如果不借助a变量,你不可能再得到这个地址
a !== b; //a和b持有的是两块内存的引用
const c = a; //手动把a里保存的地址保存在c变量中
a === c; //c和a现在指向同一块内存,因为它们保存了同样的地址
es6中数组新增常用的方法有哪些
es6中数组新增常用的4个方法是:1、forEach(),用于遍历数组,无返回值;2、filter(),过滤掉数组中不满足条件的值;3、map(),遍历数组,返回一个新数组;4、reduce(),让数组的前后两项进行某种计算,然后返回其值。
1.forEach
遍历数组,无返回值,不改变原数组,仅仅只是遍历 --相当于for循环遍历
let arr=[23,44,56,22,11,99]
let res=arr.forEach(item=>{
console.log(item);
//23,44,56,22,11,99
})
let res2=arr.forEach((item,index)=>{
console.log(item,index);
//23 0
//44 1
//....
})
2.filter
filter()函数过滤掉数组中不满足条件的值,如果回调函数返回true就留下,返回一个新数组,不改变原数组,!!!可以用来做数组去重
let arr = [1,5,2,16,4,6]
//1.找出数组中的偶数
let newArr=arr.filter((v,i)=>
v%2==0)
console.log(newArr,'newArr');//2,16,4,6
//2.过滤器 保留为TRUE的结果
let arrTue=[13,14,9,33]
let newArr2=arrTue.filter(item=>(item%3===0)?true:false)
console.log(newArr2,'newArr2');//9,33
//3.利用filter去重‘
// 第一种
let arr3=[2,3,5,1,2,3,4,5,6,8],newArr3
function unique(arr){
const res = new Map()
return arr.filter((item)=>
!res.has(item) && res.set(item,1)
)
}
console.log(newArr3=unique(arr3),'newArr3');//2,3,5,1,4,6,8
//第二种
let testArray = [
{key:"01",name:'张三'},
{key:"02",name:'小李'},
{key:"03",name:'小罗'},
{key:"04",name:'张三'},
{key:"03",name:'小李'},
];
let deduplicationAfter = testArray.filter((value,index,array)=>{
//findIndex符合条件的数组第一个元素位置。
return array.findIndex(item=>item.key === value.key && item.name === value.name) === index
})
console.log(deduplicationAfter)
3.reduce
reduce()汇总 一堆出来一个(用于比如,算个总数,算个平均),reduce让数组的前后两项进行某种计算,然后返回其值,并继续计算,不改变原数组,返回计算的最终结果,如果不给定初始值,则从数组的第二项开始遍历
arr.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue]) ,第一个参数回调函数,第二个参数初始值
3.1求和
//第一种给定初始值
var arr = [1, 3, 5, 7];
// 原理: 利用reduce特性 prev初始值设置0 并把函数的返回值再次带入函数中
var sum = arr.reduce(function (tmp, item,index) { // prev 初始为0 以后则为函数返回的值
console.log(tmp,item,index);
// 0 1 0
// 1 3 1
// 4 5 2
// 9 7 3
return tmp + item; // 数组各项之间的和
}, 0);
console.log(sum); //16
//第二种不给初始值
var arr2 = [1, 3, 5, 7]
var result = arr2.reduce(function (tmp, item, index) {
//tmp 上次结果,item当前数,index次数1开始
console.log(tmp, item, index)
//1 3 1
// 4 5 2
// 9 7 3
return tmp + item;
})
console.log(result,) //16
3.2求平均数
var arr = [1, 3, 5, 7]
var result = arr.reduce(function (tmp, item, index) {
console.log(tmp,item,index);
// 1 3 1
// 4 5 2
// 9 7 3
if (index != arr.length - 1) { // 不是最后一次
return tmp + item
} else {
return (tmp + item)/arr.length
}
})
console.log(result,'[[[u99') // 平均值 4
4.map
map遍历数组,返回一个新数组,不改变原数组, 映射 一个对一个,映射到一个新数组
let arr = [6,10,12,5,8]
let result = arr.map(function (item) {
return item*2
})
let result2 = arr.map(item=>item*2) // es6的箭头函数简写,若想了解,后面的文章有介绍
console.log(result)
console.log(result2)
let score = [18, 86, 88, 24]
let result3 = score.map(item => item >= 60 ? '及格' : '不及格')
console.log(result3)
es6中object有哪些方法
es6中的object方法:1、“Object.is()”,用来比较两个值是否严格相等,与严格比较运算符“=== ”的行为基本一致;2、“Object.assign()”,用于对象的合并;3、“Object.keys()”,遍历对象,获取全部键名;4、“Object.keys()”,遍历对象,获取全部键值;5、“Object.entries()”,遍历对象,获取全部值对。
Object.is()
Object.is()它用来比较两个值是否严格相等,与严格比较运算符( === )的行为基本一致,是在三等号判断的基础上新增了两个不同之处。
Object.is()不同之处只有两个:一是+0不等于-0,二是NaN等于自身。
语法:Object.is(value1, value2);
传入两个要比较的值,判断是否相同,全等的话返回true,不全等返回false。
console.log(Object.is('foo','foo'));//true
console.log(Object.is({},{}))//false
console.log(Object.is([],[]))//false
console.log(+0===-0)//true
console.log(NaN===NaN)//false
console.log(Object.is(+0,-0)) //false
console.log(Object.is(NaN,NaN)) //true
三等号既要判断值的类型是否相等,还要判断引用地址是否相等。所以Object.is()也是,在判断对象和数组这些引用类型的数据是不相等的。
Object.assign()
Object.assign()方法用于对象的合并,将源对象( source )的所有可枚举属性,复制到目标对象( target )。
Object.assign(target, ...sources) 参数: target--->目标对象 source--->源对象 返回值:target,即目标对象
var target={name:'guxin',age:25};
var source={state:'single'}
var result=Object.assign(target,source);
console.log(target,target==result);
Object.keys()、Object.values()、Object.entries()
Object.keys()方法,返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历( enumerable )属性的键名数组。
Object.values()方法返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历( enumerable )属性的键值数组。
Object.entries()方法返回一个二维数组,成员是参数对象自身的(不含继承的)所有可遍历( enumerable )属性的键值对数组 例如:
[["key","value"],["key","value"]]。
let obj = {name:``"winne"``,age:22};
let objKeys = Object.keys(obj);
let objValues = Object.values(obj);
let objItem = Object.entries(obj);
取出了想要的部分,我们就可以遍历数组取得每一项了。
//for..of遍历
for( let key of objKeys){
console.log(key)
}