【前端18_JS】ES 6:箭頭函數、處理錯誤、數據結構 Set、WeakSet、數據類型 Symbol、魔術字符


箭頭函數

參數

  • 最簡單的箭頭函數:一個形參可以不用括號
	var f = v => v;
    console.log(f(1));
    //1

	//這就等同於
	var f = function (v) {
        console.log(v)
    };
    f();
  • 函數如果沒有形參,需要加括號
    var f1 = () => 5;
    console.log(f1());
    //5
  • 多參數也需要加括號
    var f2 = (a,b) => a + b;
    console.log(f2(3,4));
    //7

用法 & 問題

  • 箭頭函數不能直接返回對象,他會當作代碼塊去處理,解決方法:在對象外 套上圓括號 即可
	//不能直接返回對象 
	//解決:在對象外加 ()
    var f3 = hi => ({name:"小強",age:18});
    console.log(f3(1));
    //{name: "小強", age: 18}
  • 函數如果沒有返回值,打印的是 undefined
	let {log:l} = console;
	var f4 = () => {};
    l(f4());
    //undefined
  • 把很多實參捏到一起,變成真正的數組,用 ...arr ,也叫做 rest
	let {log:l} = console;
	var f5 = (...arr) => arr;
    l(f5(1,2,'33',4,"5"));
    //(5) [1, 2, "33", 4, "5"]
  • map 映射結合,把數組中的每一項都加1
	let {log:l} = console;
    var arr_map = [1,2,3,4].map(items => items + 1);
    l(arr_map);
    //(4) [2, 3, 4, 5]
  • sort 結合,進行從小到大排序
	var arr_sort = [100,5,74,998].sort((a,b) => a-b);
    l(arr_sort);
    //(4) [5, 74, 100, 998]

與 this 的聯繫

用了箭頭函數,那麼 this 指向的就是對象,而不是誰調用就指誰了

	//看這個例子
	function f8() {
        setTimeout(function () {
            console.log(this)
        },1000)
    }
    function f8_jiantou() {
        setTimeout( () => {
            console.log(this)
        },4000)
        //當定時器的函數體擴回後,定時器又重新是windows的了
        //當定時器的函數體擴回前,定時器是一直指向obj_f8的
    }

    var obj_f8 = {
        name:"f8Name"
    };
    f8.call(obj_f8);
    //Window {parent: Window, postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, …}
    
    //這裏把 obj_f8 的指針給了f8_jiantou,那麼定時器裏的this 就指向obj_f8
    f8_jiantou.call(obj_f8);
    //{name: "f8Name"}

再來一個例子慢慢理解一下

	function foo () {
        return () => {
            return () =>{
                console.log(this.id);
            }
        }
    }
    var foo1 = foo.call({id:"一"});
    console.log(foo1);
    /*() => {
            return () =>{
                console.log(this.id);
            }
        }*/

    var foo2 = fun1.call({id:"二"});
    console.log(foo2);
    /*() =>{
                console.log(this.id);
            }*/

    foo2();
    //一

缺點

  • 不能使用箭頭函數實例化對象了
	var F = () =>{

    };
    var f = new F;
    f();
    //Uncaught TypeError: F is not a constructor
  • 不能用 arguments 獲取傳來的參數了
	/*3.不能使用arguments*/
    var fun3 = () => {
        console.log(arguments);
    };
    fun3(123);
    //Uncaught ReferenceError: arguments is not defined

處理錯誤

  • 一般由 trycatchfinallythrow 幾個構成
  • try:嘗試執行代碼,這裏遇到的第一個錯誤會帶到 catch
  • catch:處理錯誤,可以把錯誤吞併掉,從而避免卡住瀏覽器
  • finally:無論 try 中出錯與否,都會執行
  • throw:拋屍,比方說 throw new error("你輸錯了");
<body>
    <h3>請輸入6~100</h3>
    <input type="text" id="inp">
    <button id="btn">這是一個測試</button>
</body>

<script>
    var btn = document.querySelector("#btn");
    var inp = document.querySelector("#inp");
    //嘗試執行代碼
    btn.onclick = function () {
        try{
            if(inp.value < 6){
                throw new error("你輸錯了");
            }
        }catch (err) {
            //try裏遇到第一個錯誤之後會攜帶錯誤信息跳到catch裏
            //會把error喫掉,不會卡住瀏覽器,會繼續渲染
            console.log(err);
            //處理錯誤
            inp.value = '';
        }finally {
            //不管有沒有錯誤都要執行
            console.log("喫瓜羣衆")
        }
    }
</script>

數據結構:set

這個數據結構的特點是:元素不會重複
它沒有下標,沒有所謂的 length 長度

規則

  • 重複元素的判斷跟 === 差不多,不同的是 NaN,如果有兩個 NaN,他會認成一個,也就是書面一樣
	let set = new Set([NaN,NaN]);
    console.log(set);
    //Set(1) {NaN}
	let set = new Set([0,-0]);
    console.log(set);
    //Set(1) {0}
	let set = new Set([1,"1"]);
    console.log(set);
    //Set(2) {1, "1"}

長度

  • set.size
	let set = new Set([1,1,1,2,2,3,3,3,4,5,6,"5",NaN,NaN]);
    console.log(set.size);
    //8
    
    console.log(set.length);
    //undefined

增加元素

  • set.add()
	let set = new Set([]);
    set.add("8848鈦金手機");
    console.log(set);
    //Set(1) {"8848鈦金手機"}

刪元素

  • set.delete() 刪除元素,返回布爾值,表示成功與否
	let set = new Set(["8848鈦金手機"]);
    console.log(set);
    //Set(1) {"8848鈦金手機"}

    set.delete("8848鈦金手機");
    console.log(set);
    //Set(0) {}

查找元素

  • set.has(""); 查找元素,返回布爾值表示,true 爲存在
	let set = new Set(["8848鈦金手機"]);

    console.log(set.has("8848鈦金手機"));;
    //true

遍歷

遍歷可以用如下的方法

  • Array.from(set)
  • 結構解析[...set]
  • forEach 循環
	var set1 = new Set([1,2,3,4,3,2,1])
    /*只要有遍歷器接口的都可以用forOf遍歷*/
    console.log(Array.from(set1));
    //(4) [1, 2, 3, 4]
    
    console.log([...set1]);
    //(4) [1, 2, 3, 4]
	let set = new Set(["甲","乙","丙","丁"]);
    set.forEach((item) => console.log(item));
    //甲
    //乙
    //丙
    //丁

清空

  • set.clear(); 來清空
	let set = new Set(["8848鈦金手機"]);
    console.log(set);
    //Set(1) {"8848鈦金手機"}
    
    set.clear();
    console.log(set);
    //Set(0) {}

曲線救國實現 map 方法

	var set = new Set([1,1,2,2,3,3,4,4,5,5]);
    //先把set結構解析成數組,然後用數組的map
    var map = new Set([...set].map(item => item + 10));
    console.log(map);
    //Set(5) {11, 12, 13, 14, 15}

數組去重

用 set 的特性啊,沒有重複的元素
想得到麼小夥子

	console.log([...new Set([1,2,3,1,2,3,1,2,3,1,2,3])]);
    //(3) [1, 2, 3]

求兩個 set 元素的交集

關鍵,用過濾器 filter,他會保留返回值是 true

	let set1 = new Set([1,2,3,4,5,9]);
    let set2 = new Set([1,2,5,6,7,8,9,]);
    let result_jiaoji = [...set1].filter(items => set2.has(items));
    console.log(result_jiaoji);
    //(4) [1, 2, 5, 9]

WeakSet

  • 只能添加 Object 的 set
  • WeakSet 不允許被循環
  • WeakSet 裏面放節點-防止內存泄露-JC
	var weakset = new WeakSet();
    var set = new Set([1]);
    var obj = {
        name:'1'
    };
    //添加一個對象
    weakset.add(obj);
    console.log(weakset);
    //WeakSet {{…}}
	
	//如果想要添加一個數字,他會報錯
    weakset.add(1);
    //Uncaught TypeError: Invalid value used in weak set
  • 如果想添加個數組
	var weakset = new WeakSet();
    weakset.add([[1,2],[1,2]]);
    console.log(weakset);
    //WeakSet {Array(2)}

數據類型 Symbol

ES 6 中又新添加了個數據類型

  • 他的值 獨一無二
	let s1 = Symbol("這裏是描述s1");
    let s2 = Symbol("這裏是描述s2");

    console.log((s1 == s2));
    //false

    console.log((typeof s1));
    //symbol

    //console.log(s1 + "1");
    //Uncaught TypeError: Cannot convert a Symbol value to a string
    //不能隱式轉換,能顯示轉換

    console.log((s1.toString() + '1'));
    //Symbol(這裏是描述s1)1
  • 建議放在對象中做屬性名(因爲它的特性–永遠不會重複)
	let s1 = Symbol();
    let s2 = Symbol();
    const obj = {
        [s1]:"string1",
        [s2]:"string2"
    };
    console.log(obj[s1]);
    //string1
    
    console.log(obj[s2]);
    //string2
  • Object.keys() 是拿不出來 Symbol 的,根據這個特性,可以僞裝成私有屬性,for in 循環更是白扯,啥都不輸出
	let s1 = Symbol();
    let s2 = Symbol();
    const obj = {
        [s1]:"string1",
        [s2]:"string2"
    };
    for (let x in obj){
        console.log(x);
        //沒用,啥都不輸出
    }
    console.log(Object.keys(obj));
    //(2) [Symbol(), Symbol()]

取值

它有自己的方法 Object.getOwnPropertySymbols(obj)

	let s1 = Symbol();
    let s2 = Symbol();
    const obj = {
        [s1]:"string1",
        [s2]:"string2"
    };

    //這個可以拿出來以Symbol爲key的
    console.log(obj[Object.getOwnPropertySymbols(obj)[0]]);
    //string1

Symbol.for()

Q:有人就想問,Symbol 既然是獨一無二的,真的就不能重用麼?

引進新的方法:Symbol.for(); 只要描述相同的話,那麼他倆就是相同的

	let a = Symbol("a");

    //重用,第一個Symbol.for("b")相當於註冊
    let b = Symbol.for("b");
    //之後Symbol.for("b")是尋找,並且把b的指針給c
    let c = Symbol.for("b");

    console.log((a == b));
    //false

    console.log((b == c));
    //true

取 ‘ 描述 ’

  • symbol.description 可以拿出屬性
  • Symbol.keyFor(b) 只能拿出 Symbol.for("") 設定的屬性
	let a = Symbol("a");
    let b = Symbol.for("b");
    let c = Symbol.for("b");

    console.log(a.description);
    //a

    console.log(b.description);
    //b

    //主要拿Symbol.for的description的
    console.log(Symbol.keyFor(b));
    //b

    console.log(Symbol.keyFor(a));
    //undefined

魔術字符

就是出現頻率賊 JB 高,改起來賊 JB 費勁,一改就要改一大堆的的字符串就叫做魔術字符

官方說法:我們把 耦合性極強,複用性極差,出現頻率極高 的字符串成爲魔術字符

	//例子
	//這裏的字符串	'6'	  就稱之爲魔術字符
	//這是判斷語句少的情況,多了的話改起來就費勁了
	function test(mon) {
        if(mon == "6"){

        }else if(mon > "6"){

        }else if(mon < "6"){

        }
    }

那解決的方法蠻多的,用個變量代替它不就好了。要改的話,就改變量的值就好了

	//這樣改唄
	const obj = {
        key:"value"
    };
    function test(mon) {
        if(mon == obj.key){

        }else if(mon > obj.key){

        }else if(mon < obj.key){

        }
    }

深入理解 Object 和 Map

Object

  • 對象結構來源於:hash 結構
  • 對象的 key 是會自動 toString
  • string - value 的組合

Map

  • map 的 key 值沒有 toString,很自由,想放什麼放什麼
  • value - value 的組合
	const map = new Map();
    map.set({name:1},2);
    console.log(map.get({name:1}));
    //undefined
    
    //這裏的undefined是因爲 
    //map.get({name:1}) 中,又新建了一個{name:1}
    //這個跟set裏的對象,雖然內容一樣,但是指針不同
	//相當於
	var obj_kong = {};
    console.log((obj_kong == {}));
    //false
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章