一、新增数据类型Symbol
概念:
Symbol代表独一无二的
Symbol类型的值通过Symbol函数来生成,同时Symbol函数返回的值的唯一的
Symbol函数可以接收字符串作为参数,但是即使相同参数返回的值也是唯一的
作用:
属性私有化
数据保护
//没有参数的情况 var s1=Symbol(); var s2=Symbol(); s1===s2; //false //有参数的情况 var s1=Symbol("foo"); var s2=Symbol("foo"); s1===s2; //false var mySymbol=Symbol(); //第一种写法 var a={}; a[mySymbol]="Hello!"; //第二种写法 var a={ [mySymbol]:"Hello!" }; //第三种写法 var a={}; Object.defineProperty(a,mySymbol,{value:"Hello!"}); //枚举symbol的key值 Object.getOwnPropertySymbols(obj); //注意:Symbol作为对象的key值不能被fon in进行遍历
二、块级作用域
概念:在ES6中,凡是{}包裹的代码都是块级作用域,凡是在块级作用域中用let const声明的变量都在有一个暂时性死区。
{ let a=20; } console.log(a);//报错
三、var let const声明变量
var
支持变量声明与解析
不支持块级作用域
允许重复声明
let
不支持变量声明与解析
支持块级作用域
不允许重复声明
用let声明的变量或者方法只会在代码块中生效
{
let a=10;
var b=20;
}
console.log(a); //报错
const
不支持变量声明与解析
支持块级作用域
不允许重复声明
声明常量,一旦声明不可修改
声明常量必须赋值,不能和var一样声明后再定义
四、解构赋值
概念:允许按照一定的格式,从对象和数组中提取值
//数组解构 let [a,b,c]=[1,2,3]; //对象解构---对象解构时,key值必须要一一对应 let {name,age}={name:"孙艺珍",age:20}; //对象解构+别名 let {name:_name,age:_age}={naem:"孙艺珍",age:20}; //多重解构 let {obj:{name},arr:[a,b]}={obj:{name:"孙艺珍",arr:[10,20]}}; //案例 let {left:l,top:t}=document.getElementById("box");
五、扩展运算符
概念:将数组或对象转换成参数序列,使用逗号分隔的序列。
作用:
1、数组、对象的合并
2、函数剩余参数
3、替代arguments
//数组合并 var arr1=[10,20,30]; var arr2=[40,50,60]; var newArr=[...arr1,...arr2]; //展开数组 console.log(Math.max(...arr)); //对象合并 var obj1={100,height:100}; var obj2={left:100,top:100}; var newObj={...obj1,...obj2};
六、字符串模板
1、字符串太长需要换行怎么办?
//常规解决方案 var a="<div>"+ "<span>"+num+"</span>"+ "<div>"; //ES6神器 var a=` <div> <span></span> </div> `;
2、字符串拼接太麻烦怎么办?
//ES6神器-----使用 `` 代替 "" 或 '' ,使用${phone}实现变量拼接 var phone=15200000000; var intro=`my name is wql,my phone id ${phone}`;
3、includes字符串搜索
//ES6神器----includes方法:str.includes(内容)
找到了返回true,找不到返回false var str="good method!"; str.includes("method");
4、判断首尾startsWith endsWith
/* startsWith判断是否位于头部 endsWith判断是否位于尾部 这两个方法是includes的扩展 */ let str="how are you?"; str.startsWith("how");//true str.endsWith("?");//true
5、repeat字符串重复(懒人福利)
//str.repeat(n); 将字符串重复n次(n为整数) let str="money"; str.repeat(2);//"moneymoney"
七、对象新增的方法
1、对象的简写
var a=10; var obj={a}; //等价于 var obj={a:10}; //当key值与value值一样的时候我们可以写一个
2、Object.is
//判断两个对象是否指向同一个内存地址 var obj1={a:1,b:2}; var obj2=obj1; Object.is(obj1,obj2);//true
3、Object.assign
//合并对象 var obj1={name:"孙艺珍",age:20}; var obj2={sex:"女"}; var newObj=Object.assign(obj1,obj2); console.log(newObj);//{name:"孙艺珍",age:20,sex:"女"}
八、数组中新增的方法
1、Array.of()
//将一组值转换为数组 var arr=Array.of(1,2,3,4); console.log(arr);//[1,2,3,4]
2、Array.from()
//将伪数组转换为数组 var aLi=Array.from(document.getElementsByTagName("li")); console.log(aLi instanceof Array);//instanceof判断某对象是否属于某类的实例
3、Array.find()
//通过条件查找数据,返回第一个符合条件的数据 var arr=[1,2,3,4]; var n=arr.find(function(item,index,array){ return item>3; }) console.log(n)
4、Array.findIndex()
//查找数组中符合条件的数据的下标,如果没有查找到则返回undefined var arr=[1,2,3,4]; var n=arr.findIndex(function(item,index,array){ return item>3; }) console.log(n)
5、Array.fill()
//对数组进行填充 语法:arr.fill("内容",开始下标,结束下标) var arr=[1,2,3,4]; arr.fill("wql",1,3);//[1,3) console.log(arr)//[1, "wql", "wql", 4]
九、for of && for in
/* 1、for of是ES6的,fon in是ES5的 2、for of遍历的是值,for in遍历的是键 3、for of不能遍历对象,for in既可以遍历数组也可以遍历对象 4、for of遍历数组的时候,如果有未定义的项,遍历出来是undefined,for in遍历不到 5、for of不能遍历到原型上定义的属性(自定义属性),for in可以遍历到
6、for of的兼容性不是很好,移动端安卓微信浏览器不支持,Safari支持 */ Array.prototype.hehe="呵呵"; var arr=[1,2,3,,4]; for(let item of arr){ console.log(item)//1 2 3 undefined 4 } for(let prop in arr){ console.log(prop)//0 1 2 4 hehe } var obj={ name:"孙艺珍", age:20 }; for(let item of obj){//报错 console.log(item) } for(let prop in obj){ console.log(prop)//name age }
十、函数
1、函数参数默认值
//ES6之前函数如何设置默认值 function fn(x){ var x=x||10; } //ES6函数默认值,等价于上面的写法,如果没有传递参数,就用默认值10 function fn(x=10){ }
2、剩余参数
//fn函数中a接收实参1,...rest接收剩余参数为一个数组 function fn(a,...rest){ console.log(rest)//[2,3,4,5] } fn(1,2,3,4,5)
3、箭头函数
//语法一 function 换成了 ()=> var fn=(a)=>{ console.log(a) } fn(10) //语法二 不写{}默认表示return,当前函数意思是返回a这个值 var fn=a=>a; fn(10) //语法三 不写{}表示retur,当前函数意思是返回一个对象 var fn=a=>({a:1}); fn() /* 箭头函数特点: 1、this指向离自己最近的外层作用域的对象 2、不能当做构造函数使用(箭头函数是匿名函数,没有函数名字,没办法new) 3、没有arguments这个参数(ES6已经取消arguments了) 4、不能当做generator函数 */
十一、Set集合
/* Set:集合 1、类似于数组,但成员的值是唯一的,没有重复的值,并且是无序的 2、Set是一个构造函数 3、Set每次执行完毕后都会返回一个Set,因此可以进行链式调用 */ let s=new Set(); //添加 add() s.add("a").add("b"); console.log(s)//Set(2) {"a", "b"} //删除 返回值是一个布尔值 s.delete("a");//true //判断a是不是Set的成员 返回布尔值 s.has("a") //清除所有 没有返回值 s.clear() //返回所有键名 s.keys() //返回所有value值 s.values() //返回所有键值对 s.entries() //可以通过for of遍历每一个值 for(let item of s){ console.log(s) }
十二、Map字典类型结构
/* 1、字典:用来存储不重复key的hash结构,不同于Set集合,字典使用[键,值]的形式来存储 2、Map执行完毕后都会返回一个Map,可以进行链式调用 3、特点:普通对象只能通过字符串来当做key值,但是Map可以用任意值来当做key值 */ //创建Map对象 let map=new Map([ ["a",1], ["b",2] ]) console.log(map)//Map(2) {"a" => 1, "b" => 2} //获取map长度 map.size //添加数组 map.set("c",3) //获取map值 map.get("a") //删除数据 删除成功返回true map.delete("a") //检测map中是否含有某个值 返回布尔值 map.has("a") //清除所有数据 map.clear() //获取所有key值 map.keys() //{"b", "c"} //获取所有value值 map.values() //{2, 3} //获取所有键值对 map.entries() //遍历map对象 index在前,item在后(数组中item在前) map.forEach((index,item)=>{ console.log(index,item) })
十三、Proxy介绍
概念:Proxy是ES6中新增的一个特性。
作用:在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写,很类似于设计模式中的代理模式。
基本用法:
let p=new Proxy(target,handler);
参数:
target:用Proxy包装被代理的对象(可以是任意类型的对象,包括原生数组、函数、甚至是另一个代理)
handler:是一个对象,其声明了代理target的一些操作,其属性是当执行一个操作时定义代理的行为的函数
特点:
①可以劫持整个对象,并返回一个新对象
②有13种劫持操作
③handler代理的一些常用的方法:
get 读取
set 修改
has 判断对象是否有该属性
construct 构造函数
apply 当目标对象是一个函数的时候
deletePrototy 用于拦截delete操作
十四、get/set方法
var target={ name:"孙艺珍", age:20, sex:"女" } var p=new Proxy(target,{ get(obj,attr){ console.log("属性被访问了") }, set(obj,attr,value){ console.log("属性被设置了") } }) p.name; p.name="小王";
get函数:当访问target对象身上的一些属性的时候就会触发get函数,get函数接收2个参数
参数一:代理的对象,也就是target
参数二:访问的属性
set函数:当设置target对象身上的一些属性的时候就会触发set函数,set函数接收3个参数
参数一:代理的对象
参数二:设置对象的属性
参数三:设置对象属性的值
使用场景:
1、虚拟属性
var target = { firstName: "张", lastName: "小凡" } var p = new Proxy(target, { get(obj, attr) { if (attr == "fullName") { return [obj.firstName, obj.lastName].join(""); } return obj[attr] }, set(obj, attr, value) { if (attr == "fullName") { var fullNameInfo = value.split(" "); obj.firstName = fullNameInfo[0]; obj.lastName = fullNameInfo[1]; } else { obj[attr] = value; } } }) console.log(p.fullName);//张小凡 p.fullName = "小 甜甜"; console.log(p.firstName);//小 console.log(p.lastName);//甜甜
2、私有属性
//把_开头的变量都认为私有变量 var target = { name: "张三", age: 19, _sex: "女" } var p = new Proxy(target, { get(obj, attr) { if (attr.startsWith("_")) { console.log("私有属性不允许被访问"); return false; } return obj[attr]; }, set(obj, attr, value) { if (attr.startsWith("_")) { console.log("私有属性不允许被设置"); return false; } obj[attr] = value; }, has(obj, attr) { if (attr.startsWith("_")) { return false; } return (attr in obj); } })
十五、函数拦截
apply:当目标对象是一个函数,且它被调用时,就是被apply方法拦截
参数:apply(target,context,arguments){}
target:目标对象
context:目标对象的上下文对象(this)
arguments:目标对象的参数数组
construct:用于拦截new命令,意思就是你在new目标对象的时候,会走construct(){}
参数:construct(target,arguments){}
target:目标对象
arguments:构造函数的参数对象
function fn(a, b) { } var handler = { apply: function (target, context, args) { console.log(target, context, args) return args[0]; }, construct: function (target, args) { return { value: args[1] }; } }; var p = new Proxy(fn, handler); console.log(p(1, 2)) //1 console.log(new p(1, 2)) // {value:2}