1. ES6提供了默認參數值機制,允許你為參數設置默認值,防止在函數被調用時沒有傳入這些參數:
const required = () => {throw new Error('Missing parameter')}; const add = (a = required(), b = required()) => a + b;
add(1, 2) //3 add(1) // Error: Missing parameter.
2,變量的解構賦值
2-1.數組的解構賦值:左邊和等號右邊的形式要統一,如果不統一解構將失敗。
let [a,b,c]=[1,2,3]; let [a,[b,c],d]=[1,[2,3],4];
// 解構賦值是允許你使用默認值的
let [foo = true] =[];
console.log(foo); //控制台打印出true
let [a,b="name"]=['小明']
console.log(a+b); //控制台顯示“小明name”
null相當於有值,但值為null.undefined相當於什么都沒有,如果值不對應就會報undefined
let [a,b="name"]=['小明',null];
console.log(a+b); //控制台顯示“小明null”
2-2. 對象的解構賦值
let {foo,bar} = {foo:'Hello',bar:'World'}; console.log(foo+" "+bar); // Hello World // 如果在解構之前就定義了變量,要在解構的語句外邊加一個圓括號 let foo; ({foo} ={foo:'Hello'}); console.log(foo); // Hello
2-3. 字符串解構
const [a,b,c,d,e]="Hello"; console.log(a); //H
3,對象方法屬性可以簡寫
const o = {
method(){
return "Hello!";
}
};
// 等同於
const o = {
method: function() {
return "Hello!";
}
}
5, 動態寫key名
let keys= 'foo'; let obj = { [keys]: true, ['a' + 'bc']: 123}; console.log(obj.foo) //true console.log(obj.abc) //123
6. 擴展運算符和rest運算符
對象擴展運算符(…)。它們可以很好的為我們解決參數和對象數組未知情況下的編程
function argment(...arg){ console.log(arg[0]); console.log(arg[1]); console.log(arg[2]); console.log(arg[3]); } argment(1,2,3); // 1,2,3,undefined
7. 數組賦值,擴展運算符
let arr1=['a','b','c']; let arr2=arr1; console.log(arr2); //['a','b','c'] arr2.push('d'); console.log(arr1); //['a','b','c','d'] console.log(arr2); //['a','b','c','d'] //聲明兩個數組arr1和arr2,然后我們把arr1賦值給arr2,然后我們改變arr2的值,你會發現arr1的值也改變了,因為我們這是對內存堆棧的引用,而不是真正的賦值 let arr1=['a','b','c']; let arr2=[...arr1]; // 也可合並多個[...arr1, ...arr2, ...arr3]
console.log(arr2); //['a','b','c'] arr2.push('d'); console.log(arr2); //['a','b','c','d'] console.log(arr1); //['a','b','c'] // 現在控制台預覽時,arr1並沒有改變
引用數據類型--名存在棧內存中,值存在於堆內存中,但是棧內存會提供一個引用的地址指向堆內存中的值
淺拷貝只是改變棧內存指向,深拷貝改變堆值,新開辟棧JSON.parse(JSON.stringify())可以深拷貝,Jquery 的extend,或者遞歸
$.extend( [deep], target, object1 [, objectN ] )
deep表示是否深拷貝,為true為深拷貝,為false,則為淺拷貝
target Object類型 目標對象,其他對象的成員屬性將被附加到該對象上。
object1 objectN可選。 Object類型 第一個以及第N個被合並的對象。
contact, slice都不是真正意義的深拷貝
8. 循環輸出rest參數和擴展運算符
function loopFun1(...arg){
for(let val of arg){ console.log(val);
} }
function loopFun(reset1,...arg){ console.log(arg);
// console.log(arg.length); }
loopFun1(1,2,3); //1,2,3
loopFun(1,2,3); //[2,3]
let [a,b,..c]= [1,2,3,4,5]
console.log(a) // [1]
console.log(b) // [2]
console.log(c) // [3,4,5]
9,字符串模版
let a='alice';
document.write( `I am ${a} ${1+2} age`); //I am alice 3 age
10. ES6數字操作
Binary,二進制的開始是0(零),然后第二個位置是b(注意這里大小寫都可以實現)
let binary = 0B010101;
console.log(binary); //21
八進制的英文單詞是Octal,也是以0(零)開始的,然后第二個位置是O(歐),然后跟上八進制的值就可以了。
let b=0o666;
console.log(b); //438
數字驗證Number.isFinite( xx )
可以使用Number.isFinite( )來進行數字驗證,只要是數字,不論是浮點型還是整形都會返回true,其他時候會返回false。
let a= 11/4; console.log(Number.isFinite(a));//true console.log(Number.isFinite('Hello'));//false console.log(Number.isFinite(NaN));//false console.log(Number.isFinite(undefined));//false NaN是特殊的非數字,可以使用Number.isNaN()來進行驗證。 console.log(Number.isNaN(NaN));//true
判斷是否為整數Number.isInteger(xx)
let a=123.1; console.log(Number.isInteger(a)); //false
整數轉換Number.parseInt(xxx)和浮點型轉換Number.parseFloat(xxx)
let a='9.18'; console.log(Number.parseInt(a)); //9 console.log(Number.parseFloat(a)); //9.18
最大安全整數
console .log(Number.MAX_SAFE_INTEGER); Math.pow(2,53)-1;
最小安全整數
console.log(Number.MIN_SAFE_INTEGER);
安全整數判斷isSafeInteger( )
let a= Math.pow(2,53)-1; console.log(Number.isSafeInteger(a));//false
11.es6新特性
11-1, JSON數組格式轉換(key為數組序號)
let json = { '0': 'I', '2': 'LOVE', '1': 'YOU', length:3 } let arr=Array.from(json); console.log(arr) // ["I", "YOU", "LOVE"]
Object.keys(json) //["0", "1", "2", "length"] 獲取對象key值
Object.keys(json).map(key=>({
key,
value: json[key]
}))
11-2, Array.of()方法:(它負責把一堆文本或者變量轉換成數組類似eval)
let arr =Array.of(3,4,5,6); console.log(arr); //[3, 4, 5, 6]
11-3, find( )實例方法:
所謂的實例方法就是並不是以Array對象開始的,而是必須有一個已經存在的數組,然后使用的方法,這就是實例方法。這里的find方法是從數組中查找。在find方法中我們需要傳入一個匿名函數,函數需要傳入三個參數:
value:表示當前查找的值。
index:表示當前查找的數組索引。
arr:表示當前數組。
let arr=[1,2,3,4,5,6,7,8,9]; console.log(arr.find(function(value,index,arr){ return value > 5; })) // 6
11-4, fill( )實例方法:
fill()也是一個實例方法,它的作用是把數組進行填充,它接收三個參數,第一個參數是填充的變量,第二個是開始填充的位置,第三個是填充到的位置。
let arr=[0,1,2,3,4,5,6,7,8,9]; arr.fill('a',2,5); console.log(arr); //[0, 1, "a", "a", "a", 5, 6, 7, 8, 9]
11-5, for...in和for...of區別
for...in
1.循環出來的是index索引,是字符串型的數字;2.遍歷順序有可能不是按照實際數組的內部順序;
3.使用for in會遍歷數組所有的可枚舉屬性,包括原型上的以及數組自定義的屬性;
所以for in更適合遍歷對象,不要使用for in遍歷數組。,在遍歷數組的時候的時候使用for...of;
for...in循環出的是key,for...of循環出的是value;
注意,for...of是ES6新引入的特性。修復了ES5引入的for...in的不足;
for...of不能循環普通的對象,需要通過和Object.keys()搭配使用;
Object.prototype.objCustom = function () {};
Array.prototype.arrCustom = function () {}; let iterable = [3, 5, 7]; iterable.foo = "hello"; //數組中key為數字 for (let i in iterable) { console.log(i); // 0, 1, 2, "foo", "arrCustom", "objCustom" } for (let i of iterable) { console.log(i); // 3, 5, 7 }
11-6,同時輸出數組的內容和索引:我們用entries()這個實例方法,配合我們的for…of循環就可以同時輸出內容和索引了
let arr=['a','b','c'] for (let [index,val] of arr.entries()){ console.log(index+':'+val); //0:a 1:b 2:c
}
11-7, entries( )實例方法:
entries()實例方式生成的是Iterator形式的數組,那這種形式的好處就是可以讓我們在需要時用next()手動跳轉到下一個值。我們來看下面的代碼:
let arr=['a','b','c'] let list=arr.entries(); console.log(list.next().value); //[0, "a"] console.log(list.next().value); //[1, "b"] console.log(list.next().value); //[2, "c"]
12. 函數解構
12-1,對象的函數解構
let json = { a:'1', b:'2' } function fun({a,b='1'}){ console.log(a,b); } fun(json); //1 2
12-2, 數組的函數解構
let arr = ['a','b','c']; function fun(a,b,c){ console.log(a,b,c); } fun(...arr); //a,b,c
13. in 是用來判斷對象或者數組中是否存在某個值的
let obj={ a:'1', b:'2' } console.log('a' in obj); //true console.log(0 in arr1); //如果是數組則為索引 // 遍歷 let arr=['a','b','c']; console.log(arr.map(x=>'d')); // d,d,d arr.some(x=>console.log(x)); //a,b,c arr.filter(x=>console.log(x));// a,b,c
14 Object.is( ) 對象比較
console.log(+0 === -0); //true
console.log(NaN === NaN ); //false
console.log(Object.is(+0,-0)); //false
console.log(Object.is(NaN,NaN)); //true
===為同值相等,is()為嚴格相等。
15. Object.assign( )合並對象
//way1 var a={a:'1'}; var b={b:'2'}; var c={c:'3'}; let d=Object.assign(a,b,c) console.log(d); //{a: "1", b: "2", c: "3"} //way2 const person = { a:1 }; const tools = { b:2 }; const attributes = { c:3 }; const summary = {...person, ...tools, ...attributes}; // {a:1,b:2,c:3}
16.聲明Symbol
var a = new String;
var b = new Number;
var c = new Boolean;
var d = new Array;
var e = new Object;
var f= Symbol();
console.log(typeof(d));
17.Symbol對象元素(key)的保護作用
let obj={name:'hw',skill:'angry'}; let age=Symbol(); obj[age]=18; for (let item in obj){ console.log(obj[item]); //hw angry } console.log(obj) //{name: "hw", skill: "angry", Symbol(): 18}
18:Set和WeakSet數據結構(Set的數據結構是以數組的形式構建的)
Set和Array 的區別是Set不允許內部有重復的值,如果有只顯示一個,相當於去重。雖然Set很像數組,但是他不是數組。
Set的聲明:
let setArr = new Set(['a','b','c','a']); console.log(setArr);//Set {"a", "b", "c"}
追加add:
setArr.add('d'); //Set {"a", "b", "c", "d"}
刪除delete:
用has進行值的查找,返回的是true或者false。
.size相當與length
setArr.clear() //清空
for (let item of setArr){ //循環 console.log(item); } setArr.forEach((value)=>console.log(value));
WeakSet的聲明(弱)
let weakObj=new WeakSet(); let obj={a:'aa',b:'bb'} weakObj.add(obj); console.log(weakObj);
(總結:在實際開發中Set用的比較多,WeakSet用的並不多,但是他對傳入值必須是對象作了很好的判斷,我們靈活應用還是有一定的用處的。)
19,map數據結構
Map的靈活性要更好,你可以把它看成一種特殊的鍵值對,但你的key可以設置成數組,值也可以設置成字符串,讓它不規律對應起來。
let json = { name:'hw', skill:'angry' } var map=new Map(); map.set(json,'iam'); console.log(map); //當然也可key字符串,value是對象 console.log(map.get(json)); //取值get -->iam map.delete(json); //刪除delete console.log(map.size); //0 console .log(map.has('a')) //false map.clear()
20. 用Proxy進行預處理
聲明Proxy
new Proxy({},{}); var pro = new Proxy({ add: function (val) { return val + 10; }, name: 'I am hw' }, { get:function(target,key,property){ console.log('come in Get'); return target[key]; } }); console.log(pro.name); //先輸出了come in Get。相當於在方法調用前的鈎子函數31
20-1. get屬性
get屬性是在你得到某對象屬性值時預處理的方法,他接受三個參數
target:得到的目標值
key:目標的key值,相當於對象的屬性
property:這個不太常用,用法還在研究中,還請大神指教。
20-2. set屬性
set屬性是值你要改變Proxy屬性值時,進行的預先處理。它接收四個參數。
target:目標值。
key:目標的Key值。
value:要改變的值。
receiver:改變前的原始值。
var pro = new Proxy({ add: function (val) { return val + 10; }, name: 'I am hw' }, { get:function(target,key){ console.log('come in Get'); return target[key]; }, set:function(target,key,value,receiver){ console.log(` setting ${key} = ${value}`); return target[key] = value; } }); console.log(pro.name); pro.name='qc'; console.log(pro.name);
21. function test(fruit = '默認值') {
// 改寫多個||判斷
const redFruits = ['apple', 'strawberry', 'cherry', 'cranberries']; if (redFruits.includes(fruit)) { console.log('red'); } }
22. 數組去重
console.log(new Set([1, 2, 3, 3])); >> [1,2,3]
過濾空值:空值指的是沒有具體意義的一些值,比如0,undefined,null,false,空字符串等
let res = [1,2,0,undefined,null,false,''].filter(Boolean); >> 1,2
const isRequired = () => { throw new Error('param is required'); }; const hello = (name = isRequired()) => { console.log(`hello ${name}`) }; // 拋出一個錯誤,因為參數沒有傳 hello(); // 沒有問題 hello('hello')
1,在B.js中export default xxx ,A.js中可以import ’ 隨意名,不加大括號 ’ from 'B.js' 。
如果B.js 為單個方法export Funame1, 那么A.js中必須 import {Funname1, Funame2} from B.js不可隨意命名
ps: 一個模塊中只能有一個默認導出export default
,但是卻可以有任意命名導出(0個、1個、多個)
導出方式1,export const A ='a',2,const A = 'a'; export { A as myA } //可以用as對導入、導出模塊重命名(myA) 。導出接口的值是動態綁定的
導入變量為只讀,不可修改。但導入變量屬性能更改,但其他模塊引用也會造成更改。如果導入模塊不帶路徑又要配置文件說明。
導入方式2,整體加載發 import * as AB from './ab' 。調用:AB.A; AB.b 。(*表示所有重命名加載到對象AB上,然后調用AB下面的方法)
23. promise使用
var promise = new Promise((resolve, reject) => {/* fn 匿名函數 */
// ... some code
if (/* 異步操作成功 */){
resolve(value);
} else {
reject(error);
}
});
//bad
promise.then((value) => {//success}, (error) => {//failure})
//good
Promise.then((data) => { /* success */ }).catch((err) => {/* error */ });
//一般來說,不要在then方法里面定義Reject狀態的回調函數(即then的第二個參數),總是使用catch方法
//一但fn執行完,會立即出發then回調
promise充當異步與回調之間的中介,每一個異步任務立刻返回一個Promise對象。
resolve函數的作用是,將Promise對象的狀態從“未完成”變為“成功”(即從Pending變為Resolved),在異步操作成功時調用,並將異步操作的結果,作為參數傳遞出去;
reject函數的作用是,將Promise對象的狀態從“未完成”變為“失敗”(即從Pending變為Rejected),在異步操作失敗時調用,並將異步操作報出的錯誤,作為參數傳遞出去。
then 回調動作的觸發時機是 promise 被執行完。我們還可以串聯 then 方法執行回調操作,每次 then 調用都會以之前的 then 調用的返回值為參數。
function timeout(ms) { return new Promise((resolve, reject) => { console.log(1) setTimeout(resolve, ms, '4'); //setTimeout(fn, milliseconds, param1, param2, ...) param1,param2是傳給fn的實參 console.log(2) }); } timeout(2000).then((value) => { console.log(value); //done }); function fn(){ console.log(3) } fn()
//Promise對象在創建后立即執行,then方法指定的回調函數,將在當前腳本所有同步任務執行完才會執行。
var p1 = Promise.resolve(value); // 等價於 var p1 = new Promise(resolve => resolve(value)); var p2 = Promise.reject('err'); // 等同於 var p2 = new Promise((resolve, reject) => reject('err'));
參數擴展 1,function fun (a,b, ...arg){} //arg = 3,4,5收起來 fun(1,2,3,4,5) 2,arr=[...arr1,...arr2]合並展開 //數組方法: let arr = [1,2,3] let arr1 = [[1],[2],[3]] let arr3 = [({price:10,count:2},{price:5,count:4}] //更新 console.log(arr.map((item, index, arr) => item* 2 )) //[2,4,6]更新數組 console.log(arr.reduce((pre, next, index, arr) => pre+ next)) //6 console.log(arr1.reduce((pre, next, index) => pre.concat(next))//扁平化二維數組 console.log(arr3,reduce((pre,next, index)=>{return pre+next.price*next.count;},0))//對象疊加計算,原數組第一項添加為0 //過濾 console.log(arr.filter((item, index, arr) => item>1&&item<5)) //2,3 console.log(arr.find(item, index, arr) => item>1&&item<5) //2當遍歷循環到判斷到一個為true則跳出循環,輸出當前數組元素 console.log(arr.findIndex((item,index)=>{ return item>1&&item<5})) //1 索引 //判斷 console.log(arr.includes(1)) //true console.log(arr.some(x=>{return x>1})) //true一個滿足則為true所有不滿足為false即 並集 console.log(arr.every(x=>{return x>1})) //false所有滿足為true,一個不滿足則為false即交集