国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

前端常見面試八股文

這篇具有很好參考價(jià)值的文章主要介紹了前端常見面試八股文。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

HTML篇

1、H5新增標(biāo)簽有哪些?

一、語義化標(biāo)簽

header、footer、nav、aside、section、article

語義化的意義?

1、更適合搜索引擎的爬蟲爬取有效的信息,利于SEO。

2、對(duì)開發(fā)團(tuán)隊(duì)很友好,增加了標(biāo)簽的可讀性,結(jié)構(gòu)更加的清晰,便于團(tuán)隊(duì)的開發(fā)和維護(hù)。

二、多媒體標(biāo)簽

視頻標(biāo)簽:video

屬性:src、 Poster(加載等待畫面的圖片)、muted(靜音)

音頻標(biāo)簽: audio

屬性:src、loop、controls(調(diào)出當(dāng)前控件)

三、表單元素、控件

輸入框input中新增 type,類型可為、email、url、data、number等

required、placeholder

2、src和href的區(qū)別

src和href都是對(duì)外部資源的引用,區(qū)別如下:

src: 表示對(duì)資源的引用,用在js腳本、img、frame等元素上,當(dāng)瀏覽器解析到該元素時(shí),會(huì)暫停其他資源的下載和處理,直到該資源加載、編譯、執(zhí)行完成,所以js腳本會(huì)放在頁面的底部,而不是頭部。

href:表示超文本引用,指向一些網(wǎng)絡(luò)資源,當(dāng)瀏覽器識(shí)別它指向的文件時(shí),就會(huì)并行下載資源,不會(huì)停止對(duì)當(dāng)前文件的處理,用在a、link上

3、defer和async

參考博文:

https://blog.csdn.net/weixin_42561383/article/details/86564715

默認(rèn)情況下,瀏覽器是同步加載js腳本的,即渲染引擎遇到 script標(biāo)簽就會(huì)停下來,等執(zhí)行完腳本,再去繼續(xù)向下渲染,如果是外部腳本,還必須加入腳本的下載時(shí)間。

加入腳本的很多而且體積很大的話,下載執(zhí)行 就會(huì)占用很大的時(shí)間,照成瀏覽器堵塞,用戶就會(huì)感覺卡死了,沒有任何響應(yīng),體驗(yàn)極差,所以瀏覽器允許腳本的異步加載,方式如下:

<script src="path/to/myModule.js" defer></script>
<script src="path/to/myModule.js" async></script>

關(guān)鍵字就是defer和async,腳本會(huì)異步加載。渲染引擎遇到這行命令就會(huì)開始下載外部的腳本,但是并不會(huì)等待其腳本下載完成和執(zhí)行完成,而是直接執(zhí)行后面的命令。

defer和async的區(qū)別:

defer:需要等待整個(gè)頁面正常DOM渲染完成后,才會(huì)執(zhí)行下載好的js腳本,并且是按下載完后的順序執(zhí)行。

async:當(dāng)外部的js腳本下載完成后,渲染引擎會(huì)暫停DOM渲染,開始執(zhí)行下載好的JS腳本的內(nèi)容,在執(zhí)行完成后,再去渲染。

簡(jiǎn)單的說:

defer是需要等DOM元素都渲染完成后,才去執(zhí)行下載完成的js腳本

async是當(dāng)js腳本下載完成后,開始執(zhí)行的時(shí)候中斷DOM渲染,執(zhí)行js腳本的內(nèi)容,執(zhí)行完成再去渲染DOM元素

沒有deferasync屬性,瀏覽器會(huì)立即下載并執(zhí)行相應(yīng)的腳本,并且在下載和執(zhí)行時(shí)頁面的處理會(huì)停止??赡苄纬身撁娑氯?/p>

不用異步加載的話可以把外部引入的腳本放在</body>前即可

4、行內(nèi)元素與塊級(jí)元素

塊級(jí)元素: 獨(dú)占一行,可以設(shè)置寬高,設(shè)置margin和padding都有效,代表如下:

div、p、h1…h(huán)6、table、tr、ol、li、ul

行內(nèi)元素元素: 可以排成一行,設(shè)置寬高無效,對(duì)margin設(shè)置左右方向有效,而上下無效,padding設(shè)置都無效,代表如下:

基本上都是文本標(biāo)簽

span、img、b、strong、font、br、a

5、title與h1、b與strong、i與em的區(qū)別

Strong表示的是重點(diǎn)內(nèi)容,有語氣加強(qiáng)的含義,,會(huì)重讀,而展示強(qiáng)調(diào)的內(nèi)容

b只是展示強(qiáng)調(diào)的內(nèi)容

title屬性沒有明確意義只表示是個(gè)標(biāo)題,H1則表示層次明確的標(biāo)題,對(duì)頁面信息的抓取也有很大的影響

i內(nèi)容展示為斜體,em表示強(qiáng)調(diào)的文本

6、回流(重拍)與重繪

先了解下HTML文文件渲染的過程

前端常見面試八股文

都發(fā)生在渲染DOM樹(Render Tree)后的過程中,其中Layout是回流,Painting是重繪

回流:瀏覽器中進(jìn)行布局的過程就是回流

重繪:瀏覽器進(jìn)行 渲染就是重繪

觸發(fā)回流的一些條件:

1、添加或者刪除可見的DOM元素;

2、元素位置改變;

3、元素尺寸改變——邊距、填充、邊框、寬度和高度

4、內(nèi)容改變——比如文本改變或者圖片大小改變而引起的計(jì)算值寬度和高度改變;

5、頁面渲染初始化;

6、瀏覽器窗口尺寸改變——resize事件發(fā)生時(shí);

前端常見面試八股文

觸發(fā)重繪的一些條件:

1、改變背景色

2、改變透明度

簡(jiǎn)單的說,就是不影響布局的情況下,改變的就是重繪

前端常見面試八股文

性能優(yōu)化方法:

減少瀏覽器的回流行為達(dá)到性能優(yōu)化。

1、用transform代替位移

2、用visibility:hidden透明度代替display:none

3、使用display:none技術(shù),只引發(fā)兩次回流和重繪;

4、使用cloneNode(true or false)和replaceChild技術(shù),引發(fā)一次回流和重繪;

5、讓元素脫離動(dòng)畫流,減少回流的Render tree的規(guī)模;

7、cookie、localStorage 和 sessionStorage的區(qū)別及應(yīng)用實(shí)例

詳解cookie

簡(jiǎn)單的理解是因?yàn)閔ttp協(xié)議的無狀態(tài)性,所以需要cookie去把特別的信息保存下來,當(dāng)然保存的是在瀏覽器中,下面簡(jiǎn)單的講解下邏輯

1、瀏覽器向服務(wù)器發(fā)送請(qǐng)求,傳輸一些信息

2、服務(wù)器收到請(qǐng)求,在響應(yīng)體中通過set-cookie返回字段,保存在瀏覽器中。

3、瀏覽器再次發(fā)送請(qǐng)求時(shí)會(huì)攜帶cookie,根據(jù)服務(wù)器中對(duì)比,做一個(gè)判斷。

在前端的js代碼中通過:

document.cookie = ‘name=value’

去設(shè)置cookie,其中cookie帶有如下屬性

max-age/expires:可設(shè)置cookie的有效時(shí)間,其中expires必須時(shí)GMT的時(shí)間格式,可用new Date().toGMTString()去對(duì)時(shí)間進(jìn)行轉(zhuǎn)換。在沒有設(shè)置時(shí)間時(shí),cookie會(huì)隨著瀏覽器的關(guān)閉,而被刪除

domain:可設(shè)置訪問該cookie的域名

path:可設(shè)置訪問此cookie的頁面路徑

Size:設(shè)置cookie的大小

http:cookie的httponly屬性,如果為true。則只有在http請(qǐng)求頭中會(huì)有此cookie的信息,而不能通過document.cookie來進(jìn)行訪問

刪除cookie

只需要把cookie的有效時(shí)間設(shè)置為當(dāng)前日期的前任何時(shí)間即可

下面是列子:

  <body>
    <form>
      用戶名<input type="text" name="username1111" /> 密碼<input
        type="password"
        name="pwd"
        id="pwd"
      />
      提交<input id="submit" type="submit" /> 記住密碼<input type="checkbox" />
      <button onclick="hand1()" id="delete">刪除cookie</button>
    </form>

    <script>
      let lineTime = new Date("2022-7-20 19:7:30").toGMTString();
      console.log("lineTime: ", lineTime);
      let submit = document.getElementById("submit");
      let username = document.querySelector('input[type="text"]');
      let pwd = document.querySelector('input[type="password"]');
      let check = document.querySelector('input[type="checkbox"]');

      let arr = document.cookie.split(";");
      console.log(arr);
      let arr1 = [];
      arr.forEach((item) => {
        arr1.push(item.split("="));
      });
      let cookie = {};
      for (let i = 0; i < arr1.length; i++) {
        let name = arr1[i][0];
        let value = arr1[i][1];
        cookie[name] = value;
      }
      if (document.cookie) {
        username.value = cookie.yourname;
        check.checked = true;
      }
      submit.addEventListener("click", (e) => {
        let value = username.value;
        let key = "yourname";
        if (check.checked && username.value !== "") {
          document.cookie = `${key}=${value};expires=${lineTime}`;
          e.preventDefault();
        }
      });

      function hand1() {
        let key = "yourname";
        document.cookie = `${key}=; expires=Thu, 01 Jan 1970 00:00:00 GMT`;
        console.log(document.cookie);
        e.preventDefault();
      }
    </script>
localStorage 和sessionStorage

前面得cookie作為一個(gè)存儲(chǔ)手段進(jìn)行舉例,但是在H5中新增了兩種存儲(chǔ)方式,其中使用方法如下:

localStorage.key() :拿到指定key得值

localStorage.setItem('名','值'):設(shè)置相關(guān)的儲(chǔ)存值

localStorage.getItem('名'):取出對(duì)應(yīng)名的值

localStorage.removeItem('名'):移除掉相關(guān)的值

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <input type="text" />
    <button onclick="hand1()" class="hand">搜索</button>
    <ul id="one"></ul>

    <script>
      if (sessionStorage.length > 0) {
        for (let i = 0; i < sessionStorage.length; i++) {
          let key = sessionStorage.key(i);
          let newLi = document.createElement("li");
          newLi.innerHTML = `${sessionStorage.getItem(key)}`;
          let ul = document.getElementById("one");
          ul.append(newLi);
          let close = document.createElement("span");
          close.innerHTML = `刪除`;
          newLi.appendChild(close);
          close.addEventListener("click", (e) => {
            sessionStorage.removeItem(key);
            newLi.parentNode.removeChild(newLi);
          });
        }
      }

      let search = document.querySelector('input[type="text"]');
      let hand = document.getElementsByClassName("hand")[0];
      let temp = 0;
      function hand1() {
        if (search.value) {
          console.log(111);
          temp++;
          sessionStorage.setItem(`${temp}`, search.value);
          let newLi = document.createElement("li");
          newLi.innerHTML = `${sessionStorage.getItem(temp)}`;
          let ul = document.getElementById("one");
          ul.append(newLi);
          let close = document.createElement("span");
          close.innerHTML = `刪除`;
          newLi.appendChild(close);
          close.addEventListener("click", (e) => {
            console.log(temp);
            sessionStorage.removeItem(temp);
            newLi.parentNode.removeChild(newLi);
          });
        }
      }
    </script>
  </body>
</html>

sessionStorage使用的方法和localStorage一致。

三者的區(qū)別

cookie具有時(shí)效性,可以手動(dòng)的去設(shè)置需要保存的時(shí)間,內(nèi)存大小大概為4KB,內(nèi)容保存在客戶端上,刪除的話把過期時(shí)間設(shè)置為前一天即可。

localStorage,除非手動(dòng)去刪除,不然一直會(huì)保存,內(nèi)存大小為5MB

sessionStorage,臨時(shí)會(huì)話保存,相關(guān)頁面關(guān)閉掉就自動(dòng)刪除,內(nèi)容大小為5MB

建議理解三者的基本使用再去理解這面試題,因?yàn)楣ぷ髦幸材苡玫?/p>

8、同源策略與跨域問題

什么是同源策略

借用阮一峰老師的描述:

前端常見面試八股文

簡(jiǎn)單地說就是為了網(wǎng)頁之間的安全性,但是在平常的工作中,我們會(huì)遇到別的資源請(qǐng)求問題,也就是跨域問,下面給出幾種常見的跨域解決問題的方案

跨域解決方案

參考B站技術(shù)蛋老師的講解

1、JSONP

json with padding,也就是JSON的填充方法。在服務(wù)器與客戶端之間的格式我們常用的是JSON格式。

我們用script標(biāo)簽獲取數(shù)據(jù),其中的數(shù)據(jù)會(huì)被執(zhí)行,所以我們一般會(huì)給數(shù)據(jù)外包一個(gè)js函數(shù),然后再外包一層作為傳輸用的json格式。

我們知道通過script標(biāo)簽請(qǐng)求的資源中,并不會(huì)受到同源策略的限制,而jsonp方法就是通過這個(gè)方式去實(shí)現(xiàn)別的資源共享,簡(jiǎn)單原理如下:

原理可分為 客戶端與服務(wù)器

客戶端:客戶端上去寫一個(gè)函數(shù),專門用來處理跨域獲取服務(wù)器JSON數(shù)據(jù)的方法,在傳入的url上寫額外的參數(shù),傳到服務(wù)器,同時(shí)客戶端收到服務(wù)器傳過來的數(shù)據(jù)后,調(diào)用提前設(shè)定好的函數(shù),執(zhí)行服務(wù)器傳過來的數(shù)據(jù)。

服務(wù)器:數(shù)據(jù)源是在服務(wù)器上存在的,而我們需要再然后服務(wù)器對(duì)額外的參數(shù)進(jìn)行判斷,把數(shù)據(jù)外包一個(gè)js函數(shù),通過JSON的方式傳給客戶端。

前端常見面試八股文

前端常見面試八股文

2、CORS

當(dāng)瀏覽器向服務(wù)器發(fā)起請(qǐng)求的時(shí)候,會(huì)在請(qǐng)求頭中添加origin(協(xié)議+主機(jī)+端口),也就是表明自己的協(xié)議+主機(jī)+端口,當(dāng)服務(wù)器接收到這個(gè)origin的時(shí)候,就得添加頭部Access-Control-Allow-Origin到響應(yīng)里面,瀏覽器看到服務(wù)器傳回來的Access-Control-Allow-Origin,就可以進(jìn)行判斷是否進(jìn)行跨域請(qǐng)求

前端常見面試八股文

前端常見面試八股文

核心其實(shí)就是設(shè)置Access-Control-Allow-Origin

9、檢測(cè)數(shù)據(jù)類型的方法

1、typeof

typeof在檢測(cè)null、object、array、data的結(jié)果中都是object,所以無法用來區(qū)分這幾個(gè)類型的區(qū)別

 <script>
      let a = [
        "123",
        123,
        false,
        true,
        Symbol(1),
        new Date(),
        null,
        undefined,
        function () {},
        {},
        []
      ];
      a.forEach((item) => {
        console.log(item, "檢測(cè)出的值:", typeof item);
      });
    </script>

前端常見面試八股文

2、instanceof

缺點(diǎn)是只能檢測(cè)該對(duì)象是否存在目標(biāo)對(duì)象的原型上

[對(duì)象] instanceof [構(gòu)造函數(shù)]

  <script>
      function Foo() {}
      var f1 = new Foo();
      var d = new Number(1);

      console.log(f1 instanceof Foo); // true
      console.log(d instanceof Number); //true
      console.log(123 instanceof Number); //false   -->不能判斷字面量的基本數(shù)據(jù)類型
    </script>
console.log(Number instanceof Number)  // false
console.log(String instanceof String)  // false
console.log(Fun instanceof Fun)        // false,這里Fun指的是函數(shù)
console.log(null instanceof Object)   // false,null不具有任何對(duì)象的特性,也沒有__proto__屬性

instanceof 用于判斷對(duì)象類型,但以上情況的結(jié)果都為false,請(qǐng)注意。

instanceof 的原理

因?yàn)闀?huì)一直往原型鏈上查找

L代表instanceof左邊,R代表右邊

function hand(L, R) {
        let L = L._propto_;
        while (true) {
          if (L === null) {
            return false;
          }
          if (L === R.propotype) {
            return true;
          }
          L = L._propto_;
        }
      }
3、constructor

constructor 不能判斷null、undefind,因?yàn)樗麄儾皇菢?gòu)造對(duì)象

  <script>
      let a = [
        "123",
        123,
        false,
        true,
        Symbol(1),
        new Date(),
        function () {},
        {},
        [],
        null,
        undefined,
      ];
      try {
        a.forEach((item) => {
          console.log(item, "檢測(cè)出的值:", item.constructor.name);
        });
      } catch (e) {
        console.log(e);
      }
    </script>

前端常見面試八股文

4、Object.prototype.toString.call

可以檢測(cè)出所有的數(shù)據(jù)類型

<script>
      let a = [
        "123",
        123,
        false,
        true,
        Symbol(1),
        new Date(),
        function () {},
        {},
        [],
        null,
        undefined,
      ];
      try {
        a.forEach((item) => {
          console.log(
            item,
            "檢測(cè)出的值:",
            Object.prototype.toString.call(item)
          );
        });
      } catch (e) {
        console.log(e);
      }
    </script>

前端常見面試八股文

在使用Array.prototype.toString.call的時(shí)候,遇到null、undefined會(huì)出現(xiàn)報(bào)錯(cuò)

10、阻止默認(rèn)事件

在面試中我們會(huì)被問到事件冒泡、默認(rèn)事件等概念,下面做一些簡(jiǎn)單的了解:

事件冒泡

1.原理:元素自身的事件被觸發(fā)后,如果父元素有相同的事件,如click事件,那么元素本身的觸發(fā)狀態(tài)就會(huì)傳遞,也就是冒到父元素,父元素的相同事件也會(huì)一級(jí)一級(jí)根據(jù)嵌套關(guān)系向外觸發(fā),直到document/window,冒泡過程結(jié)束。

2.使用范圍:冒泡事件只是針對(duì)于click相關(guān)的事件,還有click的分支事件:mouseup、mousedown

默認(rèn)事件:

比如點(diǎn)擊a標(biāo)簽會(huì)默認(rèn)打開、input提交表單按鈕,都是默認(rèn)事件

阻止默認(rèn)事件但是不阻止事件冒泡

event.preventDefault()

阻止事件冒泡阻止默認(rèn)事件

event.stopPropagation();

在jquery中阻止事件冒泡和默認(rèn)行為,在原生js中只阻止事件冒泡

return false

11、文檔流,文本流清除浮動(dòng)

文檔流:

我理解的是頁面中的塊級(jí)元素等DOM元素按照默認(rèn)的方式去進(jìn)行排列

文本流:

網(wǎng)頁頁面上的一些文字的排列

清除浮動(dòng)的方法及原理:

原理:其實(shí)就是讓目標(biāo)元素脫離文檔流即可,手段有float:left、position中的絕對(duì)定位和固定定位

方法:

1、用偽類去清除浮動(dòng)

2、在浮動(dòng)元素上添加一個(gè)空盒子,寫上clear:both的樣式

3、雙偽類清除浮動(dòng)

12、手寫call、apply、bind

1、call

想要手寫出就得知道它是怎么使用的,函數(shù).call(綁定this指向,參數(shù)一,參數(shù)二,…)

<script>
      function person(a, b, c, d) {
        console.log(this.name);
        console.log(a, b, c, d);
      }
      let egg = {
        name: "測(cè)試",
      };

      //js創(chuàng)建新函數(shù)是在函數(shù)原型上去添加
      Function.prototype.newCall = function (params) {
        //先做判斷,如果綁定的調(diào)用的this不是函數(shù),則拋出異常錯(cuò)誤
        if (typeof this !== "function") {
          throw new TypeError("不是函數(shù)");
        }

        //防止傳入null、undefinde,和window進(jìn)行綁定
        params = params || window;

        //先獲取傳入的參數(shù)
        let arr = [...arguments].slice(1);

        //把this指向指向形參的函數(shù),保存this
        params.fn = this;

        //帶入的參數(shù)傳入函數(shù)中
        let result = params.fn(...arr);

        //刪除用完的函數(shù)

        delete params.fn;

        return result;
      };

      person.newCall(egg,'1','2','3','4')
    </script>

前端常見面試八股文

2、apply

apply和call的寫法基本一至,就是二者接受的參數(shù)不同,面試apply的寫法

函數(shù).apply(this指向?qū)ο?,[參數(shù)1,參數(shù)2,參數(shù)3…])

 <script>
      function person(a, b, c, d) {
        console.log(this.name);
        console.log(a, b, c, d);
      }
      egg = {
        name: "tom",
      };

      Function.prototype.newApply = function (context) {
        if (typeof this !== "function") {
          throw TypeError("不是一個(gè)函數(shù)");
        }
        context = context || window;
        context.fn = this;
        let result
        if (arguments[1]) {
          result = context.fn(...arguments[1]);
        } else {
          result = context.fn();
        }
        
        delete context.fn
        return result
      };


      person.newApply(egg,[1,2,3,4])
    </script>

前端常見面試八股文

3、bind

bind與前兩個(gè)的區(qū)別如下

1、bind返回的是一個(gè)函數(shù)

2、如果是new出來的 ,返回一個(gè)空對(duì)象,且使創(chuàng)建出來的實(shí)例的__proto__指向_this的prototype,且完成函數(shù)柯里化

<script>
      function person(a, b, c, d) {
        console.log(this.name);
        console.log(a, b, c, d);
      }

      Function.prototype.newBind = function (content) {
        if (typeof this !== "function") {
          throw TypeError("不是一個(gè)函數(shù)");
        }
        let arr = Array.prototype.slice.call(arguments, 1);
        const that = this;
        return function fn() {
          if (this instanceof fn) {
            return new that(...arr, ...arguments);
          } else {
            return that.apply(content, arr.concat(...arguments));
          }
        };
      };

      egg = {
        name: "tom",
      };

      person.newBind(egg, 1, 2, 3)(4);
    </script>

前端常見面試八股文

13、new的過程中發(fā)生了什么

其實(shí)new的過程中就是this指向改變、新創(chuàng)建一個(gè)實(shí)列的過程,如下

   <script>
      function Mother(tip){
        this.tip=tip
      }
      let son =new Mother()

      // 1、創(chuàng)建一個(gè)son空對(duì)象
      // 2、使空對(duì)象的隱式原型指向原函數(shù)的顯示原型
      // son_proto_=Mother.prototype
      // 3、原函數(shù)進(jìn)行this的綁定,指向空對(duì)象
      // let result =Mother.call(son,tip)
      // 4、判斷函數(shù)結(jié)果是不是null、undefined,是就返回之前新對(duì)象,不是就返回結(jié)果
      // return result instanceof Object ? Object: result
    </script>

14、js的繼承方式

1、原型鏈繼承

關(guān)鍵點(diǎn)就是: 繼承函數(shù).prototype =new 被繼承函數(shù)

  <script>
      function person() {
        this.obj = {
          age: 10,
        };
        this.speack=function(){
          console.log('父元素');
        }
      }
      person.prototype.name = "tom";
      //子元素
      function son() {
        this.name = "son1";
      }
      son.prototype = new person(); //原型鏈繼承
      let p1 = new son();
      console.log(p1.obj.age); //10
      console.log(p1 instanceof person); //true
      console.log(p1.name); //son1
    </script>

缺點(diǎn):

1、繼承單一

2、子類無法向父類的構(gòu)造函數(shù)傳參

3、所有新實(shí)列都會(huì)共享父類實(shí)列的屬性(原型上的屬性也是共享的,一個(gè)實(shí)列修改了原型屬性,另一個(gè)也會(huì)被修改)

2、原型繼承
<script>
   var person ={
      arr: ['a','b','c','d']
   }
   var p1 =Object.create(person)
   p1.arr.push('aaa')
   console.log(p1);  //{}
   console.log(person); 

    </script>

前端常見面試八股文

缺點(diǎn):子類實(shí)列共享了父類構(gòu)造函數(shù)的引用屬性,不能傳參

3、構(gòu)造函數(shù)繼承
<script>
      var person = function (name) {
        this.name = name;
      };
      person.prototype.age=10
      var son = function () {
        person.call(this, "tom");
      };
      var p1 =new son()
        console.log(p1.name);//tom
        console.log(p1.age);undefined
        
    </script>

重點(diǎn):借用.call()和.apply()將父類構(gòu)造函數(shù)引入子類函數(shù)(在子類函數(shù)中做了父類函數(shù)的自執(zhí)行)

優(yōu)點(diǎn):1、可以繼承多個(gè)構(gòu)造函數(shù)屬性

? 2、在子實(shí)列中可以向父實(shí)列傳參

缺點(diǎn):1、只能繼承父實(shí)列的構(gòu)造函數(shù)屬性

? 2、每新實(shí)列都會(huì)有父類構(gòu)造函數(shù)的副本,臃腫

4、組合繼承
  <script>
      var person = function (name) {
        this.name = name;
      };
      person.prototype.age=10
      var son = function () {
        person.call(this, "tom"); //構(gòu)造函數(shù)繼承
      };
      son.prototype=new person() //原型鏈繼承
      var p1 =new son()
        console.log(p1.name);//tom
        console.log(p1.age);undefined
        
    </script>

重點(diǎn):結(jié)合了兩種模式的優(yōu)點(diǎn),傳參和復(fù)用
特點(diǎn):1、可以繼承父類原型上的屬性,可以傳參,可復(fù)用。
   2、每個(gè)新實(shí)例引入的構(gòu)造函數(shù)屬性是私有的。
缺點(diǎn):調(diào)用了兩次父類構(gòu)造函數(shù)(耗內(nèi)存),子類的構(gòu)造函數(shù)會(huì)代替原型上的那個(gè)父類構(gòu)造函數(shù)。

5、寄生組合繼承
 <script>
      var person = function (name) {
        this.name = name;
      };
      person.prototype.age = 10;
      var son = function () {
        person.call(this, "tom"); //構(gòu)造函數(shù)繼承
      };
      son.prototype = Object.create(person.prototype); //寄生組合繼承
      son.prototype.constructor = son;
      var p1 = new son();
      console.log(p1.name); //tom
      console.log(p1.age); //10
    
    </script>

優(yōu)點(diǎn)

  • 只調(diào)用了一次父類構(gòu)造函數(shù),只創(chuàng)建了一份父類屬性
  • 子類可以用到父類原型鏈上的屬性和方法
6、extends繼承
  <script>
      class person{
        constructor(){
          this.name ='tom'
        this.speack =()=>{
          console.log('我是爹');
        }
        }
      }

     class son extends person{
       constructor(){
       
         super()
          this.age=12
       }
     }
    
    let s1 =new son()

    console.log(s1.age,s1.name);
    </script>

ES6出來的

? 子類只要繼承父類,可以不寫 constructor ,一旦寫了,則在 constructor 中的第一句話必須是 super 。

15、箭頭函數(shù)和普通函數(shù)的區(qū)別

1、call、apply、bind不會(huì)改變箭頭函數(shù)this值,會(huì)改變普通函數(shù)this值

2、箭頭函數(shù)沒有原型屬性

3、箭頭函數(shù)不綁定arguments,取而代之用rest參數(shù)… 解決

4、箭頭函數(shù)不能作為構(gòu)造函數(shù)使用,不能使用new

5、箭頭函數(shù)中的 this 和調(diào)用時(shí)的上下文無關(guān),而是取決于定義時(shí)的上下文

16、移動(dòng)端1px像素解決辦法

先理解概念,物理像素、邏輯像素

物理像素:是不同手機(jī)型號(hào)出廠時(shí)攜帶的像素,也稱為硬件像素

邏輯像素:css中記錄的像素

問題描述:

在開發(fā)的時(shí)候ui設(shè)計(jì)師要求的1px是設(shè)備的物理像素,而css中的是邏輯像素,它們之間并不是直接等于的關(guān)系,存在著比列關(guān)系,通??梢杂?javascript 中的 window.devicePixelRatio 來獲取,也可以用媒體查詢的 -webkit-min-device-pixel-ratio 來獲取。當(dāng)然,比例多少與設(shè)備相關(guān)。

解決辦法:

1、媒體查詢利用設(shè)備像素比列縮放,設(shè)置小數(shù)像素

css可以這樣設(shè)置:

.border { border: 1px solid #999 }
@media screen and (-webkit-min-device-pixel-ratio: 2) {
    .border { border: 0.5px solid #999 }
}
@media screen and (-webkit-min-device-pixel-ratio: 3) {
    .border { border: 0.333333px solid #999 }
}

js可以這樣寫:

<body><div id="main" style="border: 1px solid #000000;"></div></body>
<script type="text/javascript">
    if (window.devicePixelRatio && devicePixelRatio >= 2) {
        var main = document.getElementById('main');
        main.style.border = '.5px solid #000000';
    }
</script>

2、媒體查詢 + transfrom 對(duì)方案1的優(yōu)化

/* 2倍屏 */
@media only screen and (-webkit-min-device-pixel-ratio: 2.0) {
    .border-bottom::after {
        -webkit-transform: scaleY(0.5);
        transform: scaleY(0.5);
    }
}
/* 3倍屏 */
@media only screen and (-webkit-min-device-pixel-ratio: 3.0) {
    .border-bottom::after {
        -webkit-transform: scaleY(0.33);
        transform: scaleY(0.33);
    }
}

17、偽類與偽元素的區(qū)別

首先在知道這個(gè)概念之前先了解什么是偽類?偽元素?

1、偽元素

1、偽元素在DOM樹中創(chuàng)建了一些抽象元素,這些抽象元素并不存在與文檔語言中(邏輯上存在,不存在文檔樹中)

2、偽元素由兩個(gè)::開頭,接的是偽元素得名稱(使用兩個(gè)::是為了區(qū)分偽類和偽元素,在CSS2中依然可以用一個(gè):的語法,但是在CSS3中必須使用兩個(gè)冒號(hào)::)

3、一個(gè)選擇器只能使用一個(gè)偽元素,并且偽元素必須處于選擇器語句的最后

偽元素的種類:

前端常見面試八股文

2、偽類

1、偽類由一個(gè)冒號(hào)開頭:

2、獲取不存在與DOM樹中的信息。比如<a>標(biāo)簽的:link、visited等,這些信息不存在與DOM樹結(jié)構(gòu)中,只能通過CSS選擇器來獲取

偽類的種類:

前端常見面試八股文

18、移動(dòng)端、瀏覽器字體小于12px的解決方案

font-size: 12px;是瀏覽器字體設(shè)置最小的時(shí)候,12以下的數(shù)值不生效了,要是想實(shí)現(xiàn)小于12px,方法如下:

 transform: scale(0.5); 

這時(shí)候可能會(huì)遇到字體縮放和布局一起縮小了,只需要將字體與容器樣式分開寫就好了

<style>
      *,
      body {
        padding: 0;
        margin: 0;
      }
      .one {
        font-size: 20px;
        transform: scale(0.5);
      }
      .father {
        width: 100px;
        height: 100ox;
        background-color: red;
      }
    </style>
  </head>
  <body>
    <div class="father"><p class="one">這是一段話</p></div>
  </body>

19、js浮點(diǎn)數(shù)精度計(jì)算問題解決

一般運(yùn)算中,我們會(huì)保留后兩位小數(shù),這里做點(diǎn)知識(shí)擴(kuò)展

1、.toFixed()

語法:

數(shù)字.toFixed(2)

括號(hào)中的數(shù)字是保留的位數(shù),該方法會(huì)四舍五入,返回的值類型是string型

2、Math.round()

語法:

Math.round(x) 

x是數(shù)值

返回值: 給指定的數(shù)字值四舍五入到最接近的整數(shù)

解決精度運(yùn)算問題有如下方式:

1、 擴(kuò)大倍數(shù)法:有多少位小數(shù)就擴(kuò)大10的n次方

document.write((0.01*100+0.09*100)/100); //輸出結(jié)果為0.1

2、四舍五入法:

document.write((0.01+0.09).toFixed(2)); //保留2位小數(shù),輸出結(jié)果為0.10

document.write(Math.round((0.01+0.09)*100)/100); //輸出結(jié)果為0.1

20、移動(dòng)端的300毫秒延遲問題

問題描述:

移動(dòng)端瀏覽器在派發(fā)點(diǎn)擊事件的時(shí)候,通常會(huì)出現(xiàn)300ms左右的延遲。也就是說,當(dāng)我們點(diǎn)擊頁面的時(shí)候移動(dòng)端瀏覽器并不是立即作出反應(yīng),而是會(huì)等上一小會(huì)兒才會(huì)出現(xiàn)點(diǎn)擊的效果。

方案一:禁用縮放

<meta name="viewport" content="user-scalable=no">
<meta name="viewport" content="initial-scale=1,maximum-scale=1">

方案二:更改默認(rèn)的視口寬度

<meta name="viewport" content="width=device-width">

方案三:fastclick,解決移動(dòng)端300ms延遲

FastClick 是 FT Labs 專門為解決移動(dòng)端瀏覽器 300 毫秒點(diǎn)擊延遲問題所開發(fā)的一個(gè)輕量級(jí)的庫。FastClick的實(shí)現(xiàn)原理是在檢測(cè)到touchend事件的時(shí)候,會(huì)通過DOM自定義事件立即出發(fā)模擬一個(gè)click事件,并把瀏覽器在300ms之后的click事件阻止掉。

直接安裝依賴按照官網(wǎng)的教程使用就好了

21、HTTP緩存

面試中我們常會(huì)被到,你知道http緩存的方式有幾種嗎?這樣的問題,下面我簡(jiǎn)單的介紹下,為什么會(huì)有HTTP緩存、緩存的方式

1、存在的意義

我們每一次的網(wǎng)絡(luò)請(qǐng)求中,在請(qǐng)求成功的前提下,服務(wù)器都會(huì)給我們返回對(duì)應(yīng)的資源,瀏覽器進(jìn)行下載,但是并不是所以的資源都會(huì)被下載,比如當(dāng)某些資源未改變時(shí),瀏覽器會(huì)在本地緩存中拿到它們,從而避免了重復(fù)下載的過程,這也算是一種性能上的優(yōu)化

可以被緩存的資源:JS文件、CSS文件、圖片、字體包等等

2、緩存的類型

我們可以知道,前端發(fā)起HTTP請(qǐng)求的時(shí)候,會(huì)在請(qǐng)求頭上攜帶相關(guān)的信息,瀏覽器就會(huì)根據(jù)我們攜帶的信息去判斷,本次請(qǐng)求的該資源是否有本地緩存

強(qiáng)緩存

以前的使用中,我們一直用的是expires,也就是當(dāng)服務(wù)器返回響應(yīng)時(shí),在響應(yīng)頭中將過期的時(shí)間寫入expires字段中,自己隨便找個(gè)網(wǎng)站F12打開調(diào)試臺(tái),找一條網(wǎng)絡(luò)請(qǐng)求即可

前端常見面試八股文

可以看到expires中寫入了過期的時(shí)間范圍,那整個(gè)流程是怎么樣的呢?

當(dāng)首次資源發(fā)送時(shí):

前端常見面試八股文

再次發(fā)送資源時(shí),瀏覽器會(huì)把expires中的時(shí)間戳和本地時(shí)間去進(jìn)行對(duì)比,如果本地時(shí)間小于expires中的時(shí)間,則在緩存中拿到這個(gè)資源,這里的時(shí)間戳由于是服務(wù)器上傳的,所以需要保證瀏覽器和服務(wù)器上的時(shí)間一致

前端常見面試八股文

expires是通過拿到時(shí)間戳去進(jìn)行比對(duì)的,在后面又增加了Cache-Control 中的max-age 字段也允許我們通過設(shè)定時(shí)間長度來達(dá)到同樣的目的。

max-age可以看作是對(duì)expires的補(bǔ)充,在日常工作中,我們可能用max-age較多,但是如果要實(shí)現(xiàn)向下兼容,expires也是必不可少的

cache-control: max-age=3600, s-maxage=31536000

這里可以看到max-age的值,它并不是一個(gè)時(shí)間戳,而是一個(gè)時(shí)間長度,單位是秒,意思是在3600秒內(nèi),該資源是有效的。max-age的機(jī)制就是對(duì)資源的判定有效不再受到服務(wù)器時(shí)間的限制,客戶端會(huì)記錄到請(qǐng)求資源的時(shí)間點(diǎn),以此時(shí)間點(diǎn)為起點(diǎn),從而確保兩個(gè)時(shí)間點(diǎn)都來自于客戶端,相對(duì)來說更加的精確,這里就不給出請(qǐng)求圖了,和上面原理一致

這里介紹下cache-control中的值

max-age:緩存保存的時(shí)間

no-cache:繞開了瀏覽器,每一次發(fā)起請(qǐng)求都不會(huì)再去詢問瀏覽器的緩存情況,而是直接向服務(wù)端去確認(rèn)該緩存是否過期

no-store:不使用任何的緩存策略,連服務(wù)器端的緩存確認(rèn)都繞開了,只允許直接向服務(wù)端發(fā)起請(qǐng)求,并下載完整的響應(yīng)

public:資源能被本地緩存、服務(wù)器代理

private:資源只能給本地緩存,其他服務(wù)器不能緩存

協(xié)商緩存

瀏覽器向服務(wù)器詢問是否需要重新下載資源,還是從本地上獲取到緩存的資源,值得一提的是,當(dāng)服務(wù)器提示資源未改動(dòng),資源就會(huì)被重定向到瀏覽器緩存,對(duì)應(yīng)的HTTP狀態(tài)碼是304

協(xié)商緩存的實(shí)現(xiàn)

Last-Modified:時(shí)間戳,當(dāng)我們第一次請(qǐng)求資源時(shí),會(huì)在響應(yīng)頭中返回

If-Modified-Since:時(shí)間戳,就是服務(wù)器返回的Last-Modified的值

過程就是,請(qǐng)求頭會(huì)攜帶If-Modified-Since,服務(wù)器會(huì)進(jìn)行判斷,若If-Modified-Since的時(shí)間戳是和last-modified不一致,服務(wù)器就會(huì)完整的返回響應(yīng)內(nèi)容,并且返回新的last-modified值,如果一致,就返回304,響應(yīng)頭也不會(huì)添加last-modified字段

第一次請(qǐng)求:

前端常見面試八股文

再次請(qǐng)求

前端常見面試八股文

但是last-modified有自己的缺陷

1、last-modified的值只精確到秒級(jí)

2、如果文件每隔一段時(shí)間重復(fù)生成,但內(nèi)容是一致的,last-modified會(huì)每次返回資源文件,即使內(nèi)容一致

所以etag對(duì)其進(jìn)行了補(bǔ)充

Etag是服務(wù)器對(duì)每個(gè)資源文件生成的唯一 標(biāo)識(shí)字符串 ,這個(gè)字符串基于文件內(nèi)容編碼,只要文件內(nèi)容不同,對(duì)應(yīng)的Etag也會(huì)不同

請(qǐng)求方式和上圖差不多,服務(wù)器返回Etag,下次請(qǐng)求請(qǐng)求頭會(huì)帶上名為if-None-Match的字符串為服務(wù)器做對(duì)比

這里其實(shí)可以看到,Etag會(huì)讓服務(wù)器多做事,也就是會(huì)影響到服務(wù)器的性能,所以我們使用的時(shí)候需要進(jìn)行考慮,Etag的感知文件變化上比Last-modified更為準(zhǔn)確,所以優(yōu)先級(jí)也更高,二者同時(shí)出現(xiàn)時(shí),以Etag為準(zhǔn)

上訴只是對(duì)HTTP緩存的一些簡(jiǎn)單介紹,基礎(chǔ)面試知識(shí)點(diǎn)可以應(yīng)付了,HTTP緩存有很多知識(shí),感興趣可以多百度看下

CSS篇

1、舉出讓元素居中的方法

個(gè)人總結(jié)出兩種情況,即需要居中的元素帶寬高、不帶寬高,如下:

帶寬高
 <style>
      .father {
        width: 500px;
        height: 500px;
        background-color: red;
        position: relative;
      }
      .son {
        width: 100px;
        height: 100px;
        background-color: blue;
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        margin: auto;
      }
    </style>
    
    <body>
    <div class="father">
      <div class="son"></div>
    </div>
  </body>
 <style>
      .father {
        width: 500px;
        height: 500px;
        background-color: red;
        position: relative;
      }
      .son {
        width: 100px;
        height: 100px;
        background-color: blue;
        position: absolute;
        top: 50%;
        left: 50%;
        margin-top: -50px;
        margin-left: -50px;
      }
    </style>
    
    
     <body>
    <div class="father">
      <div class="son"></div>
    </div>
  </body>

前端常見面試八股文

不帶寬高
 <style>
      .father {
        width: 500px;
        height: 500px;
        background-color: red;
        position: relative;
      }
      .son {
        background-color: blue;
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%,-50%);
      }
    </style>
    
     <body>
    <div class="father">
      <div class="son">son</div>
    </div>
  </body>
<style>
      .father {
        width: 500px;
        height: 500px;
        background-color: red;
        display: flex;
        justify-content: center;
        align-items: center;
      }
      .son {
        background-color: blue;
      }
    </style>
    
    
     <body>
    <div class="father">
      <div class="son">son</div>
    </div>
  </body>

2、常見的布局方式

一、左邊(右邊)固定,右邊(左邊)自適應(yīng)
float布局
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      .left {
        width: 200px;
        height: 200px;
        background-color: red;
        float: left;
      }
      .right {
        height: 200px;
        background-color: blue;
      }
    </style>
  </head>
  <body>
    <div class="left"></div>
    <div class="right"></div>
  </body>
</html>

絕對(duì)定位
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      .left {
        width: 200px;
        height: 200px;
        background-color: red;
        position: absolute;
      }
      .right {
        height: 200px;
        background-color: blue;
      }
    </style>
  </head>
  <body>
    <div class="left"></div>
    <div class="right"></div>
  </body>
</html>

彈性布局
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      .box {
        display: flex;
      }
      .left {
        width: 200px;
        height: 200px;
        background-color: red;
      }
      .right {
        flex: 1;
        background-color: blue;
      }
    </style>
  </head>
  <body>
    <div class="box">
      <div class="left"></div>
      <div class="right"></div>
    </div>
  </body>
</html>

彈性布局若是要實(shí)現(xiàn)右邊固定的效果,則加上如下代碼即可

.box {
        display: flex;
        flex-direction: row-reverse;
      }
二、左中右(左右不變,中間自適應(yīng))
float布局
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      .left {
        width: 200px;
        height: 200px;
        background-color: red;
        float: left;
      }
      .right {
        width: 200px;
        height: 200px;
        background-color: red;
        float: right;
      }
      .center {
        background-color: blue;
        height: 200px;
      }
    </style>
  </head>
  <body>
    <div class="left"></div>
    <div class="right"></div>
    <div class="center"></div>
  </body>
</html>

絕對(duì)定位
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      .left {
        width: 200px;
        height: 200px;
        background-color: red;
        position: absolute;
        left: 0;
      }
      .right {
        width: 200px;
        height: 200px;
        background-color: red;
        position: absolute;
        right: 0;
      }
      .center {
        background-color: blue;
        height: 200px;
        width: 100%;
      }
    </style>
  </head>
  <body>
    <div class="left"></div>

    <div class="right"></div>
    <div class="center"></div>
  </body>
</html>

彈性布局
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      .box {
        display: flex;
      }
      .left {
        width: 200px;
        height: 200px;
        background-color: red;
      }
      .right {
        width: 200px;
        height: 200px;
        background-color: red;
      }
      .center {
        background-color: blue;
        flex: 1;
      }
    </style>
  </head>
  <body>
    <div class="box">
      <div class="left"></div>
      <div class="center"></div>
      <div class="right"></div>
    </div>
  </body>
</html>

前端常見面試八股文

三、上中下(上下不變,中間自適應(yīng))

在寫之前,首先說明一點(diǎn),關(guān)于元素的寬度,若是沒給出,在瀏覽器中會(huì)自動(dòng)給出寬度, 但是關(guān)于高度并不會(huì)自動(dòng)給出高度,所以上面的彈性布局列子中,沒給出高度但是還是顯示出了盒子是因?yàn)楹凶拥膬?nèi)容已經(jīng)被撐開了,但是高度并不會(huì)自動(dòng)分配

絕對(duì)定位
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      .top {
        height: 200px;
        width: 100%;
        background-color: red;
        position: absolute;
        top: 0;
      }
      .bottom {
        height: 200px;
        width: 100%;
        background-color: red;
        position: absolute;
        bottom: 0;
      }
      .center {
        position: absolute;
        background-color: blue;
        top: 200px;
        bottom: 200px;
        width: 100%;
      }
    </style>
  </head>
  <body>
    <div class="top"></div>
    <div class="center"></div>
    <div class="bottom"></div>
  </body>
</html>

彈性布局
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      html,
      body {
        height: 100%;
      }
      .box {
        height: 100%;
        display: flex;
        flex-direction: column;
      }
      .top {
        width: 100%;
        height: 200px;
        background-color: red;
      }
      .bottom {
        width: 100%;
        height: 200px;
        background-color: red;
      }
      .center {
        flex: 1;
        background-color: blue;
      }
    </style>
  </head>
  <body>
    <div class="box">
      <div class="top"></div>
      <div class="center"></div>
      <div class="bottom"></div>
    </div>
  </body>
</html>

額外補(bǔ)充點(diǎn):

文檔流和文本流

個(gè)人對(duì)文檔流的理解就是盒模型中的概念。
文檔流就是在瀏覽器中的規(guī)則,塊狀元素的規(guī)則是從上到下排序的,行內(nèi)元素是從左到右排序的

文本流:適用于文字之間的規(guī)則

其中我們?cè)谏厦娴牧凶又衒loat、絕對(duì)定位、固定定位、display:flex,都會(huì)讓原本的元素脫離文檔流,在了解相關(guān)的規(guī)則后,我們可以按照自己的想法去布局。

vue篇

1、你怎么理解vue?它是屬于什么模式?

vue.js是一款漸進(jìn)式、多途徑、高性能JavaScript框架,易用、靈活、高效

屬于MVVM(Model-View-ViewModel)模式,也是就model(模型層)、ViewModel(視圖驅(qū)動(dòng)層)、view(視圖層),數(shù)據(jù)在傳遞的時(shí)候雙向傳遞

2、v-if和v-show的區(qū)別

相同點(diǎn):v-if與v-show都可以動(dòng)態(tài)控制dom元素顯示隱藏

不同點(diǎn):v-if顯示隱藏是將dom元素整個(gè)添加或刪除,而v-show隱藏則是為該元素添加css–display:none,dom元素還在。

性能角度上:v-if有更高的切換消耗;v-show有更高的初始渲染消耗;

使用場(chǎng)景:v-if適合運(yùn)營條件不大可能改變;v-show適合頻繁切換。

3、vue響應(yīng)式原理和雙向綁定原理

在了解該知識(shí)點(diǎn)前,先做一個(gè)只是鋪墊,詳細(xì)介紹下Object.defineProperty的用法

Object.defineProperty詳解

Object.defineProperty是es5的方法,作用是直接在一個(gè)對(duì)象上定義一個(gè)新屬性,或者修改一個(gè)對(duì)象的現(xiàn)有屬性,并返回這個(gè)對(duì)象(只能用在對(duì)象上,不能用在數(shù)組上)

1、語法

Object.defineProperty(obj, prop, descriptor)

2、參數(shù)
  • obj:必需。目標(biāo)對(duì)象
  • prop:必需。需定義或修改的屬性的名字
  • descriptor:必需。目標(biāo)屬性所擁有的特性
3、屬性用法

修改某個(gè)屬性的值時(shí),給這個(gè)屬性添加一些特性。

let person = {}; 
Object.defineProperty(person, 'name', 
    writable: true || false,
    configurable: true || false,
    enumerable: true || false,
    value:'gjf'
});

屬性詳解:

writable:是否可以被重寫,true可以重寫,false不能重寫,默認(rèn)為false。
enumerable:是否可以被枚舉(使用for…in或Object.keys())。設(shè)置為true可以被枚舉;設(shè)置為false,不能被枚舉。默認(rèn)為false。
value:值可以使任意類型的值,默認(rèn)為undefined
configurable:是否可以刪除目標(biāo)屬性或是否可以再次修改屬性的特性(writable, configurable, enumerable)。設(shè)置為true可以被刪除或可以重新設(shè)置特性;設(shè)置為false,不能被可以被刪除或不可以重新設(shè)置特性。默認(rèn)為false。

vue響應(yīng)式原理(vue雙向綁定的原理)
vue2.x中

object.defineProperty是屬性級(jí)別的攔截,會(huì)在set、get的方法中進(jìn)行攔截操作

當(dāng)把一個(gè)普通的js對(duì)象傳入vue實(shí)列作為data選項(xiàng)時(shí),vue會(huì)遍歷此對(duì)象的所有的property,并使用object.defineProperty,把這些property全部轉(zhuǎn)換為getter/setter。然后watcher會(huì)監(jiān)聽setter的變化,每當(dāng)setter變化后,就會(huì)進(jìn)行視圖層的重新渲染,達(dá)到響應(yīng)式效果

前端常見面試八股文

在這里主要我改動(dòng)了data中的某一個(gè)值,那么整個(gè)響應(yīng)式的狀態(tài)又會(huì)重新開始進(jìn)行setter、監(jiān)聽,相對(duì)來說浪費(fèi)資源

<body>
    <div id="app">
        hellow
    </div>

    <script>
        let data ={
            name: 'tom',
            age:123
        }
        let vm ={}
        var id= document.getElementById('app')
        Object.keys(data).forEach((k)=>{
             Object.defineProperty(vm,k,{
                 get:function(){
                     id.textContent=data[k]
                     return data[k]
                 },
                 set:function(e){
                   data[k]=e
                   id.textContent=data[k]
                 }
             })
        })
    </script>

若是data中有多個(gè)值,則會(huì)進(jìn)行循環(huán)輸出,來監(jiān)聽每一個(gè)值的變化

vue3.x中

Proxy(代理)

對(duì)象級(jí)別的攔截

改變語法原有的規(guī)則,可以自定義其規(guī)則(元編程)

target:代理處理的目標(biāo)對(duì)象

handler: 代理處理的方法

let obj =new Proxy(target,handler)

自定義對(duì)象屬性的獲取、賦值、枚舉、函數(shù)調(diào)用等功能

  <body>
    <div id="app">
        hellow
    </div>

    <script>
        let data ={
            name: 'tom',
            age:123
        }
        let vm ={}
        var id= document.getElementById('app')
        

        const vs =new Proxy(data,{
            get(target,key){
                id.textContent=target[key]
            },
            set(target,key,newValue){
                if(target[key] === newValue){
                    return
                }
                target[key]=newValue
                id.textContent=target[key]
            }
        })
    </script>

這里去監(jiān)聽每一個(gè)屬性的時(shí)候不需要用到循環(huán)的方法,簡(jiǎn)單的說就是誰改變就去監(jiān)聽誰,在原用的基礎(chǔ)上提升了性能

4、虛擬DOM和diff算法

參考b站 https://www.bilibili.com/video/BV1dV411a7mT/

1、認(rèn)識(shí)虛擬DOM

沒有虛擬DOM之前: 數(shù)據(jù)改變=>操作DOM=>視圖更新

使用虛擬DOM后:數(shù)據(jù)改變=>虛擬DOM(計(jì)算出變更)=>操作DOM=>視圖更新

虛擬DOM:用js模擬DOM結(jié)構(gòu)

如下圖,左邊是實(shí)際DOM元素,而右邊是js模擬的DOM結(jié)構(gòu)

前端常見面試八股文

2、虛擬DOM的好處

每當(dāng)dom改變的時(shí)候,不會(huì)全部都進(jìn)行DOM改變,而是被改動(dòng)的地方進(jìn)行改變

前端常見面試八股文

這里就是用js代碼去模擬DOM結(jié)構(gòu)

用虛擬DOM計(jì)算出最小的變化,然后再去更新變化的實(shí)際DOM

3、認(rèn)識(shí)diff算法基本概念

是兩個(gè)虛擬DOM之間的一種比較

1、虛擬DOM之間會(huì)平級(jí)別對(duì)比 ,深度遍歷進(jìn)行對(duì)比

2、對(duì)比的同時(shí)會(huì)通過key值進(jìn)行判斷,判斷元素是僅僅位置發(fā)生改變還是需要整個(gè)替換或刪除

3、如果不是元素發(fā)生改變的話,再對(duì)內(nèi)容進(jìn)行對(duì)比,如果是內(nèi)容發(fā)生改變的話,就直接修改內(nèi)容

詳細(xì)的算法介紹就需要另外研究了

5、vue的生命周期與不同階段的作用

vue的生命周期有:beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、beforeDestroy、destroyed

作用

beforeCreate:可以加載loading事件,在加載實(shí)列的時(shí)候被觸發(fā)

created:初始化完成時(shí)的事件在這里,這里也結(jié)束loading事件,異步請(qǐng)求也適合在這里被調(diào)用

mounted:可以掛載元素,過去DOM節(jié)點(diǎn)

updated:對(duì)數(shù)據(jù)統(tǒng)一處理,這里寫上對(duì)應(yīng)的函數(shù)即可

beforeDestroy:可以確定一個(gè)停止事件的確認(rèn)框

nextTick:更新數(shù)據(jù)后,立即操作dom

6、vue組件之間的傳值方式

1、父子組件傳值方式
父組件向子組件傳值

1、傳值前現(xiàn)在父組件中導(dǎo)入需要的子組件,然后在父組件中傳入值、

2、子組件需要在props:{}中定義傳過來的值,以及類型,然后就可以在其他地方使用

父組件

前端常見面試八股文

子組件:
前端常見面試八股文

子組件向父組件傳值

就是在子組件中通過$emit(傳向父組件事件,傳向父組件值)向父組件傳入值,父組件接受改變即可

子組件:

<template>
  <div>
    {{ sendData }}

    <button @click="hand">點(diǎn)擊</button>
  </div>
</template>

<script>
export default {
  name: "Son",
  props: ["sendData"],
  data() {
    return {
      city: "上海",
    };
  },
  methods: {
    hand: function () {
      console.log(this.city);
      this.$emit("change", this.city);
    },
  },

 
};

父組件:

<template>
  <div class="home">
    <Son :sendData="msg" @change="changeFather" />
  </div>
</template>

<script>
// @ is an alias to /src
import Son from "@/components/son.vue";

export default {
  name: "Home",
  components: {
    Son,
  },
  data() {
    return {
      msg: "北京",
    };
  },
  methods: {
    changeFather: function (city) {
      console.log(this.msg);
      this.msg = city;
    },
  },
};
</script>

2、兄弟組件傳值方式
1、bus總線方法

1、定義一個(gè)bus.js ,內(nèi)容如下

import Vue from "vue";
const Bus = new Vue();
export default Bus;

2、然后在main.js中添加如下代碼

import bus from "./components/bus";
Vue.use(bus);
Vue.prototype.$bus = bus;

3、在需要傳值的兄弟組件中,通過 b u s . bus. bus.emit(傳入方法,傳入值),方式傳入

<template>
  <div>
    <p>child1</p>
    <button @click="hand1">點(diǎn)擊</button>
  </div>
</template>

<script>
export default {
  name: "Child1",
  data() {
    return {
      msg: "666",
    };
  },
  methods: {
      hand1: function () {
          this.$bus.$emit('get',this.msg)
      }
  }
};
</script>

<style></style>

4、在接收的組件中在mouted生命周期中,用 b u s . bus. bus.on(傳過來的方法名,回調(diào)函數(shù)),來進(jìn)行接收

<template>
  <div>
    <p>child2</p>
    <p>{{ cmsg }}</p>
  </div>
</template>

<script>
export default {
  name: "Child2",
  data() {
    return {
      cmsg: "",
    };
  },
  mounted: function () {
    this.$bus.$on("get", (data) => {
      console.log(data);
      this.cmsg = data;
    });
  },
};
</script>

<style></style>

2、 可以子組件先傳入父組件,然后再由父組件再傳給另一個(gè)子組件

7、methods、computed 和 watch 的區(qū)別和運(yùn)用的場(chǎng)景?

1、methods、computed的區(qū)別

在頁面進(jìn)行渲染的時(shí)候,methos中所有的方法都會(huì)被重新調(diào)用,而computed,只會(huì)在其被依賴項(xiàng)改變的時(shí)候才會(huì)重新計(jì)算

2、computed和watch的區(qū)別

computed是計(jì)算屬性,有如下特點(diǎn):

1、計(jì)算屬性定義的屬性可以不用在data中定義,在DOM中直接使用。

2、支持緩存,只有在數(shù)據(jù)依賴項(xiàng)發(fā)生改變的時(shí)候,才會(huì)重新計(jì)算。

3、不支持異步操作,在computed中異步操作無效,無法監(jiān)聽數(shù)據(jù)的變化

使用方法如下:

前端常見面試八股文

watch是監(jiān)聽屬性,特點(diǎn)如下:

1、不支持緩存,只要數(shù)據(jù)變化,就會(huì)直接觸發(fā)響應(yīng)的操作

2、在watch內(nèi)支持異步操作

3、監(jiān)聽的函數(shù)接受兩個(gè)參數(shù),第一個(gè)是參數(shù)最新的值,第二個(gè)是參數(shù)輸入之前的值

使用方法如下:

前端常見面試八股文

前端常見面試八股文

總結(jié):

  • 如果一個(gè)數(shù)據(jù)需要經(jīng)過復(fù)雜計(jì)算就用 computed
  • 如果一個(gè)數(shù)據(jù)需要被監(jiān)聽并且對(duì)數(shù)據(jù)做一些操作就用 watch

8、在哪個(gè)生命周期內(nèi)調(diào)用異步請(qǐng)求?

在created、beforeMount、mounted都可以發(fā)送異步請(qǐng)求,因?yàn)榭梢詫⒎?wù)端端返回的數(shù)據(jù)進(jìn)行賦值。但是最常用的是在 created 鉤子函數(shù)中調(diào)用異步請(qǐng)求,因?yàn)樵?created 鉤子函數(shù)中調(diào)用異步請(qǐng)求

有兩個(gè)優(yōu)點(diǎn):
第一點(diǎn):能更快獲取到服務(wù)端數(shù)據(jù),減少頁面 loading 時(shí)間;
第二點(diǎn):放在 created 中有助于一致性,因?yàn)閟sr 不支持 beforeMount 、mounted 鉤子函數(shù)。

9、對(duì) keep-alive 的了解?

前端常見面試八股文

10、組件中 data 為什么是一個(gè)函數(shù)?

因?yàn)関ue的組件可能在不同的頁面中會(huì)被調(diào)用,是一個(gè)函數(shù)的話每一次的調(diào)用就會(huì)執(zhí)行data函數(shù)并返回新的數(shù)據(jù),這樣就可以避免多處調(diào)用之間的數(shù)據(jù)污染

11、Vue 中的 key 有什么作用?

我們可以知道,通常我們?cè)谑褂胿-for的時(shí)候會(huì)去標(biāo)明key值,但是不建議去使用其數(shù)組的下標(biāo)index作為key值。

在上面中已經(jīng)簡(jiǎn)單的介紹的虛擬DOM、diff算法,key值主要是為了diff算法服務(wù)的,給每一個(gè)循環(huán)出的item綁定一個(gè)key值,做唯一標(biāo)識(shí)

好處如下:

1、判斷新舊VDOM節(jié)點(diǎn)在邏輯上是不是同一個(gè)對(duì)象

2、準(zhǔn)確。因?yàn)閗ey的特性是唯一性。所以如果不加key,采用index的標(biāo)記法,那么vue會(huì)選擇復(fù)用同類型節(jié)點(diǎn)(Vue的就地更新策略),導(dǎo)致之前節(jié)點(diǎn)的狀態(tài)被保留下來,會(huì)產(chǎn)生一系列的bug.

3、快速。在元素list一直變化的情況下,key值設(shè)置唯一時(shí),能很精確找到/找不到變更元素,若使用index標(biāo)記,要遍歷vnode,時(shí)間長。

  • Vue的策略是不對(duì)dom直接更新,而是先比較oldDOM和VDOM 之間的區(qū)別,通過比較差別并且復(fù)用沒有改變的dom,來快速的構(gòu)建新的dom并渲染到頁面

12、vue中如何動(dòng)態(tài)的設(shè)置class、style?

//動(dòng)態(tài)class對(duì)象
<div :class="{ 'isActive': true, 'red': isRed }"></div>
//動(dòng)態(tài)style對(duì)象
<div :style="{ color: bgColor, fontSize: '18px' }"></div>
//動(dòng)態(tài)class數(shù)組
<div :class="['is-active', isRed ? 'red' : '' ]"></div>
//動(dòng)態(tài)style數(shù)組
<div :style="[{ color: bgColor, fontSize: '18px' }, { fontWeight: '500' }]"></div>

13、為什么v-if和v-for不建議用在同一標(biāo)簽?

因?yàn)関-for的優(yōu)先級(jí)高于v-if,程序會(huì)先執(zhí)行v-for的操作,然后再去執(zhí)行v-if,每次都會(huì)先去循環(huán)再進(jìn)行條件判斷,就會(huì)帶來性能上的浪費(fèi)

14、不需要響應(yīng)式的數(shù)據(jù)應(yīng)該怎么處理?

// 方法一:將數(shù)據(jù)定義在data之外
data () {
    this.list1 = { xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx }
    this.list2 = { xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx }
    this.list3 = { xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx }
    this.list4 = { xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx }
    this.list5 = { xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx }
    return {}
 }
    
// 方法二:Object.freeze()
data () {
    return {
        list1: Object.freeze({xxxxxxxxxxxxxxxxxxxxxxxx}),
        list2: Object.freeze({xxxxxxxxxxxxxxxxxxxxxxxx}),
        list3: Object.freeze({xxxxxxxxxxxxxxxxxxxxxxxx}),
        list4: Object.freeze({xxxxxxxxxxxxxxxxxxxxxxxx}),
        list5: Object.freeze({xxxxxxxxxxxxxxxxxxxxxxxx}),
    }
 }


前端常見面試八股文

15、watch有哪些屬性,分別有什么用?

1、正常監(jiān)聽

<div id="app">
<input tyoe="text" v-model="brand">
</div>


new Vue({
	el:"#app",
	data:{
		brand:'nike',
	},
	watch:{
		cityname(newbrand,oldbrand){
			//...
		}
	}
})

2、immediate

watch時(shí)有一個(gè)特點(diǎn),就是當(dāng)值第一次綁定的時(shí)候,不會(huì)執(zhí)行監(jiān)聽函數(shù),只有值發(fā)生改變才會(huì)執(zhí)行。如果我們需要在最初綁定值的時(shí)候也執(zhí)行函數(shù),則就需要用到immediate屬性。

<body>
<div id="app">
    <input type="text" v-model="num">
</div>
<script src="vue.js"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            num: 1
        },
        watch: {
            num: {
            	// 數(shù)據(jù)發(fā)生變化就會(huì)調(diào)用這個(gè)函數(shù)  
                handler(newVal, oldVal) {
                    console.log('oldVal:', oldVal)
                    console.log('newVal:', newVal)
                },
                // 立即處理 進(jìn)入頁面就觸發(fā)
                immediate: true
            }
        }
    })
</script>
</body>
普通的監(jiān)聽時(shí)候?qū)懙恼?qǐng)示寫的函數(shù)其實(shí)就是在寫這個(gè)handler方法。
immediate表示在watch中首次綁定的時(shí)候,是否執(zhí)行handler,值為true則表示在watch中聲明的時(shí)候,就立即執(zhí)行handler方法,值為false,則和一般使用watch一樣,在數(shù)據(jù)發(fā)生變化的時(shí)候才執(zhí)行handler。

3、deep

深度監(jiān)聽,當(dāng)需要監(jiān)聽一個(gè)對(duì)象的改變時(shí),普通的watch方法無法監(jiān)聽到對(duì)象內(nèi)部屬性的改變,只有data中的數(shù)據(jù)才能夠監(jiān)聽到變化,此時(shí)就需要deep屬性對(duì)對(duì)象進(jìn)行深度監(jiān)聽。

<div id="app">
<input tyoe="text" v-model="brand">
</div>


new Vue({
	el:"#app",
	data:{
		brand:(name:'nike',id:"no1"),
	},
	watch:{
		cityname:{
			handler:(newbrand,oldbrand){
			//...
		},
		deep:true,
		immediate:true
		}
	}
})

vue-router篇

1、this.$router和this.$route的區(qū)別

this.$router:是全局路由器的router的實(shí)列,可以在任何組件內(nèi)進(jìn)行訪問,就是跳轉(zhuǎn)路由的方法,里面有很多的方法比如


      this.$router.push()
      this.$router.replace()
      this.$router.go()

his.$route:包含當(dāng)前激活的路由狀態(tài)信息、url解析得到的信息

**1.$route.path**
      字符串,對(duì)應(yīng)當(dāng)前路由的路徑,總是解析為絕對(duì)路徑,如 "/foo/bar"。
**2.$route.params**
      一個(gè) key/value 對(duì)象,包含了 動(dòng)態(tài)片段 和 全匹配片段,
      如果沒有路由參數(shù),就是一個(gè)空對(duì)象。
**3.$route.query**
      一個(gè) key/value 對(duì)象,表示 URL 查詢參數(shù)。
      例如,對(duì)于路徑 /foo?user=1,則有 $route.query.user == 1,
      如果沒有查詢參數(shù),則是個(gè)空對(duì)象。
**4.$route.hash**
      當(dāng)前路由的 hash 值 (不帶 #) ,如果沒有 hash 值,則為空字符串。錨點(diǎn)
**5.$route.fullPath**
      完成解析后的 URL,包含查詢參數(shù)和 hash 的完整路徑。
**6.$route.matched**
      數(shù)組,包含當(dāng)前匹配的路徑中所包含的所有片段所對(duì)應(yīng)的配置參數(shù)對(duì)象。
**7.$route.name    當(dāng)前路徑名字**
**8.$route.meta  路由元信息

2、active-class 是哪個(gè)組件的屬性?

active-class是vue-router模塊的router-link組件中的屬性,用來做選中樣式的切換;

用法:
1、直接在路由js文件中配置linkActiveClass

export default new Router({
  linkActiveClass: 'active'
})

2、在router-link中寫入active-class

<router-link to="/home" class="menu-home" active-class="active">首頁</router-link>

這里這個(gè)路由的樣式可以直接在style中去寫對(duì)應(yīng)的類名就好了

如果兩個(gè)路由都是用一樣的樣式,比如如下情況:

<div class="menu-btn">
  <router-link to="/" class="menu-home" active-class="active">
    首頁
  </router-link>
</div>
<div class="menu-btn">
  <router-link to="/my" class="menu-my" active-class="active">
    我的
  </router-link>
</div>

這樣跳轉(zhuǎn)后兩個(gè)router-link都會(huì)有顯示的樣式,可能是因?yàn)?to=“/” 引起的,active-class選擇樣式時(shí)根據(jù)路由中的路徑去匹配,然后顯示,例如在my頁面中,路由為localhost:8080/#/my,那么to=“/”和to=”/my"都可以匹配到,所有都會(huì)激活選中樣式

解決辦法

a.直接在路由js文件中配置linkActiveClass

export default new Router({
  linkExactActiveClass: 'active',
})

b.在router-link中寫入exact

<router-link to="/" class="menu-home" active-class="active" exact>首頁</router-link>

3、路由傳參的方式與動(dòng)態(tài)路由匹配

介紹前我們先了路由的兩中形式

  • 編程式的導(dǎo)航 router.push

  • 聲明式的導(dǎo)航 <router-link>

對(duì)于參數(shù)的傳遞主要是用對(duì)象的方式去寫的,可分為命名路由、查詢參數(shù)

命名路由

使用前提:在注冊(cè)路由的地方需要給路由命名

 {
    path: "/",
    name: "Home",
    component: Home,
  },

命名路由搭配著params來進(jìn)行傳遞,如下

this.$router.push({ name: 'Home', params: { userId: 123 }})
<router-link :to="{ name: 'Home', params: { userId: 1111}}">click to news page</router-link>

在目標(biāo)頁面接收

this。$route.params.userId
查詢參數(shù)

查詢參數(shù)其實(shí)就是在路由地址后面帶上參數(shù)和傳統(tǒng)的url參數(shù)一致的,也就是傳遞的參數(shù)會(huì)出現(xiàn)在url地址欄上

注意:name、path可以和query搭配,params只能和name搭配

用法:

this.$router.push({ path: 'Home', query: { userId: 123 }});
<router-link :to="{ path: 'Home', query: { userId: 1111}}">click to news page</router-link>

接收:

this.$route.query.userId
動(dòng)態(tài)路由匹配

常見場(chǎng)景:當(dāng)我們有一個(gè)通用組件,對(duì)應(yīng)不同ID共和不相同的客戶,都要使用這個(gè)組件來渲染,我們就可以使用路由中的 動(dòng)態(tài)路參數(shù)來達(dá)到這個(gè)效果,一個(gè)路徑參數(shù)使用:進(jìn)行標(biāo)記,每當(dāng)匹配到一個(gè)路由,參數(shù)值就會(huì)被設(shè)置

可以用this.$route.params去接收參數(shù)的值

注意:當(dāng)使用該方法時(shí),原組件的實(shí)列會(huì)被復(fù)用,但是組件的生命周期鉤子不會(huì)被調(diào)用,簡(jiǎn)單列子如下

寫跳轉(zhuǎn)的組件:

  <div>
    <p><router-link to="/about/1">user1</router-link></p>
    <p><router-link to="/about/2">user2</router-link></p>
    <p><router-link to="/about/3">user3</router-link></p>
  </div>

路由寫法:

  {
    path: "/about/:id",
    name: "About",

    component: () => import("../views/About.vue"),
  },

在目標(biāo)組件用 {{ this.$route.params.id }}進(jìn)行參數(shù)接收即可

關(guān)于在watch中$route(to, from)不生效

這里我想監(jiān)聽組件的路由變化,使用watch去監(jiān)聽$route(to, from)發(fā)現(xiàn)不生效,解決辦法參考這篇文章

https://blog.csdn.net/u010227042/article/details/107961248

路由組件傳參

當(dāng)組件中使用 $route 會(huì)與路由緊密耦合,這限制了組件的靈活性,因?yàn)樗荒苡糜谔囟ǖ?URL。雖然這不一定是件壞事,但我們可以通過 props 配置來解除這種行為:

1、如果 props 被設(shè)置為 true,route.params 將會(huì)被設(shè)置為組件屬性

這里用動(dòng)態(tài)路由匹配做列子,同樣傳入的是id

在目標(biāo)跳轉(zhuǎn)的路由中:

  {
    path: "/about/:id",
    name: "About",
    props: true,
    component: () => import("../views/About.vue"),
  },

目標(biāo)路由中props接收然后直接用:

export default {
  name: "About",
  props: ["id"],
};
2、對(duì)象模式
  {
        //對(duì)象模式
        path:'/about/chilrenRoute2/:id',
        component:chilrenRoute2,
        props: { userName: 'userName'}
      }

  export default {
    props:['userName']
  }

獲?。?/p>

  <p>  通過 props傳遞——對(duì)象 , 獲取路由組件傳遞參數(shù)值 /about/chilrenRoute2/:id 路由的id值:  {{ this.userName }}</p>


3、函數(shù)模式

函數(shù)模式的路由配置中,props屬性是函數(shù),這個(gè)函數(shù)返回一個(gè)對(duì)象。
在函數(shù)模式中,可以有一個(gè)參數(shù),這個(gè)參數(shù)就是route對(duì)象,里面存儲(chǔ)的是路由的相關(guān)攜帶信息。

     {
        //函數(shù)模式
        path:'/about/chilrenRoute2/:id',
        component:chilrenRoute2,
        props: function (route){

          //route 是 $route對(duì)象
            return {
              userName:'userName',
              querys: route.params.id
            }

        }
      }


js代碼:

  export default {
    // props:['id']
    // props:['userName']
    props:['userName','querys']
  }

獲取:

  <p>  通過 props傳遞——函數(shù)模式 , 獲取路由組件傳遞參數(shù)值 /about/chilrenRoute2/:id 路由的id值:  {{ this.userName }} ,  {{ this.querys }} ,  {{ $route.params }}</p>

4、vue-router 有哪幾種導(dǎo)航鉤子(導(dǎo)航守衛(wèi))?

1、全局守衛(wèi): router.beforeEach

2、全局解析守衛(wèi): router.beforeResolve

3、全局后置鉤子: router.afterEach

4、路由獨(dú)享的守衛(wèi): beforeEnter

5、組件內(nèi)的守衛(wèi): beforeRouteEnter、beforeRouteUpdate (2.2 新增)、beforeRouteLeave

beforeRouteEnter
  // 在渲染該組件的對(duì)應(yīng)路由被 confirm 前調(diào)用
  // 不!能!獲取組件實(shí)例 `this`
  // 因?yàn)楫?dāng)守衛(wèi)執(zhí)行前,組件實(shí)例還沒被創(chuàng)建
  雖然無法直接獲取組件實(shí)力
  但是我們可以通過next參數(shù)的回調(diào)函數(shù)獲取到當(dāng)前實(shí)例進(jìn)行操作
  beforeRouteEnter: (to, from, next) => {
    next((vm) => {
      //vm就是當(dāng)前組件實(shí)例
    });
  }
beforeRouteUpdate
  // 在當(dāng)前路由改變,但是該組件被復(fù)用時(shí)調(diào)用
  // 舉例來說,對(duì)于一個(gè)帶有動(dòng)態(tài)參數(shù)的路徑 /foo/:id,在 /foo/1 和 /foo/2 之間跳轉(zhuǎn)的時(shí)候,
  // 由于會(huì)渲染同樣的 Foo 組件,因此組件實(shí)例會(huì)被復(fù)用。而這個(gè)鉤子就會(huì)在這個(gè)情況下被調(diào)用。
  // 可以訪問組件實(shí)例 `this`
beforeRouteLeave
  // 導(dǎo)航離開該組件的對(duì)應(yīng)路由時(shí)調(diào)用
  // 可以訪問組件實(shí)例 `this`
詳細(xì)介紹:

https://zhuanlan.zhihu.com/p/54112006

5、vue-router歷史模式和hash模式的區(qū)別?

hash模式:

url里面帶有#號(hào),開發(fā)中默認(rèn)的就是hash模式,hash雖然出現(xiàn)在URL中,但是不會(huì)被包括在HTTP請(qǐng)求中,所以改變hash不會(huì)重新刷新頁面

路由的哈希模式就是利用了window.onhashchange事件,也就是url中的hash值(#號(hào)后面的值)如果有變化,就會(huì)自動(dòng)調(diào)用hashchange的監(jiān)聽事件,在hashchange的監(jiān)聽事件內(nèi)可以得到改變后的url,這樣就能找到對(duì)應(yīng)頁面進(jìn)行加載

window.addEventListener('hashchange', () => {
   // 把改變后的url地址欄的url賦值給data的響應(yīng)式數(shù)據(jù)current,調(diào)用router-view去加載對(duì)應(yīng)的頁面
   this.data.current = window.location.hash.substr(1)
})
歷史模式:

利用了H5新增的pushState()、replaceState()方法。當(dāng)這兩個(gè)方法執(zhí)行時(shí),只能改變當(dāng)前地址欄的URL,但是瀏覽器不會(huì)像后端發(fā)起請(qǐng)求,也不會(huì)觸發(fā)popstate事件的執(zhí)行。

也就是說,完成URL跳轉(zhuǎn)而無需重新加載頁面,由于vue是單頁面的形式,當(dāng)后臺(tái)沒有正確配置的時(shí)候,需要我們自己去配置404頁面

前端常見面試八股文

6、動(dòng)態(tài)路由添加

最好和vuex做一個(gè)案列理解

7、vue-router怎么重定向的?

用redirect即可定位到相對(duì)位置

const routes = [
  {
    path: '/users/:id/posts',
    redirect: to => {
      // 方法接收目標(biāo)路由作為參數(shù)
      // return 重定向的字符串路徑/路徑對(duì)象
    },
  },
]

8、vue-router實(shí)現(xiàn)路由懶加載

路由懶加載也就是延遲加載沒在需要的時(shí)候記加載,隨用隨載,也是前端優(yōu)化的一種手段

懶加載的實(shí)現(xiàn)方法:

1、ES6標(biāo)準(zhǔn)語法import()
const Foo = () => import('../components/Foo')
const Aoo = () => import('../components/Aoo')

export default new Router({
    routes: [
        {
            path: '/Foo',
            name: 'Foo',
            component: Foo
        },
        {
            path: '/Aoo',
            name: 'Aoo',
            component: Aoo
        }
    ]
})

就是定義一個(gè)變量,變量就是路由文件,然后在路由中隨用隨導(dǎo)入

2、Vue異步加載技術(shù)
 	1:vue-router配置路由,使用vue的異步組件技術(shù),可以實(shí)現(xiàn)懶加載,此時(shí)一個(gè)組件會(huì)生成一個(gè)js文件。
 	2:component: resolve => require(['放入需要加載的路由地址'], resolve)
  {
      path: '/problem',
      name: 'problem',
      component: resolve => require(['../pages/home/problemList'], resolve)
    }

9、Vue-router跳轉(zhuǎn)和location.href有什么區(qū)別?

1、vue-router使用pushState進(jìn)行路由更新,靜態(tài)跳轉(zhuǎn),頁面不會(huì)重新加載;location.href會(huì)觸發(fā)瀏覽器,頁面重新加載一次

2、vue-router使用diff算法,實(shí)現(xiàn)按需加載,減少dom操作

3、vue-router是路由跳轉(zhuǎn)或同一個(gè)頁面跳轉(zhuǎn);location.href是不同頁面間跳轉(zhuǎn);

4、vue-router是異步加載this.$nextTick(()=>{獲取url});location.href是同步加載

10、怎么配置404頁面?

在router.js中 路由是從上到下執(zhí)行的 只需要在最后一行把path寫成 * 并且指定一個(gè)404.vue頁面即可

如何觸發(fā)404頁面,比如你的域名是http://localhost:8080/,當(dāng)你進(jìn)入一個(gè)沒有聲明/匹配的路由頁面時(shí)就會(huì)跳到404頁面,
比如訪問了http://localhost:8080/無此頁面,就會(huì)跳到404頁面,如果沒有聲明一個(gè)404頁面,那就會(huì)跳到一個(gè)空白頁面

   {
            path: '*',
            name: '/404',
            component: resolve => require(['@/components/404.vue'], resolve),
        },

11、切換路由時(shí)需要保存草稿的功能,怎么實(shí)現(xiàn)?

1、用組件內(nèi)的守衛(wèi)中的:beforeRouteLeave去實(shí)現(xiàn)

keep-alivebeforeRouteLeave (to, from, next) {
  if(用戶已經(jīng)輸入信息){
    //出現(xiàn)彈窗提醒保存草稿,或者自動(dòng)后臺(tái)為其保存
    
  }else{
    next(true);//用戶離開
  }

}

2、使用keep-alive去緩存組件

12、切換到新路由時(shí),頁面要滾動(dòng)到頂部或保持原先的滾動(dòng)位置怎么做呢?

1、使用afterEach

router.afterEach((to,from,next) => {
  window.scrollTo(0,0);
});

2、該功能只能在H5 history下去使用

注意: 這個(gè)功能只在 html5 history 模式下可用。
const router = new vueRouter({
 routes: [...],
 scrollBehavior (to, from, savedPosition) {
  // return 期望滾動(dòng)到哪個(gè)的位置
 }
})
scrollBehavior (to, from, savedPosition) {
 if (savedPosition) {
  return savedPosition
 } else {
  return { x: 0, y: 0 }
 }
}

13、說說vue-router完整的導(dǎo)航解析流程是什么?(選)

1.導(dǎo)航被觸發(fā)
2.在即將離開的組件里調(diào)用beforeRouteLeave守衛(wèi)
3.調(diào)用全局前置守衛(wèi)beforeEach守衛(wèi)
4.在重用的組件里調(diào)用beforeRouteUpdate守衛(wèi) / 調(diào)用路由配置的beforeEnter守衛(wèi)
5.解析異步路由組件
6.在被激活的組件里調(diào)用beforeRouteEnter
7.調(diào)用全局的beforeResolve守衛(wèi)
8.導(dǎo)航被確認(rèn)
9.調(diào)用全局的 afterEach 鉤子
10.觸發(fā)DOM更新
11.用創(chuàng)建好的實(shí)例調(diào)用 beforeRouteEnter 守衛(wèi)中傳給 next 的回調(diào)函數(shù)。

VUEX

要是看不懂官網(wǎng)的列子就看這篇博客入門就好了

https://www.jianshu.com/p/a804606ad8e9

關(guān)于mapState、mapAction等的了解可以看看這篇博客

https://www.cnblogs.com/m2maomao/p/9954640.html文章來源地址http://www.zghlxwxcb.cn/news/detail-405025.html

到了這里,關(guān)于前端常見面試八股文的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 前端面試題八股文匯總(最新)

    前端面試題八股文匯總(最新)

    前言:小伙伴們,本篇文章是博主自己在面試過程中的一些面試題的記錄,自己在總結(jié)回顧記錄的同時(shí)希望也能幫助到你們,可以結(jié)合對(duì)應(yīng)的知識(shí)點(diǎn)去理解和查看!有什么不對(duì)的地方歡迎伙伴們指正!大家一起學(xué)習(xí)!一共有五大回合,如果在后續(xù)面試過程中還會(huì)持續(xù)更新!

    2023年04月08日
    瀏覽(47)
  • C++面試八股文:在C++中,有哪些可執(zhí)行體?

    某日二師兄參加XXX科技公司的C++工程師開發(fā)崗位第14面: 面試官:在C++中,有哪些可執(zhí)行體? 二師兄:可執(zhí)行體? 面試官:也就是可調(diào)用對(duì)象。 二師兄:讓我想一想。函數(shù)、函數(shù)指針、類的靜態(tài)方法、類的成員方法、仿函數(shù)、lambda表達(dá)式。 面試官:能說一說他們之間有什么

    2024年02月08日
    瀏覽(23)
  • C++面試八股文:struct、class和union有哪些區(qū)別?

    某日小二參加XXX科技公司的C++工程師開發(fā)崗位5面: 面試官:struct和class有什么區(qū)別? 小二:在C++中,struct和class的唯一區(qū)別是默認(rèn)的訪問控制。struct默認(rèn)的成員是public的,而class的默認(rèn)成員是private的。 面試官:struct、class和union有哪些區(qū)別? 小二:union和struct、class在內(nèi)存布

    2024年02月07日
    瀏覽(49)
  • C++面試八股文:在C++中,你知道哪些運(yùn)算符?

    某日二師兄參加XXX科技公司的C++工程師開發(fā)崗位第11面: 面試官:在C++中,你都知道都哪些運(yùn)算符? 二師兄:啥?運(yùn)算符? +-*/= 這些算嗎? 面試官:嗯,還有其他的嗎? 二師兄:當(dāng)然還有, +=,-=,*=,/=,== ,還有邏輯運(yùn)算,位運(yùn)算等。 面試官:好的。那你知道這些運(yùn)算的優(yōu)

    2024年02月08日
    瀏覽(17)
  • C++面試八股文:C++中,設(shè)計(jì)一個(gè)類要注意哪些東西?

    某日二師兄參加XXX科技公司的C++工程師開發(fā)崗位第9面: 面試官:C++中,設(shè)計(jì)一個(gè)類要注意哪些東西? 二師兄:設(shè)計(jì)一個(gè)類主要考慮以下幾個(gè)方面:1.面向?qū)ο蟮姆庋b、繼承及多態(tài)。2. big three 或者 big five 。3.運(yùn)算符和函數(shù)重載、靜態(tài)成員、友元、異常處理等相關(guān)問題。 面試官

    2024年02月08日
    瀏覽(25)
  • C++面試八股文:static和const的關(guān)鍵字有哪些用法?

    某日二師兄參加XXX科技公司的C++工程師開發(fā)崗位第7面: 面試官:C++中, static 和 const 的有哪些用法? 二師兄: satic 主要用在以下三個(gè)方面:1.用在全局作用域,修飾的變量或者函數(shù)為靜態(tài)的,限制在本文件內(nèi)使用。2.方法內(nèi)修飾修飾靜態(tài)局部變量,在第一次訪問

    2024年02月08日
    瀏覽(22)
  • 2023最新八股文前端面試題 (css、js、h5c3)

    隨著科技的不斷發(fā)展,前端技術(shù)也在不斷演進(jìn),成為了現(xiàn)代應(yīng)用開發(fā)中不可或缺的一部分。在2023年的前端面試中,面試官們常常會(huì)問及關(guān)于CSS、JS以及HTML5/CSS3等方面的問題,以評(píng)估面試者的技術(shù)深度和實(shí)踐經(jīng)驗(yàn)。下面,讓我們來一起解析這些最新的前端面試題,探討這些技術(shù)的前沿趨勢(shì)。

    2024年02月16日
    瀏覽(28)
  • Java 面試八股文

    參考: 2023年 Java 面試八股文(20w字)_json解析失敗_leader_song的博客-CSDN博客

    2024年02月13日
    瀏覽(26)
  • elasticsearch面試八股文

    es的存儲(chǔ)和更新機(jī)制 Elasticsearch(ES)是一個(gè)開源的分布式搜索和分析引擎,其存儲(chǔ)架構(gòu)和更新機(jī)制如下: 存儲(chǔ)架構(gòu): 索引(Index) :ES的數(shù)據(jù)組織單元是索引,每個(gè)索引可以包含多個(gè)類型(Types),類似于數(shù)據(jù)庫中的表。索引是由一個(gè)或多個(gè)分片(Shard)組成的,用于將數(shù)據(jù)

    2024年02月16日
    瀏覽(32)
  • 吃透SpringMVC面試八股文

    SpringMVC是一種基于 Java 的實(shí)現(xiàn)MVC設(shè)計(jì)模型的請(qǐng)求驅(qū)動(dòng)類型的輕量級(jí)Web框架,屬于Spring框架的一個(gè)模塊。 它通過一套注解,讓一個(gè)簡(jiǎn)單的Java類成為處理請(qǐng)求的控制器,而無須實(shí)現(xiàn)任何接口。同時(shí)它還支持RESTful編程風(fēng)格的請(qǐng)求。 MVC的全名是 Model View Controller ,是模型(model)-視圖

    2023年04月20日
    瀏覽(18)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包