<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>

          30+ 個工作中常用的前端小知識(干貨)

          共 16241字,需瀏覽 33分鐘

           ·

          2022-02-27 04:53

          以下內(nèi)容來自公眾號逆鋒起筆,關(guān)注每日干貨及時送達

          作者:隱冬

          https://juejin.cn/post/6908698827033837575


          1. JS為什么單線程
          一個簡單的原因就是,js在設(shè)計之初只是進行一些簡單的表單校驗,這完全不需要多線程,單線程完全可以勝任這項工作。即便后來前端發(fā)展迅速,承載的能力越來越多,也沒有發(fā)展到非多線程不可的程度。
          而且還有一個主要的原因,設(shè)想一下,如果js是多線程的,在運行時多個線程同時對DOM元素進行操作,那具體以哪個線程為主就是個問題了,線程的調(diào)度問題是一個比較復(fù)雜的問題。
          HTML5新的標準中允許使用new Worker的方式來開啟一個新的線程,去運行一段單獨的js文件腳本,但是在這個新線程中嚴格的要求了可以使用的功能,比如說他只能使用ECMAScript, 不能訪問DOMBOM。這也就限制死了多個線程同時操作DOM元素的可能。

          2.使用css寫出一個三角形角標

          元素寬高設(shè)置為0,通過border屬性來設(shè)置,讓其它三個方向的border顏色為透明或者和背景色保持一致,剩余一條border的顏色設(shè)置為需要的顏色。
             
          div {
              width0;
              height0;
              border5px solid #transparent;
              border-top-color: red;
          }

          3.水平垂直居中

          我一般只使用兩種方式定位或者flex,我覺得夠用了。
             
          div {
              width100px;
              height100px;
              position: absolute;
              top0;
              right0;
              bottom0;
              left0;
              margin: auto;
          }
          父級控制子集居中
             
          .parent {
              display: flex;
              justify-content: center;
              align-items: center;
          }

          4. css一行文本超出...

             
          overflowhidden;
          text-overflow:ellipsis;
          white-spacenowrap;

          5.多行文本超出顯示...

             
          display-webkit-box;
          -webkit-box-orientvertical;
          -webkit-line-clamp: 3;
          overflowhidden;

          6.IOS手機容器滾動條滑動不流暢

             
          overflowauto;
          -webkit-overflow-scrollingtouch;

          7.修改滾動條樣式

          隱藏div元素的滾動條
             
          div::-webkit-scrollbar {
              display: none;
          }
          div::-webkit-scrollbar 滾動條整體部分
          div::-webkit-scrollbar-thumb 滾動條里面的小方塊,能向上向下移動(或往左往右移動,取決于是垂直滾動條還是水平滾動條)
          div::-webkit-scrollbar-track 滾動條的軌道
          div::-webkit-scrollbar-button 滾動條的軌道的兩端按鈕,允許通過點擊微調(diào)小方塊的位置。
          div::-webkit-scrollbar-track-piece 內(nèi)層軌道,滾動條中間部分
          div::-webkit-scrollbar-corner 邊角,即兩個滾動條的交匯處
          div::-webkit-resizer 兩個滾動條的交匯處上用于通過拖動調(diào)整元素大小的小控件
          注意此方案有兼容性問題,一般需要隱藏滾動條時我都是用一個色塊通過定位蓋上去,或者將子級元素調(diào)大,父級元素使用overflow-hidden截掉滾動條部分。暴力且直接。微信搜索readdot,關(guān)注后回復(fù)視頻教程獲取23種精品資料

          8.解決ios audio無法自動播放、循環(huán)播放的問題

          ios手機在使用audio或者video播放的時候,個別機型無法實現(xiàn)自動播放,可使用下面的代碼hack
             
          // 解決ios audio無法自動播放、循環(huán)播放的問題
          var music = document.getElementById('video');
          var state = 0;

          document.addEventListener('touchstart'function(){
              if(state==0){
                  music.play();
                  state=1;
              }
          }, false);

          document.addEventListener("WeixinJSBridgeReady"function () {
              music.play();
          }, false);

          //循環(huán)播放
          music.onended = function () {
              music.load();
              music.play();
          }

          9.隱藏頁面元素

          display-none: 元素不會占用空間,在頁面中不顯示,子元素也不會顯示。
          opacity-0: 元素透明度將為0,但元素仍然存在,綁定的事件仍舊有效仍可觸發(fā)執(zhí)行。
          visibility-hidden:元素隱藏,但元素仍舊存在,占用空間,頁面中無法觸發(fā)該元素的事件。

          10.前端工程化

          一提到前端工程化很多人想到的都是webpack,這是不對的,webpack僅僅是前端工程化中的一環(huán)。在整個工程化過程中他幫我們解決了絕大多數(shù)的問題,但并沒有解決所有問題。
          前端工程化是通過工具提升效率,降低成本的一種手段。
          近些年被廣泛的關(guān)注和探討,究其原因主要是因為現(xiàn)代化前端應(yīng)用功能要求不斷提高,業(yè)務(wù)邏輯日益復(fù)雜,作為當下互聯(lián)網(wǎng)時代唯一不可或缺的技術(shù),前端可以說是占據(jù)了整個開發(fā)行業(yè)的半壁江山。從傳統(tǒng)的網(wǎng)站,到現(xiàn)在的H5,移動App,桌面應(yīng)用,以及小程序。前端技術(shù)幾乎是無所不能的全面覆蓋。
          在這些表象的背后呢,實際上是行業(yè)對開發(fā)人員的要求發(fā)生了天翻地覆的變化,以往前端寫demo,套模板,調(diào)頁面這種刀耕火種的方式已經(jīng)完全不符合當下對開發(fā)效率的要求,前端工程化就是在這樣一個背景下被提上臺面,成為前端工程師必備的手段之一。
          一般來說前端工程包含,項目初始化,項目開發(fā),提交,構(gòu)建,部署,測試,監(jiān)控等流程。工程化就是以工程的角度來解決這些問題。比如項目初始化我們一般使用npm init, 創(chuàng)建頁面模板使用plop,我們喜歡使用ES6+開發(fā),但是需要通過babel編碼成ES5,持續(xù)集成的時候我們使用git/ci cd,但是為了保持開發(fā)規(guī)范我們引入了ESLint,部署一般使用git/cd或者jenkins等等。

          11.contenteditable

          html中大部分標簽都是不可以編輯的,但是添加了contenteditable屬性之后,標簽會變成可編輯狀態(tài)。
             
          <div contenteditable="true"></div>
          不過通過這個屬性把標簽變?yōu)榭删庉嫚顟B(tài)后只有input事件,沒有change事件。也不能像表單一樣通過maxlength控制最大長度。我也忘記我在什么情況下用到過了,后面想起來再補吧。

          12.calc

          這是一個css屬性,我一般稱之為css表達式??梢杂嬎?code style="margin: 3px;padding: 3px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;font-size: 14px;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;border-radius: 4px;color: rgb(155, 110, 35);background-color: rgb(255, 245, 227);word-break: break-all;">css的值。最有趣的是他可以計算不同單位的差值。很好用的一個功能,缺點是不容易閱讀。接盤俠沒辦法一眼看出20px是啥。
             
          div {
              widthcalc(25% - 20px);
          }

          13.Date對象

          獲取當前時間毫秒值
             
          // 方式一
          Date.now(); // 1606381881650
          // 方式二
          new Date() - 0// 1606381881650
          // 方式三
          new Date().getTime() // 1606381881650
          創(chuàng)建Date對象的兼容性問題。
             
          // window和安卓支持,ios和mac不支持
          new Date('2020-11-26'); 
          // window和安卓支持,ios和mac支持
          new Date('2020/11/26');

          14.Proxy和Object.defineProperty區(qū)別

          Proxy的意思是代理,我一般叫他攔截器,可以攔截對象上的一個操作。用法如下,通過new的方式創(chuàng)建對象,第一個參數(shù)是被攔截的對象,第二個參數(shù)是對象操作的描述。實例化后返回一個新的對象,當我們對這個新的對象進行操作時就會調(diào)用我們描述中對應(yīng)的方法。
             
          new Proxy(target, {
              get(target, property) {

              },
              set(target, property) {

              },
              deleteProperty(target, property) {

              }
          })
          Proxy區(qū)別于Object.definedProperty。
          Object.defineProperty只能監(jiān)聽到屬性的讀寫,而Proxy除讀寫外還可以監(jiān)聽屬性的刪除,方法的調(diào)用等。
          通常情況下我們想要監(jiān)視數(shù)組的變化,基本要依靠重寫數(shù)組方法的方式實現(xiàn),這也是Vue的實現(xiàn)方式,而Proxy可以直接監(jiān)視數(shù)組的變化。
             
          const list = [123];
          const listproxy = new Proxy(list, {
              set(target, property, value) {
                  target[property] = value;
                  return true// 標識設(shè)置成功
              }
          });

          list.push(4);
          Proxy是以非入侵的方式監(jiān)管了對象的讀寫,而defineProperty需要按特定的方式定義對象的屬性。

          15.Reflect

          他是ES2015新增的對象,純靜態(tài)對象也就是不能被實例畫,只能通過靜態(tài)方法的方式調(diào)用,和Math對象類似,只能類似Math.random()的方式調(diào)用。
          Reflect內(nèi)部封裝了一系列對對象的底層操作,一共14個,其中1個被廢棄,還剩下13個。
          Reflect的靜態(tài)方法和Proxy描述中的方法完全一致。也就是說Reflect成員方法就是Proxy處理對象的默認實現(xiàn)。
          Proxy對象默認的方法就是調(diào)用了Reflect內(nèi)部的處理邏輯,也就是如果我們調(diào)用get方法,那么在內(nèi)部,Reflect就是將get原封不動的交給了Reflect,如下。
             
          const proxy = new Proxy(obj, {
              get(target, property) {
                  return Reflect.get(target, property);
              }
          })
          ReflectProxy沒有絕對的關(guān)系,我們一般將他們兩個放在一起講是為了方便對二者的理解。
          那為什么會有Reflect對象呢,其實他最大的用處就是提供了一套統(tǒng)一操作ObjectAPI
          判斷對象是否存在某一個屬性,可以使用in操作符,但是不夠優(yōu)雅,還可以使用Reflect.has(obj, name); 刪除一個屬性可以使用delete,也可以使用Reflect.deleteProperty(obj, name); 獲取所有屬性名可以使用Object.keys, 也可以使用Reflect.ownKeys(obj); 我們更推薦使用ReflectAPI來操作對象,因為他才是未來。

          16.解析get參數(shù)

          通過replace方法獲取url中的參數(shù)鍵值對,可以快速解析get參數(shù)。
             
          const q = {};
          location.search.replace(/([^?&=]+)=([^&]+)/g,(_,k,v)=>q[k]=v);
          console.log(q); 

          17.解析連接url

          可以通過創(chuàng)建a標簽,給a標簽賦值href屬性的方式,獲取到協(xié)議,pathnameoriginlocation對象上的屬性。
             
          // 創(chuàng)建a標簽
          const aEle = document.createElement('a');
          // 給a標簽賦值href路徑
          aEle.href = '/test.html';
          // 訪問aEle中的屬性
          aEle.protocol; // 獲取協(xié)議
          aEle.pathname; // 獲取path
          aEle.origin;
          aEle.host;
          aEle.search;
          ...

          18.localStorage

          localStorageH5提供的永久存儲空間,一般最大可存儲5M數(shù)據(jù),并且支持跨域隔離,他的出現(xiàn)極大提高了前端開發(fā)的可能性。localStorage的使用很多人都知道setItem,getItem,removeItem, 但他也可以直接以成員的方式操作。
             
          // 存儲
          localStorage.name = 'yd';
          // 獲取
          localStorage.name; // yd
          // 刪除
          delete localStorage.name;
          // 清除全部
          localStorage.clear();

          // 遍歷
          for (let i = 0; i < localStorage.length; i++) {
              const key = localStorage.key(i); // 獲取本地存儲的Key
              localStorage[key]; // 獲取本地存儲的value
          }
          localStorage滿了的情況下仍繼續(xù)存儲并不會覆蓋其他的值,而是直接報錯(QuotaExceededError),并且當前存儲的值也會被清空。瀏覽器支持每個域名下存儲5M數(shù)據(jù)。

          19.sessionStorage

          sessionStoragelocalStorage的區(qū)別是,存在當前會話,很多人理解的是瀏覽器關(guān)閉,這是不對的,假設(shè)你在A頁面存儲了sessionStorage,新開選項卡將A頁面的鏈接粘貼進去打開頁面,sessionStorage也是不存在的。
          所以sessionStorage存在的條件是頁面間的跳轉(zhuǎn),A頁面存儲了sessionStorage,他要通過超鏈接或者location.href或者window.open來打開另一個同域頁面才能訪問sessionStorage
          這一點在混合開發(fā)嵌套H5的開發(fā)模式中尤為重要,如果以新開webview的方式打開頁面,很可能sessionStorage就沒有了。

          20.會話cookie

          cookie在設(shè)置的時候如果不設(shè)置過期時間,就表示是個會話cookie,以前我以為關(guān)閉瀏覽器會話cookie就消失了,然而...喜提bug一個。
          在多數(shù)情況下windows系統(tǒng)或者安卓系統(tǒng)確實是這樣的。但是在macOS系統(tǒng)或者ios系統(tǒng)中,關(guān)閉瀏覽器并不會清除掉會話cookie,結(jié)束瀏覽器進程才行。

          21.標簽?zāi)0遄址?/span>

          模板字符串支持在前面添加一個函數(shù),第一個參數(shù)是一個有固定內(nèi)容組成的數(shù)組,后面參數(shù)依次為傳入的變量,函數(shù)返回值為模板字符串真正展示的值。不過這個功能個人感覺沒啥用。
             
          const tag = (params, ...args) => {
              return params[0] + args[0]; // 返回值為模板字符串的真實值。
          }

          const str = tag`hello ${'world'}`;

          22.字符串常用的幾個方法

          1. includes();

          字符串中是否包含某個字符串,這個不說了,其實就是indexOf的替代方案,用起來更優(yōu)雅,

          2. startsWith();

          字符串是否為某個字符串開始,我一般用它判斷url是否有http

          3. endsWith();

          字符串是否為某個字符串結(jié)尾。判斷后綴名的時候尤其有效。

          4. repeat(number);

          得到一個重復(fù)number次的字符串。額...我也不知道什么時候有用,一般我用它造測試數(shù)據(jù)。

          5. 'abc'.padEnd(5, '1'); // abc11;

          用給定的字符串在尾部拼接到指定長度,第一個參數(shù)為長度,第二個參數(shù)為用于拼接的值。

          6. 'abc'.padStart(5, '1'); // 11abc;

          用給定的字符串在首部拼接到指定長度第一個參數(shù)為長度,第二個參數(shù)為用于拼接的值。首部補0?

          23.數(shù)組快速去重

          應(yīng)該很多人都知道這個,數(shù)組轉(zhuǎn)換成Set, 再轉(zhuǎn)換為數(shù)組,不過這種去重方式只能去除基本數(shù)據(jù)類型組成的數(shù)組。
             
          const arr = [123456];

          const arr2 = new Set(arr);

          const arr3 = [...arr2];

          24.Object.keys, values, entries

          一般我們常用Object.keys,返回一個對象的鍵組成的數(shù)組,其實還有Object.values,返回對象值組成的數(shù)組,Object.entries將對象轉(zhuǎn)成數(shù)組,每個元素是鍵值對組成的數(shù)組,可以使用此功能快速將對象轉(zhuǎn)為Map
             

          const obj = {name'yd'age18};

          Object.keys(obj); // ['name', 'age'];

          Object.values(obj); // ['yd', 18];

          const l = Object.entries(obj); // [['name', 'yd'], ['age': 18]];

          const m = new Map(l);

          25.Object.getOwnPropertyDescriptors

          獲取對象的描述信息
          Object.assign復(fù)制時,將對象的屬性和方法當做普通屬性來復(fù)制,并不會復(fù)制完整的描述信息,比如this。
             
          const p1 = {
              a'y',
              b'd',
              get name() {
                  return `${this.a} ${this.b}`;
              }
          }
          const p2 = Object.assign({}, p1);

          p2.a = 'z';

          p2.name; // y d; 發(fā)現(xiàn)并沒有修改p2.a的值,是因為this仍舊指向p1
          使用Object.getOwnPropertyDescriptors獲取完整描述信息
             
          const description = Object.getOwnPropertyDescriptors(p1);

          const p2 = Object.defineProperty({}, description);

          p2.a = 'z';

          p2.name; // z d

          26.BigInt

          JavaScript可以處理的最大數(shù)字是253次方 - 1,這一點我們可以在Number.MAX_SAFE_INTEGER中看到。
             
          consoel.log(Number.MAX_SAFE_INTEGER); //9007199254740991
          更大的數(shù)字則無法處理,ECMAScript2020引入BigInt數(shù)據(jù)類型來解決這個問題。通過把字母n放在末尾, 可以運算大數(shù)據(jù)。
          BigInt可以使用算數(shù)運算符進行加、減、乘、除、余數(shù)及冪等運算。它可以由數(shù)字和十六進制或二進制字符串構(gòu)造。此外它還支持AND、ORNOTXOR之類的按位運算。唯一無效的位運算是零填充右移運算符。
             
          const bigNum = 100000000000000000000000000000n;
          console.log(bigNum * 2n); // 200000000000000000000000000000n

          const bigInt = BigInt(1);
          console.log(bigInt); // 1n;

          const bigInt2 = BigInt('2222222222222222222');
          console.log(bigInt2); // 2222222222222222222n;
          BigInt是一個大整數(shù),所以他不能用來存儲小數(shù)。

          27.??合并空運算符

          假設(shè)變量a不存在,我們希望給系統(tǒng)一個默認值,一般我們會使用||運算符。但是在javascript中空字符串,0,false都會執(zhí)行||運算符,所以ECMAScript2020引入合并空運算符解決該問題,只允許在值為null或未定義時使用默認值。
             
          const name = '';

          console.log(name || 'yd'); // yd;
          console.log(name ?? 'yd'); // '';

          28.?可選鏈運算符

          業(yè)務(wù)代碼中經(jīng)常會遇到這樣的情況,a對象有個屬性b,b也是一個對象有個屬性c,
          我們需要訪問c,經(jīng)常會寫成a.b.c,但是如果f不存在時,就會出錯。
             
          const a = {
              b: {
                  c123,
              }
          }
          console.log(a.b.c); // 123;
          console.log(a.f.c); // f不存在所以會報錯
          ECMAScript2020定義可選鏈運算符解決該問題,通過在.之前添加一個?將鍵名變成可選
             
          let person = {};
          console.log(person?.profile?.age ?? 18); // 18

          29.import

          importECMAScript2015當中定義的一套ES Module模塊系統(tǒng),語法特性絕大多數(shù)瀏覽器已經(jīng)支持了,通過給script標簽添加type=module的屬性就可以使用ES Module的標準去執(zhí)行javascript代碼了。
             
          <script type="module">
          console.log('this is es module');
          </script>
          ES Module規(guī)范下,會采用嚴格模式(use strict)運行javascript代碼。每個ES Module都運行在單獨的作用域中,也就意味著變量間不會互相干擾。外部js文件是通過CORS的方式請求的,所以要求我們外部的js文件地址要支持跨域請求,也就是文件服務(wù)器要支持CORS。我們可以在任意網(wǎng)站控制臺輸入下面代碼。
             
          const script = document.createElement('script');

          script.type = 'module';

          script.innerHTML = `import React from 'https://cdn.bootcdn.net/ajax/libs/react/17.0.1/cjs/react-jsx-dev-runtime.development.js';`;

          document.body.append(script);
          可以發(fā)現(xiàn)在network中請求了https://cdn.bootcdn.net/ajax/libs/react/17.0.1/cjs/react-jsx-dev-runtime.development.js資源。
          ES Modulescript標簽會延遲腳本加載,等待網(wǎng)頁請求完資源之后才執(zhí)行,和使用deffer的方式加載資源相同。
          需要注意的是,import {} from 'xx'導(dǎo)入模塊的時候,并不是對象的解構(gòu),而是import的固定語法,這一點很多人容易弄錯。微信搜索readdot,關(guān)注后回復(fù)視頻教程獲取23種精品資料
          并且ECMAScript2020import開始支持動態(tài)導(dǎo)入功能,在此之前import只能寫在模塊代碼的頂部,一開始就要聲明模塊依賴的其它模塊。支持動態(tài)引入后就可以按需引入對應(yīng)的模塊,這個功能我們早在SPA中就已經(jīng)用到了。動態(tài)導(dǎo)入返回的是一個Promise。
          a.js
             
          const a = 123;
          export { a };
          b.js
             

          import('./a.js').then(data => {
              console.log(data.a); // 123;
          })

          30. 0.1 + 0.2 === 0.3 // false

             
          console.log(0.1+0.2); // 0.30000000000000004
          JS當中,Number類型實際上是double類型,運算小數(shù)時存在精度問題。因為計算機只認識二進制,在進行運算時,需要將其他進制的數(shù)值轉(zhuǎn)換成二進制,然后再進行計算
          小數(shù)用二進制表達時是無窮的。
             
          // 將0.1轉(zhuǎn)換成二進制
          console.log(0.1.toString(2)); // 0.0001100110011001100110011001100110011001100110011001101

          // 將0.2轉(zhuǎn)換成二進制
          console.log(0.2.toString(2));  // 0.001100110011001100110011001100110011001100110011001101
          雙精度浮點數(shù)的小數(shù)部分最多支持53位二進制位,所以兩者相加后,因浮點數(shù)小數(shù)位的限制而截斷的二進制數(shù)字,再轉(zhuǎn)換為十進制,就成了0.30000000000000004,這樣在進行算術(shù)計算時會產(chǎn)生誤差。
          ES6 在Number對象上面,新增一個極小的常量Number.EPSILON。根據(jù)規(guī)格,它表示1與大于1的最小浮點數(shù)之間的差。對于64位浮點數(shù)來說,大于1的最小浮點數(shù)相當于二進制的1.00..001,小數(shù)點后面有連續(xù)51個零。這個值減去1之后,就等于2的-52次方
             
          Number.EPSILON === Math.pow(2-52)
          // true
          Number.EPSILON
          // 2.220446049250313e-16
          Number.EPSILON.toFixed(20)
          // "0.00000000000000022204"
          Number.EPSILON實際上是JavaScript能夠表示的最小精度。誤差如果小于這個值,就可以認為已經(jīng)沒有意義了,即不存在誤差了。
          引入一個這么小的量的目的,在于為浮點數(shù)計算,設(shè)置一個誤差范圍。我們知道浮點數(shù)計算是不精確的。
          Number.EPSILON可以用來設(shè)置能夠接受的誤差范圍。比如,誤差范圍設(shè)為2-50次方(即Number.EPSILON * Math.pow(2, 2)),即如果兩個浮點數(shù)的差小于這個值,我們就認為這兩個浮點數(shù)相等。
             
          (0.1 + 0.2 - 0.3) < Number.EPSILON // true

          如何全鏈路進行前端性能優(yōu)化

          2022 前端領(lǐng)域新變化,你準備好了嗎?

          Vue 項目前端多語言方案

          前端異常埋點系統(tǒng)初探

          從面試官角度看一次前端面試經(jīng)歷

          點個『在看』支持下 
          瀏覽 54
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <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>
                  国产在线拍揄自揄拍无码视频 | 嫩草乱码一区三区四区 | 先锋资源av | 超碰自拍 | 天天日天天插天天操 |