【React】JavaScript進階

130 阅读5分钟

1. Basic

1.1 Variable

  • 會改變的,一般用let定義

  • 不會改變的,一般用const定義

1.2 Modify Style

直接用style修改

<script>
    //查詢滿足條件的第一個元素
    let a = document.querySelect(".xxx");
    a.style.width = "300px";
</script>

先定義類樣式,然後用classname綁定這個類

<div class="div_left">
    <h5>新聞</h5>
    <h5>好看</h5>
    <h5>地圖</h5>
    <h5>貼吧</h5>
    <h5>視頻</h5>
    <h5>圖片</h5>
    <h5>網盤</h5>
    <h5>更多</h5>
</div>

<script>
      let h5List = document.querySelectorAll("h5");
      for (let index = 0; index < h5List.length; index++) {
        const element = h5List[index];
        element.addEventListener("mouseenter", function () {
          let a = document.querySelector(".title_color");
          if (a == null) {
            this.className = "title_color";
          } else {
            a.className = "";
            this.className = "title_color";
          }
        });
      }
</script>

用classList動態捆綁類

<script>
      let h5 = document.querySelector("h5");
      //追加
      h5.classList.add("類名");
      //刪除
      h5.classList.remove("類名");
      //切換(有就刪除,沒有就加上)
      h5.classList.toggle("類名");
</script>

1.3 Event Stream

事件流指的是事件完整執行過程中的流動路徑

  • 捕獲:是從大到小
  • 冒泡:是從小到大

图片.png

    <span class="span_click">
      <div class="div_click">
        <button class="text_click">點擊冒泡</button>
      </div>
    </span>

    <script>
        let text = document.querySelector(".text_click");
        text.addEventListener("click", function () {
          window.alert("this is text");
        });
        let div = document.querySelector(".div_click");
        text.addEventListener("click", function () {
          window.alert("this is div");
        });
        let span = document.querySelector(".span_click");
        text.addEventListener("click", function () {
          window.alert("this is span");
        });
    </script>

event.stopPropagation()阻止冒泡和捕獲

    <script>
        let text = document.querySelector(".text_click");
        text.addEventListener("click", function () {
          window.alert("this is text");
        });
        let div = document.querySelector(".div_click");
        text.addEventListener("click", function () {
          window.alert("this is div");
        });
        let span = document.querySelector(".span_click");
        text.addEventListener("click", function (e) {
          window.alert("this is span");
          e.stopPropagation();
        });
    </script>

1.4 Register Event

    let sss = document.querySelect("xxx");
    sss.onClick = function(){}
    
    sss.onClick = null;
    let sss = document.querySelect("xxx");
    sss.addEventListener("click", function (e) {

        console.info(e);

      });
    
    //匿名函數無法移除
    sss.removeEventListener("click",xxxx)

1.5 委託

核心就是把事件寫到父級身上,讓子級的事件通過冒泡,傳遞到父級

    <span>
      <ul>
        <li>第一個漢字</li>
        <li>第一個漢字</li>
        <li>第一個漢字</li>
        <li>第一個漢字</li>
        <li>第一個漢字</li>
      </ul>
    </span>

    const ul = document.querySelector("ul");
    ul.addEventListener("click", function (e) {
      let target = e.target;
      console.info(target);
      target.style.color = "red";
    });

1.6 動態參數和剩餘參數(展開運算符)

arguments可以獲取動態參數

    <script>
        function getInfo() {
          let result = 0;
          for (let index = 0; index < arguments.length; index++) {
            const element = arguments[index];
            result = result + element;
          }
          return result;
        }
        console.info(getInfo(1, 2));
        console.info(getInfo(2, 3, 4));
        console.info(getInfo(2, 3, 4, 5));
  </script>

...表示剩餘參數

 <script>
    function getInfo1(a, ...arr) {
      let result = 0;
      for (let index = 0; index < arr.length; index++) {
        const element = arr[index];
        result = result + element;
      }
      return result;
    }

    console.info(getInfo1(1, 2));
    console.info(getInfo1(2, 3, 4));
    console.info(getInfo1(2, 3, 4, 5, 6));
 </script>

...表示展開運算符

 <script>
    const arr = [1, 2, 3, 4, 5];
    console.log(...arr);
    console.log(Math.max(...arr));
    console.log(Math.min(...arr));
 </script>    

2. ES6

2.1 箭頭函數

箭頭函數就是讓我們的函數代碼更简短,主要替代匿名函數

    </script>
        const fn01 = function () {
          console.info("匿名函數");
        };
        const fn02 = () => {
          console.info("箭頭函數");
        };
        fn01();
        fn02();
   </script>

注意:

  • 只有一個參數的時候,可以省略參數的小括號

  • 只有方法體是一句代碼的時候,可以省略大括號

  • 如果方法體是return,可以省略大括號和return

  • 返回對象const fn = (username) =>({name:username})

  • 傳參使用剩餘參數...arr

2.1.1 Code Demo

參數使用剩餘函數,來求和

  <script>
        const getSum = (...arr) => {
          let sum = 0;
          for (let index = 0; index < arr.length; index++) {
            sum += arr[index];
          }
          return sum;
        };
        console.info(getSum(1, 2));
        console.info(getSum(1, 2, 3));
  </script>

2.1.2 this

常規代碼是誰調用的,這個this就指向誰

箭頭函數無法創建自己的this,它會從作用域鏈的上一層查找

2.1.3 修改this指向

  • call():可以調用函數,可以改變this指向
  <script>
        const obj={
            uname = "nolan"
        }
        function fn ()  {
          console.info(this)
          for (let index = 0; index < arguments.length; index++) {
            const element = arguments[index];
            result = result + element;
          }
        };
        
        //this指向window
        fn();
        //通過call方法修改指向,this變成obj,後面可以傳多個參數,用逗號分開
        fn.call(obj,arg1,arg2...)
  </script>
  • apply():可以調用函數,可以改變this指向,用偽數組保存參數
  <script>
        const obj={
            uname = "nolan"
        }
        function fn ()  {
          console.info(this)
          for (let index = 0; index < arguments.length; index++) {
            const element = arguments[index];
            result = result + element;
          }
        };
        
        //this指向window
        fn();
        //通過apply方法修改指向,this變成obj,後面可以傳多個參數,用逗號分開
        fn.call(obj,[arg1,arg2...])
  </script>
  • bind():不能調用函數,可以改變this指向,返回一個新函數(原函數拷貝)
  <script>
        const obj={
            uname = "nolan"
        }
        function fn ()  {
          console.info(this)
          for (let index = 0; index < arguments.length; index++) {
            const element = arguments[index];
            result = result + element;
          }
        };
        
        //this指向window
        fn();
        //通過bind方法修改指向,this變成obj,後面可以傳多個參數,用逗號分開
        let function = fn.bind(obj,arg1,arg2...)
        function()
  </script>

2.2 解構賦值

2.2.1 數組解構

將數組的單元值快速批量賦值給一系列變量的簡潔語法

  <script>
        //數組解構
        const arr = [50, 60, 80];
        const [min, middle, max] = arr;
        console.info(max, min);

        let a = 1;
        let b = 2;
        [a, b] = [b, a];
        console.info(a, b);
  </script>

2.2.2 對象解構

將對象的屬性和方法快速批量賦值給一系列變量的簡潔語法

  <script>
    const obj = {
      username: "noaln",
      age: 18,
      address: "dongguan",
    };

    const { username, age, address } = obj;
    console.info(username, age, address);
  </script>

如果變量名重複,如何修改

  <script>
    const obj = {
      username: "noaln",
      age: 18,
      address: "dongguan",
    };

    const { username:uname, age, address } = obj;
    console.info(uname, age, address);
  </script>

數組對象

  <script>
        const pig = [
          {
            name: "noaln",
            age: 11,
          }
        ];

        const [{ name, age }] = pig;
        console.info(name, age);
  </script>

2.3 Array對象

array.forEach(function(currentValue, index, arr), thisValue)=>遍歷

array.map(function(currentValue,index,arr), thisValue)=>遍歷

array.filter(function(currentValue,index,arr), thisValue)=>過濾

array.some(function(currentValue,index,arr),thisValue)=>一項滿足,返回true

array.every(function(currentValue,index,arr), thisValue)=>全部滿足,返回true

array.reduce(function(total, currentValue, currentIndex, arr), initialValue)=>累計處理的結果,用於求和

array.find(function(currentValue, index, arr),thisValue)=>返回滿足條件的第一個

  <script>
        const arr = ["1A", "2B", "3C", "4D", "5E"];
        arr.forEach((item, index) => {
          console.info(item);
          console.info(index);
        });
  </script>
  <script>
        //求和,無起始值
        const arr01 = [1, 2, 3, 4, 5, 6];
        let result = arr01.reduce(function (prev, current) {
          return prev + current;
        });
        console.info(result);  => 1+2+3+4+5+6
        
        //求和,有起始值
        const arr01 = [1, 2, 3, 4, 5, 6];
        let result = arr01.reduce(function (prev, current) {
          return prev + current;
        },10);
        console.info(result);  => 1+2+3+4+5+6+10
        
        //最簡板
        arr.reduce((prev,current) => prev + current,10)
  </script>
  <script>
        const obj = [
          {
            username: "noaln",
            salary: 18,
            address: "dongguan",
          },
          {
            username: "noaln01",
            salary: 20,
            address: "dongguan",
          },
          {
            username: "noaln02",
            salary: 25,
            address: "dongguan",
          },
        ];

        let sum = obj.reduce((prev, cur) => {
          return prev + cur.salary;
        }, 0);
        console.log(sum);
  </script>

2.4 Prototype(原型對象)

每一個構造函數都有一個prototype屬性,指向另一個對象,我們也成原型對象

  • 它可以掛載函數,對象實例化不會多次創建原型上的函數,節約內存
  • 可以把不變的方法,定義在prototype對象上,所有對象實例可以共享
  • 構造函數和原型對象中的this都指向實例化的對象
  //構造函數也是函數
  <script>
    function Start(name, age) {
      this.name = name;
      this.age = age;
    }

    Start.prototype.favourite = function () {
      console.info("this is favourite");
    };

    const aaa = new Start("nolan", 10);
    aaa.favourite();
  </script>

2.4.1 自己封裝,擴展

  <script>
        Array.prototype.max = function () {
          return Math.max(...this);
        };
        Array.prototype.mim = function () {
          return Math.min(...this);
        };
        Array.prototype.sum = function () {
          return this.reduce((prev, current) => prev + current, 0);
        };
        
        const arr = [1, 2, 3, 4, 5, 6, 7];
        let result1 = arr.max();
        let result2 = arr.sum();
        console.info(result1);
        console.info(result2);
  </script>

2.4.2 Constructor

每一個構造函數都有原型對象,prototype

每一個原型對象都有Constructor屬性,指向構造函數(爸爸)

  //構造函數也是函數
  <script>
    function Start() {
    }

    const aaa = new Start();
    //之所以實例對象可以直接使用prototype.就是因為有__proto__
    console.info(aaa.__proto__ === Start.prototype//constructor指向爸爸Start
    console.info(aaa.__proto__.constructor === Start)
  </script>

图片.png

2.4.3 原型繼承

  //構造函數也是函數
  <script>
    function Person () {
        this.eays = 2,
        this.head = 1
    }
    
    function Woman(){
    
    }
    //女人能生娃
    Woman.prototype = new Person();
    Woman.prototype.constructor = Woman;
    Woman.prototype.baby = function(){
        console.info("baby);
    }
    const xxx = new Woman();
    console.info(xxx);
    console.info(xxx.eays);
    
    function Man(){
    }
    //男人不能生娃
    Man.prototype = new Person();
    Man.prototype.constructor = Man;

    const xxx = new Man();
    console.info(xxxx);
    console.info(xxxx.eays);
  </script>

3. Advance

3.1 深克隆

www.lodashjs.com/docs/lodash…

  <script>
    var objects = [{ 'a': 1 }, { 'b': 2 }];

    var deep = _.cloneDeep(objects);
    console.log(deep[0] === objects[0]);
  </script>

图片.png

3.2 複製對象

<script>
    let person = {name:"xx",age:18}
    //字面量複製
    let person2 = {...person}
</script>