1. 程式人生 > 實用技巧 >ES6常用總結(一)

ES6常用總結(一)

let,const

  • let宣告變數,const宣告常量,兩者均為塊級作用域
  • let,const在塊級作用域內不允許重複宣告
  • const宣告的基本資料型別不可以修改,引用資料型別可以修改。具體看我的另一篇文章
  • let不會存在變數提升,var會存在變數提升
console.log(a);
var a=1;
// undefined
console.log(b);
let b=1;
// 會報錯
      
// 這是應為var宣告會提升,實際上var a是在console前的,所以會undefined,而let會直接報錯

解構賦值

  • 對應賦值
let {a, b} = {a:1, b:2};  // a => 1 , b => 2
// 交換賦值
let [a,b] = [b,a];
 // 提取json資料
let json = {
      name : 'leo',
      age: 18
}
let {name, age} = json;
console.log(name,age); // leo, 18
// 遍歷Map結構
const m = new Map();
m.set('a',1);
m.set('b',2);
for (let [k, v] of m){
      console.log(k + ' : ' + v);
}
// 用於按需載入模組中需要用到的方法。
const {log, sin, cos} = require('math');

字串拓展

  • includes('str’,index):返回布林值,表示是否找到引數字串。
  • startsWith('str’,index):返回布林值,表示引數字串是否在原字串的頭部。
  • endsWith('str’,index):返回布林值,表示引數字串是否在原字串的尾部。
  • repeat(number):表示重複幾遍

模板字串

  • 在模板字串中用${}包裹變數
let a = `abc${v1}def`

字串的正則方法

  • match()、replace()、search()和split()

數值

  • Number.isFinite(), Number.isNaN()
  • Number.parseInt(), Number.parseFloat()
  • Number.isInteger()
  • Math.trunc:用來去除小數的小數部分,返回整數部分;若引數為非數值,則先轉為數值;若引數為空值或無法擷取整數的值,則返回NaN。
  • Math.sign(): 判斷一個數是正數、負數還是零,對於非數值,會先轉成數值。
  • Math.cbrt():用來計算一個數的立方根,若引數為非數值則先轉成數值。
  • Math.clz32():用於返回一個數的 32 位無符號整數形式有多少個前導 0。
  • Math.imul(): 用於返回兩個數以 32 位帶符號整數形式相乘的結果,返回的也是一個 32 位的帶符號整數。
  • Math.fround():用來返回一個數的2位單精度浮點數形式。
  • Math.hypot():用來返回所有引數的平方和的平方根
  • Math.expm1(): 用來返回ex - 1,即Math.exp(x) - 1。
  • Math.log1p(): 用來返回1 + x的自然對數,即Math.log(1 + x)。如果x小於-1,返回NaN。
  • Math.log10(): 用來返回以 10為底的x的對數。如果x小於 0,則返回 NaN。
  • Math.log2(): 用來返回以 2 為底的x的對數。如果x小於0,則返回 NaN。

函式

  • 引數新增預設值
function f(a, b='leo'){
    console.log(a, b);
}

f('hi');          // hi leo
f('hi', 'jack');  // hi jack
f('hi', '');      // hi leo

箭頭函式

  • this指向定義時的物件本身(可深研究下)
  • 不存在arguments物件,即不能使用,可以使用rest引數代替
  • 不能使用yield命令,即不能用作Generator函式
  • 不能當做建構函式,即不能用new命令,否則報錯
()=>{}

陣列

  • ...拓展符:一個連線陣列的作用;可以實現深拷貝
let a = [1, 2, 3];
let b = [4, 5, 6];
console.log([...a, ...b]);//[1,2,3,4,5,6]
  • Array.from():將 類陣列物件 和 可遍歷的物件,轉換成真正的陣列。用法
  • Array.of():將一組數值,轉換成陣列,彌補Array方法引數不同導致的差異。(Array.of(1,2,3); // [1,2,3])
  • find()和findIndex()
  • fill():用於用指定值填充一個數組,通常用來初始化空陣列,並抹去陣列中已有的元素。
  • includes():表示陣列是否包含給定的值,與字串的includes方法類似。indexOf返回-1,includes返回true或false
  • entries(),keys(),values(), flat(),flatMap()

物件

  • 簡潔表示
let a = 'a1';
let b = { a };  // b => { a : 'a1' }
// 等同於
let b = { a : a };
  • Object.is():用於比較兩個物件是否相等,'' 或者 '='會將值自動轉化為數值,object.is()彌補這個缺憾
Object.is('a','a');   // true
Object.is({}, {});    // false
  • Object.assign():物件的合併,類似陣列的連線,同屬性名後者會覆蓋前者,淺拷貝

Symbol

  • 新的原始資料型別,表示獨一無二的值,主要是為了防止屬性名衝突。
  • JavaScript一共有其中資料型別:Symbol、undefined、null、Boolean、String、Number、Object。
  • 作為新型別,有很多用法,此處省略,自行探討。
// 沒有引數
let a1 = Symbol();
let a2 = Symbol();
a1 === a2; // false 

// 有引數
let a1 = Symbol('abc');
let a2 = Symbol('abc');
a1 === a2; // false 

陣列set用法

  • 資料結構類似陣列,所有成員數值唯一
// add方法來新增新成員。
let a = new Set();
[1,2,2,1,3,4,5,4,5].forEach(x=>a.add(x));
for(let k of a){
    console.log(k)
};

// 基礎使用
let a = new Set([1,2,3,3,4]);
[...a]; // [1,2,3,4]
a.size; // 4

// 陣列去重
[...new Set([1,2,3,4,4,4])];// [1,2,3,4]

//增刪改查
let a = new Set();
a.add(1).add(2); // a => Set(2) {1, 2}
a.has(2);        // true
a.has(3);        // false
a.delete(2);     // true  a => Set(1) {1}
a.clear();       // a => Set(0) {}

// 資料型別不會轉換
[...new Set([5,'5'])]; // [5, "5"]

// 遍歷和過濾
let a = new Set([1,2,3,4]);

// map 遍歷操作
let b = new Set([...a].map(x =>x*2));// b => Set(4) {2,4,6,8}

// filter 過濾操作
let c = new Set([...a].filter(x =>(x%2) == 0)); // b => Set(2) {2,4}

// 獲取交集  並集  差集
let a = new Set([1,2,3]);
let b = new Set([4,3,2]);

// 並集
let c1 = new Set([...a, ...b]);  // Set {1,2,3,4}

// 交集
let c2 = new Set([...a].filter(x => b.has(x))); // set {2,3}

// 差集
let c3 = new Set([...a].filter(x => !b.has(x))); // set {1}

map方法

  • 由於傳統的JavaScript物件只能用字串當做鍵,給開發帶來很大限制,ES6增加Map資料結構,使得各種型別的值(包括物件)都可以作為鍵。Map結構提供了“值—值”的對應,是一種更完善的 Hash 結構實現。
  • 基礎使用
let a = new Map();
let b = {name: 'leo' };
a.set(b,'my name'); // 新增值
a.get(b);           // 獲取值
a.size;      // 獲取總數
a.has(b);    // 查詢是否存在
a.delete(b); // 刪除一個值
a.clear();   // 清空所有成員 無返回
  • map轉陣列
let a = new Map([
    ['name','leo'],
    ['age',18]
])

let a1 = [...a.keys()];   // a1 => ["name", "age"]
let a2 = [...a.values()]; // a2 =>  ["leo", 18]
let a3 = [...a.entries()];// a3 => [['name','leo'], ['age',18]]
  • 陣列轉map
let a = [ ['name','leo'], [1, 'hi' ]]
let b = new Map(a);
  • map轉物件
function fun(s) {
  let obj = Object.create(null);
  for (let [k,v] of s) {
    obj[k] = v;
  }
  return obj;
}

const a = new Map().set('yes', true).set('no', false);
fun(a)
  • 物件轉map
function fun(obj) {
  let a = new Map();
  for (let k of Object.keys(obj)) {
    a.set(k, obj[k]);
  }
  return a;
}

fun({yes: true, no: false})
  • Map 轉 JSON
// Map鍵名都是字串,轉為物件JSON:
function fun (s) {
    let obj = Object.create(null);
    for (let [k,v] of s) {
        obj[k] = v;
    }
    return JSON.stringify(obj)
}
let a = new Map().set('yes', true).set('no', false);
fun(a);// '{"yes":true,"no":false}'

// Map鍵名有非字串,轉為陣列JSON:
function fun (map) {
  return JSON.stringify([...map]);
}

let a = new Map().set(true, 7).set({foo: 3}, ['abc']);
fun(a)
// '[[true,7],[{"foo":3},["abc"]]]'
  • JSON 轉 Map
// 所有鍵名都是字串:
function fun (s) {
  let strMap = new Map();
  for (let k of Object.keys(s)) {
    strMap.set(k, s[k]);
  }
  return strMap;
  return JSON.parse(strMap);
}
fun('{"yes": true, "no": false}');// Map {'yes' => true, 'no' => false}
// 整個 JSON 就是一個數組,且每個陣列成員本身,又是一個有兩個成員的陣列:
function fun2(s) {
  return new Map(JSON.parse(s));
}
fun2('[[true,7],[{"foo":3},["abc"]]]')
// Map {true => 7, Object {foo: 3} => ['abc']}

Promise物件

  • 解決非同步程式設計帶來的回撥地獄問題。解決介面一層一層巢狀的問題。
  • 優點:請求成功後任何時間都可以拿到值;事件錯過了就無法新增監聽
  • 缺點:無法得到進行的狀態;錯誤需要新增失敗回撥才能獲知,內部錯誤不會反映到外部。
  • 基本用法
let p = new Promise(function (resolve, reject){
   if(/*非同步操作成功*/){
       resolve(value);
   } else {
       reject(error);
   }
})
// resolve作用是將Promise的狀態從pending變成resolved,在非同步操作成功時呼叫,返回非同步操作的結果,作為引數傳遞出去。
// reject作用是將Promise的狀態從pending變成rejected,在非同步操作失敗時報錯,作為引數傳遞出去。

// demo
const p1 = new Promise(function(resolve, reject) {
      setTimeout(() => resolve(console.log(123)), 3000)
})

const p2 = new Promise(function(resolve, reject) {
      setTimeout(() => resolve(p1), 1000)
})

p2
   .then(result => console.log(result))
   .catch(error => console.log(error))
// 123
// promise接受兩個引數resolve,reject,內部函式成功則觸發resolve,失敗則觸發reject

const p = new Promise(function(resolve, reject) {
  resolve('ok');
  throw new Error('test');
});
p
  .then(function(value) { console.log(value) })   // ok
  .catch(function(error) { console.log(error) });  // 捕獲錯誤
  .finally(() => {···})  // 失敗成功都會執行

const p = Promise.all([p1, p2, p3]);
const p = Promise.race([p1, p2, p3]);
  • 口語化來講這個promise就是個ajax請求語法糖,杜絕了一層套一層的寫法。
  • promise(resolve,reject){請求資料,成功觸發resolve(data),失敗觸發reject(data)}
  • 用then呢是把上一個獲取到的資料當引數傳給下一個promise