ES6新特性
一、新增数据类型Symbol。
概念:
Symbol代表独一无二的
Symbol类型的值通过Symbol函数来生成,同时Symbol函数生成的值是唯一的
Symbol函数何以接收字符串作为参数,但是即使相同参数返回的值也是唯一的
作用:
属性私有化
数据保护
//没有参数的情况 let s1 = Symbol(); let s2 = Symbol(); s1 === s2 //false //有参数的情况 let s1 = Symbol("fun"); let s2 = Symbol("fun"); s1 === s2 //false let mySymbol = Symbol(); //第一种写法 let a = {}; a[mySymbol] = "Hello!"; //第二种写法 let a = { [mySymbol]: "Hello!" } //第三种写法 let a = {}; Object.defineProperty(a,mySymbol,{value: "Hello!"}); //枚举Symbol的key值 Object. getOwnPropertySymbols(obj); //注意,Symbol作为对象的key值不能被for 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); //报错 console.log(b); //20
const
不支持变量声明与解析
支持块级作用域
不可以重复声明
声明变量,一旦声明不可修改
声明变量必须赋值,不可以像var一样先声明后再定义。
四、解构赋值。
概念:允许按照一定格式,从对象和数组中提取值。
//数组解构 let [a,b,c] = [1,2,3]; console.log(a,b,c); //1,2,3 //对象解构,对象解构时key值必须要一一对应。 let {name,age} = {name: "张三",age: 20}; console.log(name,age); //张三 20 //对象解构+别名 let {name: _name, age: _age} = {name: "张三", age: 20}; console.log(_name,_age); //张三 20 //多重解构 let {obj:{name},arr:[a,b]} = {obj:{name: "张三"},arr: [10,20]};
五、扩展运算符
概念:将数组或对象转换成参数序列,使用逗号分割的序列。
作用:
1、数组、对象的合并
2、函数剩余参数
3、替代arguments
//数组合并 let arr1 = [10,20,30]; let arr2 = [40,50,60]; let newArr = [...arr1,...arr2]; console.log(newArr); //[10,20,30,40,50,60]; //展开数组 console.log(Math.Max(...arr)); //对象合并 let obj1 = {width: 100, height: 100}; let obj2 = {left: 100, top: 100}; let newObj = {...obj1,...obj2}; console.log(newObj); //{width:100,height:100,left:100,top:100};
六、字符串模版。
1、字符串太长需要换行怎么办?
//常规解决办法 var a = "<div>" + "<span>"+num+"</span>" "</div>"; //ES6语法 let a = `<div> <span>${num}</span> </div>`
2、字符串太长怎么办?
let phone = 15844423232
let intro = `my name is chj, my phone id ${phone}`;
3、includes字符串搜索。
//ES6神器,includes方法,str.insludes(内容),找到了返回true,没找到返回false let str = "good method!"; str.includes("method"); //true
4、判断首尾,startsWith endsWith
/* startsWith判断是否位于头部 endsWith判断是否位于尾部 这两个方法是includes的扩展 */ let str = "how are you?"; str.startsWith("how"); //true str.endsWith("?") //true
5、repeat字符串重复
//str.repeat(n); 将字符串重复n次 let str = "abc"; str.repeat(3); //abcabcabc
七、对象新增方法。
1、对象的简写
let a = 10; let obj = {a}; //等价于 let obj = {a: 10}; //当key值和value值一样的时候我们可以写一个。
2、Object.is
//判断两个对象是否指向同一个内存地址 let obj1 = {a: 1, b: 2}; let obj2 = obj1; Object.is(obj1, obj2); //true
3、Object.assign
//合并对象 let obj1 = {name: '曹海杰', age: 20}; let obj2 = {sex: '男'}; let newObj = Object.assign(obj1, obj2); console.log(newObj); //{name: '曹海杰', age: 20, sex: '男'};
八、数组中新增的方法。
1、Array.of()
//将一组值转换为数组 let arr = Array.of(1,2,3,4); console.log(arr); //[1,2,3,4];
2、Array.from()
//将伪数组转换为数组。 let aLi = Array.from(document.getElementsByTagName("li")); console.log(aLi instanceof Array); //instanceof判断某对象是否属于某类的实例。
3、Array.find()
//通过条件查找数据,返回第一个符合条件的数据。 let arr = [1,2,3,4]; let n = arr.find(function(item, index, array) { return item > 3; }) console.log(n); //4
4、Array.findIndex()
//查找数组中符合条件的数据的下标,如果没有找到则返回undefined let arr = [1,2,3,4]; let n = arr.findIndex(function(item, index , array) { return item > 3; }) console.log(n);
5、Array.fill();
//对数组进行填充,语法:arr.fill('内容',开始下标,结束下标); let arr = [1,2,3,4]; arr.fill('qwe', 1, 3); console.log(arr); //[1, 'qwe', 'qwe', 4];
九、for of and for in
/* 1、for of 是ES6的,for 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 = '呵呵'; let 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 } let obj = { name: 'chj', 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) { let x= x || 10; } //ES6函数默认值,等价于上面的写法,如果没有传递参数,就使用默认值10 function fn(x=10) { }
2、剩余参数
//fn函数中a接收实参1,...rest接收剩余参数为一个数组。 funciton fn(a, ...rest) { console.log(...rest); //[2,3,4,5]; } fn(1,2,3,4,5);
3、箭头函数
//语法一 function 换成 () => let fn = (a) => { console.log(a) } //语法二 不写{}默认表示return,当前函数意思是返回a这个值 let fn = a => a fn(10); //语法三 不写{}默认表示return,当前函数表示返回一个对象 let fn = a => ({a:1}); /* 箭头函数特点: 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 //判断元素是不是Set的成员,返回值是一个布尔值 s.has("a"); //true //清除所有 没有返回值 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(); //获取所有value值 map.values(); //获取所有键值对 map.entries(); //遍历map对象 index在前item在后(数组中item在前) map.forEach((index, item) => { console.log(index, item); })
十三、Proxy介绍
概念:Proixy是ES6中新增的一个特性。
作用:在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须想通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写,很类似于设计模式中的代理模式。
基本用法:
let p = new Proxy(target, handler);
参数:
target: 用Proxy包装被代理的对象(可以是任意类型的对象,包括原生数组、函数、甚至是另一个代理)
handler:是一个对象,其声明了代理target的一些操作,其属性是当执行一个操作时定义代理的行为的函数
特点:
1、可以劫持整个对象,并返回一个新对象
2、有13中劫持操作
3、handler代理的一些常用方法:
get 读取
set 修改
has 判断对象是否有该属性
construct 构造函数
apply 当目标对象是一个函数的时候
deletePrototy 用于拦截delete操作
十四、get/set方法
let target = { name: "chj", age: 20, sex: "男" } let p = new Proxy(target, { get(obj, attr) { console.log("属性被访问了"); }, set(obj, attr, value) { console.log("属性被设置了"); } }) p.name; p.name = "小王";
get函数:当访问target对象身上的一些属性的时候就会触发get函数,get函数接收两个参数
参数一:代理的对象,也就是target。
参数二:访问的属性。
set函数:当设置target对象身上的一些属性的时候就会触发set函数,set参数接收三个参数
参数一:代理的对象
参数二:设置对象的属性
参数三:设置对象的属性的值
使用场景:
1、虚拟场景
let target = { firstName: "chj", lastName: "ls" } let p = new Proxy(target, { get(obj, attr) { if(attr == "fullName") { retrun [obj.firstName, obj.lastName].join(" "); } return obj[attr]; }, set(obj, attr, value) { if(attr == "fullName") { let fullNameInfo = value.split(" "); obj.firstName = fullNameInfo[0]; obj.lastName = fullNameInfo[1]; }else { obj[attr] = value; } } }) console.log(fullName); //chj p.fullName = "小 甜甜"; console.log(p.firstName); //小 console.log(p.lastName); //甜甜
2、私有属性
//把_开头的变量都认为私有变量 let target = { name: "张三", age: 20, _sex: "女" } let p = new Proxy(target, { get(obj, attr) { if(attr.startWith("_")) { console.log("私有属性不被允许访问"); return false; } return obj[attr]; }, set(obj, attr, value) { if(attr.startWith("_")) { console.log("私有属性不允许设置"); retrun false; } obj[attr] = value; }, has(obj, attr) { if(atrr.startWith("_")) { return false; } retrun (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) { lat handler = { apply: function(target, context, args) { console.log(target, context, args) return args[0]; }, construct: function(target, args) { return {value: args[1]}; } } }; let p = new Proxy(fn, handler); console.log(p(1, 2)) //1 console.log(new p(1, 2)) //{value: 2}

浙公网安备 33010602011771号