<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          面向后端的前端技術(shù)分享

          共 6552字,需瀏覽 14分鐘

           ·

          2021-05-16 15:16

          作者:九旬

          來源:SegmentFault 思否社區(qū)


          目的

          • 分享日常開發(fā)工作中常遇到的問題
          • 提升工作效率,編寫易維護(hù)的代碼
          • 了解前端技術(shù)的趨勢

          This

          JS 關(guān)鍵字:指向當(dāng)前環(huán)境的上下文

          1. 事件中的 this

          在 DOM 事件中,this指向當(dāng)前的 DOM 元素對象。
          在 HTML 事件(僅為 addEventListener 添加時(shí)),this 指向了接收事件的 HTML 元素
          <style>
            #box {
              height: 300px;
              line-height: 300px;
              text-align: center;
            }
          </style>
          <body>
            <div id="box">Hello World</div>
            <script>
              function bluify() {
                console.log(this);
                this.style.backgroundColor = "#00CCFF";
                this.innerHTML =
                  this.innerHTML === "Hello World" ? "你好,世界" : "Hello World";
              }
              box.addEventListener("click", bluify, false);
            </script>
          </body>

          2. 全局函數(shù)、匿名函數(shù),this 指向是全局對象

          • 瀏覽器中指向 Window
          • Node 環(huán)境指向 Global
          function func() {
            console.log(this); // Window or global
          }
          func();

          3. 對象的方法調(diào)用

          this 指向當(dāng)前的對象
          const xiaoming = {
            name: "小明",
            getName() {
              console.log(this.name);
            },
          };
          xiaoming.getName(); // 小明

          4. 構(gòu)造函數(shù)內(nèi)調(diào)用,this 指向?qū)嵗龑ο?/span>

          function Person(name, sex, age) {
            this.name = name;
            this.sex = sex;
            this.age = age;
          }
          let xiaoming = new Person("小明""男", 20);
          console.log(xiaoming); // { name: '小明', sex: '男', age: 20 }

          5. call/apply/bind 調(diào)用

          this 指向第一個(gè)參數(shù)
          const xiaoming = {
            name: "小明",
            getName() {
              console.log(this.name);
            },
          };
          const xiaohong = {
            name: "小紅",
          };
          xiaoming.getName.call(xiaohong); // 小紅

          this 復(fù)制引用

          原因: 用于糾正 this 指向不達(dá)預(yù)期的問題
          應(yīng)用場景: 比如在 setTimeout 中的函數(shù)
          用法:let that = this;
          普通函數(shù) VS 箭頭函數(shù)
          var name = "window";
          let obj = {
            name: "obj",
            outout1() {
              let that = this;
              setTimeout(function() {
                console.log("普通函數(shù)", that.name);
              }, 1000);
            },
            outout2() {
              setTimeout(() => {
                console.log("箭頭函數(shù)", this.name);
              }, 1000);
            },
          };
          obj.outout1(); // 普通函數(shù) obj
          obj.outout2(); // 普通函數(shù) obj

          因?yàn)榧^函數(shù)的this是在定義的時(shí)候就確定的,使用它可以少寫一步 this 指向,推薦使用。

          定時(shí)器

          • setTimeout:規(guī)定 N 秒后執(zhí)行
          • setInterval:規(guī)定 N 秒后循環(huán)執(zhí)行

          參數(shù)

          • 函數(shù)/字符串、字符串會(huì)觸發(fā)eval()
          • 時(shí)長毫秒(ms)
          • 傳入函數(shù)的參數(shù)列表
          傳入函數(shù)
          // setTimeout / setInterval 使用
          setTimeout(
            (...args) => {
              let sum = args.reduce((p, c) => p + c);
              console.log(args, sum); //[ 1, 2, 3 ] 6
            },
            1000,
            1,
            2,
            3
          );
          // 這段代碼的意思是:在 1 秒后將這個(gè)函數(shù)推入執(zhí)行棧,然后傳遞參數(shù)1,2,3到函數(shù)中

          一秒后開始計(jì)算 1,2,3 的和,然后輸出。
          傳入字符串
          setTimeout("alert(0)", 2000);

          可以接受一個(gè)字符串,默認(rèn)通過 eval() 解析后執(zhí)行,但是 eval 函數(shù)非常耗性能,非特殊不推薦。
          返回值
          返回定時(shí)器的 ID ,用于清除定時(shí)器。
          clearInterval(n);
          clearTimeout(n);

          setTimeout

          核心邏輯:N 秒推入執(zhí)行棧,而不是 N 秒后執(zhí)行,
          使用場景:延遲執(zhí)行某個(gè)操作時(shí)
          問題:
          • 設(shè)置 0 秒也會(huì)在下一個(gè)宏任務(wù)中執(zhí)行(異步)
          • 定時(shí)器在 for 中輸出 1-10 的坑(forEach 不可跳出循環(huán))
          異步
          // for & setTimout
          for (var i = 1; i <= 10; i++) {
            setTimeout(() => {
              console.log(i); // ??
            }, 1000);
          }

          因?yàn)楫惒降脑颍?/span>setTimeout 被延遲到下一次事件循環(huán)中執(zhí)行。
          forEach
          forEach 不能跳出循環(huán)
          let arr = [1, 2, 3];
          arr.forEach((e) => {
            console.log(e);
            1, 2, 3;
            e += 1;
            if (e === 2) {
              // break !X
              // return !X
            }
          });
          console.log(arr); // [1, 2, 3];

          forEach中使用breakreturn等都不會(huì)跳出循環(huán)。
          上列操作可以轉(zhuǎn)換為for操作
          for (let i = 0; i < arr.length; i++) {
            if (arr[i] === 2) {
              break;
            }
            arr[i] += 1;
          }
          console.log(arr); // [ 2, 2, 3 ]

          setInterval

          使用場景
          • 視頻學(xué)習(xí)的定時(shí)保存學(xué)時(shí)
          • 掃碼登錄的輪詢

          問題

          定時(shí)器不準(zhǔn)確的原因
          • N 秒后推入執(zhí)行棧,而不是 N 秒后執(zhí)行
          • 會(huì)因?yàn)榍懊嬗写a在執(zhí)行而導(dǎo)致時(shí)間變短
          案例代碼:
          假設(shè)有一個(gè) HTTP 輪詢,每一秒查詢一次數(shù)據(jù)。
          let startTime = new Date().getTime();
          let count = 0;
          setInterval(() => {
            let i = 0;
            while (i++ < 10000000); // 假設(shè)這里是查詢數(shù)據(jù)帶來的網(wǎng)絡(luò)延遲,用來增加每次函數(shù)執(zhí)行的時(shí)間
            count++;
            console.log(
              "與原設(shè)定的間隔時(shí)差了:",
              new Date().getTime() - (startTime + count * 1000),
              "毫秒"
            );
          }, 1000);

          代碼在執(zhí)行多次后,定時(shí)器會(huì)變得不準(zhǔn)確,產(chǎn)生誤差。
          定時(shí)器不及時(shí)清楚(小程序中)
          • clear的話會(huì)一直保存在內(nèi)存中,造成內(nèi)存泄漏。
          • 使用場景:保存學(xué)時(shí)、人臉識(shí)別、考試倒計(jì)時(shí)等
          • 多個(gè)頁面棧共享定時(shí)器

          解決方法

          定時(shí)器不準(zhǔn)確
          解決方法:使用settimeout模擬setinterval
          // 自定義一個(gè)定時(shí)器
          let timer = null;
          function interval(func, wait) {
            let interv = function() {
              func.call(null);
              timer = setTimeout(interv, wait);
            };
            timer = setTimeout(interv, wait);
          }

          // 使用定時(shí)器
          interval(() => {
            let date = new Date();
            console.log("log..", `${date.getMinutes()}${date.getSeconds()}`);
          }, 1000);

          // 清楚定時(shí)器
          setTimeout(() => {
            clearTimeout(timer);
          }, 1000 * 6);

          定時(shí)器太多清楚不掉,造成內(nèi)存泄漏
          解決方法:批量清楚定時(shí)器
          // 清楚當(dāng)前頁面的所有定時(shí)器
          for (let i = 1; i < 100000; i++) {
            clearInterval(i);
            clearTimeout(i);
          }

          建議及時(shí)保存定時(shí)器的id,用于清除。


          點(diǎn)擊左下角閱讀原文,到 SegmentFault 思否社區(qū) 和文章作者展開更多互動(dòng)和交流,掃描下方”二維碼“或在“公眾號后臺(tái)回復(fù)“ 入群 ”即可加入我們的技術(shù)交流群,收獲更多的技術(shù)文章~

          - END -


          瀏覽 32
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  精品蜜桃秘 一区二区三区毛茸茸 | 91av巨作在线 | 中文字幕无码乱伦 | 亚洲欧洲在线免费 | 国产精品 一道在线 |