一、新增數據類型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={width: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}