金三銀四,磨礪鋒芒;劍指大廠,揚帆起航(2020年最全大廠WEB前端面試題精選)上

金三銀四,磨礪鋒芒;劍指大廠,揚帆起航(2020年最全大廠WEB前端面試題精選)上

引言

元旦匆匆而過,2020年的春節又接踵而來,你們除了忙的提着褲子加班、年末沖沖衝外,還有着對於明年的迷茫和期待!2019年有多少苦澀心酸,2020年就有更多幸福美好,加油,奧利給!懷着一顆積極向上的心,來面對將來每一天的挑戰!javascript

所謂「兵馬未動,糧草先行」,咱們打響明天的戰役也須要精神食糧來作後勤保障纔是。在此我整理了多位從業者和我在2019年末至2020年初的一廠面試精選題,但願對磨礪鋒芒、奮發向上的小夥伴有所幫助,祝你早日劍指大廠,揚帆起航,奧利給!php

CSS

一、講講盒模型(螞蟻金服 2019.03 招行信用卡 2019.04 美團 做業幫)

盒子模型就是 元素在網頁中的實際佔位,有兩種:標準盒子模型和IE盒子模型css

標準(W3C)盒子模型:內容content+填充padding+邊框border+邊界margin寬高指的是 content 的寬高html

低版本IE盒子模型:內容(content+padding+border)+ 邊界margin,寬高指的是content+padding+border 部分的寬高前端

/* 標準模型 */
box-sizing:content-box;
 /*IE模型*/
box-sizing:border-box;

二、根據盒模型解釋邊距重疊(螞蟻金服 2019.03 圖森將來)

父子元素、兄弟元素,當有外邊距時,會取其中一個邊距的最大值,做爲實際的邊距。
空元素的有上下邊距時,也會取其中更大的一個邊距值,做爲實際的邊距。
這就是邊距重疊。vue

BFC:
概念:塊級格式化上下文
原理:java

  1. 在BFC這個元素垂直方向的邊距會發生重疊
  2. BFC的區域不會與浮動元素的box重疊
  3. BFC在頁面上是一個獨立的容器,其裏外的元素不會互相影響
  4. 計算BFC高度時,浮動元素也會參與計算

三、 寬高比4:3自適應 (螞蟻金服 2019.03 )

垂直方向的padding: 在css中,padding-top或padding-bottom的百分比值是根據容器的width來計算的。node

.wrap{
       position: relative;
       height: 0;  //容器的height設置爲0
       width: 100%;
       padding-top: 75%;  //100%*3/4
}
.wrap > *{
       position: absolute;//容器的內容的全部元素absolute,然子元素內容都將被padding擠出容器
       left: 0;
       top: 0;
       width: 100%;
       height: 100%;
}
+ **padding & calc()**: 跟第一種方法原理相同
​```css
padding-top: calc(100%*9/16);
  • padding & 僞元素
  • 視窗單位: 瀏覽器100vw表示瀏覽器的視窗寬度
width:100vw;
height:calc(100vw*3/4)

四、css選擇器的優先級( 百度前端 搜狐 美團 拼多多 VIVO)

優先級就近原則,同權重狀況下樣式定義最近者爲準react

!important>id >class>tagwebpack

important比內聯優先級高

元素選擇符的權值:元素標籤(派生選擇器):1,class選擇符:10,id選擇符:100,內聯樣式權值最大,爲1000

  1. !important聲明的樣式優先級最高,若是衝突再進行計算。
  2. 若是優先級相同,則選擇最後出現的樣式。
  3. 繼承獲得的樣式的優先級最低。

五、css水平居中 (螞蟻金服、百度前端、字節跳動)

1、對於行內元素:

text-align:center;

2、對於肯定寬度的塊級元素:

(1)margin和width實現水平居中

經常使用(前提:已設置width值):margin-left:auto; margin-right:auto;

(2)絕對定位和margin-left: -(寬度值/2)實現水平居中

固定寬度塊級元素水平居中,經過使用絕對定位,以及設置元素margin-left爲其寬度的一半

.content{

width: 200px;

position: absolute;

left: 50%;

margin-left: -100px; // 該元素寬度的一半,即100px

background-color: aqua;

}

(3)position:absolute + (left=0+top=0+right=0+bottom=0) + margin:auto

.content{

position: absolute;

width: 200px;

top: 0;

right: 0;

bottom: 0;

left: 0;

margin: auto;

}

3、對於未知寬度的塊級元素:

(1)table標籤配合margin左右auto實現水平居中

使用table標籤(或直接將塊級元素設值爲display:table),再經過給該標籤添加左右margin爲auto

(2)inline-block實現水平居中方法

display:inline-block;(或display:inline)和text-align:center;實現水平居中

存在問題:需額外處理inline-block的瀏覽器兼容性(解決inline-block元素的空白間距)

(3)絕對定位實現水平居中

絕對定位+transform,translateX能夠移動本省元素的50%

.content{

position: absolute;

left: 50%;

transform: translateX(-50%); /* 移動元素自己50% */

background: aqua;

}

(4)相對定位實現水平居中

用float或者display把父元素變成行內塊狀元素

.contentParent{

display: inline-block; /* 把父元素轉化爲行內塊狀元素 */

/*float: left; 把父元素轉化爲行內塊狀元素 */

position: relative;

left: 50%;

}

/*目標元素*/

.content{

position: relative;

right: 50%;

background-color:aqua;

}

(5)CSS3的flex實現水平居中方法,法一

.contentParent{

display: flex;

flex-direction: column;

}

.content{

align-self:center;

}

(6)CSS3的flex實現水平居中方法,法二

.contentParent{

display: flex;

}

.content{

margin: auto;

}

(7)CSS3的fit-content配合左右margin爲auto實現水平居中方法

.content{

width: fit-content;

margin-left: auto;

margin-right: auto;

}

參考連接 https://blog.csdn.net/dengdongxia/article/details/80297116

六、CSS3 的 flexbox(彈性盒佈局模型)以及適用場景 (猿輔導)

該佈局模型的目的是提供一種更加高效的方式來對容器中的條目進行佈局、對齊和分配空間。在傳統的佈局方式中,block 佈局是把塊在垂直方向從上到下依次排列的;而 inline 佈局則是在水平方向來排列。彈性盒佈局並無這樣內在的方向限制,能夠由開發人員自由操做。flexbox設置父元素的display屬性爲flex,則子元素都變成flex item,由此能夠控制子元素的排列方式、尺寸、間距等;
試用場景:彈性佈局適合於移動前端開發,在Android和ios上也完美支持。

七、如何畫一個三角形 (星環科技)

左右邊框設置爲透明,長度爲底部邊框的一半。左右邊框長度必須設置,不設置則只有底部一條邊框,是不能展現的。

{width: 0; height: 0; border-top: 40px solid transparent; border-left: 40px solid transparent; border-right: 40px solid transparent; border-bottom: 40px solid #ff0000;}

八、讓一個圖片無限旋轉(螞蟻金服 2019.03)

<img class="circle" src="001.jpg" width="400" height="400"/>

 //infinite 表示動畫無限次播放 linear表示動畫從頭至尾的速度是相同的
 .circle{
         animation: myRotation 5s linear infinite;
     }
@keyframes myRotation {
         from {transform: rotate(0deg);}
         to {transform: rotate(360deg);}
}

九、display 有哪些值?說明他們的做用?

inline默認。此元素會被顯示爲內聯元素,元素先後沒有換行符。

block此元素將顯示爲塊級元素,此元素先後會帶有換行符。

none此元素不會被顯示(隱藏)。

inline-block行內塊元素。(CSS2.1 新增的值)

list-item此元素會做爲列表顯示。

table此元素會做爲塊級表格來顯示(相似table),表格先後帶有換行符

十、position 的值?

absolute

生成絕對定位的元素,相對於 static 定位之外的第一個父元素進行定位。

元素的位置經過 "left", "top", "right" 以及 "bottom" 屬性進行規定。

fixed

生成固定定位的元素,相對於瀏覽器窗口進行定位。(老IE不支持)

元素的位置經過 "left", "top", "right" 以及 "bottom" 屬性進行規定。

relative

生成相對定位的元素,相對於其正常位置進行定位,不脫離文檔流。

所以,"left:20" 會向元素的 LEFT 位置添加 20 像素。

static默認值。

沒有定位,元素出如今正常的文檔流中(忽略 top, bottom, left, right 或者 z-index 聲明)。inherit規定應該從父元素繼承 position 屬性的值。

十一、爲何要初始化 CSS 樣式

由於瀏覽器的兼容問題,不一樣瀏覽器對有些標籤的默認值是不一樣的,若是沒對CSS初始化每每會出現瀏覽器之間的頁面顯示差別。

十二、簡要介紹一下CSS3的新特性

  1. 在佈局方面新增了flex佈局;

  2. 在選擇器方面新增了例如:first-of-type,nth-child等選擇器;

  3. 在盒模型方面添加了box-sizing來改變盒模型,

  4. 在動畫方面增長了animation、2d變換、3d變換等。在顏色方面添加透明、rgba等,

  5. 在字體方面容許嵌入字體和設置字體陰影,同時固然也有盒子的陰影,

  6. 媒體查詢。爲不一樣設備基於它們的能力定義不一樣的樣式。

    @media screen and (min-width:960px) and (max-width:1200px){
    	body{
    		background:yellow;
    	}
    }

1三、元素的顯示與隱藏

元素的顯示隱藏方法不少,不一樣方法的在不一樣的場景下頁面效果不一,對頁面的性能也有不一樣的影響。

元素隱藏方法總結:

  1. 若是但願元素不可見、不佔據空間、資源會加載、DOM 可訪問: display: none

  2. 若是但願元素不可見、不能點擊、但佔據空間、資源會加載,可使用: visibility: hidden

  3. 若是但願元素不可見、不佔據空間、顯隱時能夠又transition淡入淡出效果

    div{ 
    
    		position: absolute;
    
    		visibility: hidden;
    
    		opacity: 0;
    
    		transition: opacity .5s linear;
    
    		background: cyan;
    }
    
    
    div.active{
    		visibility: visible;
    		opacity: 1;
    }

這裏使用visibility: hidden而不是display: none,是由於display: none會影響css3的transition過渡效果。 可是display: none並不會影響cssanimation動畫的效果。

  1. 若是但願元素不可見、能夠點擊、佔據空間,可使用: opacity: 0

  2. 若是但願元素不可見、能夠點擊、不佔據空間,可使用: opacity: 0; position: absolute;

  3. 若是但願元素不可見、不能點擊、佔據空間,可使用: position: relative; z-index: -1;

  4. 若是但願元素不可見、不能點擊、不佔據空間,可使用: position: absolute ; z-index: -1;

1四、display: nonevisibility: hidden的區別

  1. display: none的元素不佔據任何空間,visibility: hidden的元素空間保留;
  2. display: none會影響css3的transition過渡效果,visibility: hidden不會;
  3. display: none隱藏產生重繪 ( repaint ) 和迴流 ( relfow ),visibility: hidden只會觸發重繪;
  4. 株連性:display: none的節點和子孫節點元素全都不可見,visibility: hidden的節點的子孫節點元素能夠設置 visibility: visible顯示。visibility: hidden屬性值具備繼承性,因此子孫元素默認繼承了hidden而隱藏,可是當子孫元素重置爲visibility: visible就不會被隱藏。

JavaScript部分

1. 談談對閉包的理解,閉包的用途,閉包的缺點 (阿里巴巴一面 2019.8)

  • 閉包是指有權訪問另一個函數做用域中的變量的函數
  • 閉包的用途:
  1. 設計私有的方法和變量。
  2. 匿名函數最大的用途是建立閉包,而且還能夠構建命名空間,以減小全局變量的使用。從而使用閉包模塊化代碼,減小全局變量的污染。
  • 閉包的缺點:
  1. 閉包會使得函數中的變量都被保存在內存中,濫用閉包可能致使內存泄漏。解決方法是在函數退出以前,將不使用的局部變量全刪了。
  2. 閉包會在父函數外部,改變父函數內部變量的值。

2. 談談js的垃圾回收機制

  • JavaScript擁有自動的垃圾回收機制,當一個值,在內存中失去引用時,垃圾回收機制會根據特殊的算法找到它,並將其回收,釋放內存。
  • 標記清除算法:
  1. 標記階段,垃圾回收器會從根對象開始遍歷。每個能夠從根對象訪問到的對象都會被添加一個標識,因而這個對象就被標識爲可到達對象。
  2. 清除階段,垃圾回收器會對堆內存從頭至尾進行線性遍歷,若是發現有對象沒有被標識爲可到達對象,那麼就將此對象佔用的內存回收,而且將原來標記爲可到達對象的標識清除,以便進行下一次垃圾回收操做。
  3. 缺點:垃圾收集後有可能會形成大量的 內存碎片
  • 引用計數算法:
  1. 引用計數的含義是跟蹤記錄每一個值被引用的次數,若是沒有引用指向該對象(零引用),對象將被垃圾回收機制回收。
  2. 缺點: 循環引用無法回收。

3. 引發JavaScript內存泄漏的操做有哪些,如何防止內存泄漏?(搜狐一面 2019.12 )

  • 內存泄漏(Memory Leak)是指程序中己動態分配的堆內存因爲某種緣由程序未釋放或沒法釋放,形成系統內存的浪費,致使程序運行速度減慢甚至系統崩潰等嚴重後果。
  • 雖然JavaScript 會自動垃圾收集,可是若是咱們的代碼寫法不當,會讓變量一直處於「進入環境」的狀態,沒法被回收。
  1. 意外的全局變量引發的內存泄漏

  2. 閉包引發的內存泄漏

  3. 未清除 dom 元素的引用的內存泄漏

  4. 循環引用引發的內存泄漏

  5. 被遺忘的計時器或回調引發的內存泄漏

  • 防止內存泄漏的方法:
  1. 及時清除引用。
  2. 使用WeakSet和WeakMap,它們對於值的引用都是不計入垃圾回收機制的,因此名字裏面纔會有一個"Weak",表示這是弱引用。
const wm = new WeakMap();
const element = document.getElementById('example');
wm.set(element, 'some information');
wm.get(element) // "some information"

先新建一個 Weakmap 實例。而後,將一個 DOM 節點做爲鍵名存入該實例,並將一些附加信息做爲鍵值,一塊兒存放在 WeakMap 裏面。這時,WeakMap 裏面對element的引用就是弱引用,不會被計入垃圾回收機制。

也就是說,DOM 節點對象的引用計數是1,而不是2。這時,一旦消除對該節點的引用,它佔用的內存就會被垃圾回收機制釋放。Weakmap 保存的這個鍵值對,也會自動消失。

4. ajax的用途,ajax請求的五種狀態(搜狐一面 2019.10 )

  • AJAX是「Asynchronous JavaScript And XML」的縮寫,是一種實現無頁面刷新獲取服務器數據的混合技術。
  • XMLHttpRequest 對象是瀏覽器提供的一個API,用來順暢地向服務器發送請求並解析服務器響應,固然整個過程當中,瀏覽器頁面不會被刷新。
  • .open()方法接收三個參數:請求方式(get or post),請求URL地址和是否爲異步請求的布爾值。「同步」意味着一旦請求發出,任何後續的JavaScript代碼不會再執行,「異步」則是當請求發出後,後續的JavaScript代碼會繼續執行,當請求成功後,會調用相應的回調函數。
// 該段代碼會啓動一個針對「example.php」的GET同步請求。
xhr.open("get", "example.php", false)
  • xhr實例的readystatechange事件會監聽xhr.readyState屬性的變化,有如下五種變化:
readyState 對應常量 描述
0(未初始化) xhr.UNSENT 請求已創建, 但未初始化(此時未調用open方法)
1(初始化) xhr.OPENED 請求已創建, 但未發送 (已調用open方法, 但未調用send方法)
2(發送數據) xhr.HEADERS_RECEIVED 請求已發送 (send方法已調用, 已收到響應頭)
3(數據發送中) xhr.LOADING 請求處理中, 因響應內容不全, 這時經過responseBody和responseText獲取可能會出現錯誤
4(完成) xhr.DONE 數據接收完畢, 此時能夠經過responseBody和responseText獲取完整的響應數據
//promise 實現ajax
function ajax(method, url, data) {
    var request = new XMLHttpRequest();
    return new Promise(function (resolve, reject) {
        request.onreadystatechange = function () {
            if (request.readyState === 4) {
                if (request.status === 200) {
                    resolve(request.responseText);
                } else {
                    reject(request.status);
                }
            }
        };
        request.open(method, url);
        request.send(data);
    });
}
ajax('GET', '/api/categories').then(function (text) {   // 若是AJAX成功,得到響應內容
    log.innerText = text;
}).catch(function (status) { // 若是AJAX失敗,得到響應代碼
    log.innerText = 'ERROR: ' + status;
});

5.講一講js裏面的異步操做有哪些?( 螞蟻金服一面 2019.03)

  1. 回調函數。 ajax典型的異步操做,利用XMLHttpRequest,回調函數獲取服務器的數據傳給前端。
  2. 事件監聽。 當監聽事件發生時,先執行回調函數,再對監聽事件進行改寫
  3. 觀察者模式,也叫訂閱發佈模式。 多個觀察者能夠訂閱同一個主題,主題對象改變時,主題對象就會通知這個觀察者。
  4. promise.
  5. es7語法糖async/await
  6. co庫的generator函數

6. javascript作類型判斷的方法有哪些?

  1. typeof,能夠判斷原始數據類型:undefined、boolean、string、number、symbol,可是typeof null的類型判斷爲object。對於引用類型,會判斷爲function、object兩種類型。
  2. instanceof ,instanceof 檢測的是原型,判斷一個實例是否屬於某種類型。
function instanceOf(left,right) {
    let proto = left.__proto__;
    let prototype = right.prototype
    while(true) {
        if(proto === null) return false;
        if(proto === prototype) return true;
        proto = proto.__proto__;
    }
}
  1. Object.prototype.toString
  • toString() 是 Object 的原型方法,調用該方法,默認返回當前對象的類型。
Object.prototype.toString.call('') ;   // [object String]
Object.prototype.toString.call(1) ;    // [object Number]
Object.prototype.toString.call(true) ; // [object Boolean]
Object.prototype.toString.call(Symbol()); //[object Symbol]
Object.prototype.toString.call(undefined) ; // [object Undefined]
Object.prototype.toString.call(null) ; // [object Null]
Object.prototype.toString.call(new Function()) ; // [object Function]
Object.prototype.toString.call(new Date()) ; // [object Date]
Object.prototype.toString.call([]) ; // [object Array]
Object.prototype.toString.call(new RegExp()) ; // [object RegExp]
Object.prototype.toString.call(new Error()) ; // [object Error]
Object.prototype.toString.call(document) ; // [object HTMLDocument]
Object.prototype.toString.call(window) ; //[object global] window 是全局對象 global 的引用

7. 如何阻止事件冒泡和默認事件?

  • 標準的DOM對象中可使用事件對象的stopPropagation()方法來阻止事件冒泡,但在IE8如下中IE的事件對象經過設置事件對象的cancelBubble屬性爲true來阻止冒泡;
  • 默認事件的話經過事件對象的preventDefault()方法來阻止,而IE經過設置事件對象的returnValue屬性爲false來阻止默認事件。

使用 IntersectionObserver

  • IntersectionObserver API爲開發者提供了一種能夠異步監聽目標元素與其祖先或視窗(viewport)處於交叉狀態的方式。祖先元素與視窗(viewport)被稱爲根(root)。
const config = {
    root: null,    // 默認指向瀏覽器的視口,但能夠是任意DOM元素
    rootMargin: '0px',  // 計算交叉時,root邊界盒的偏移量
    threshold: 0.5   // 監聽對象的交叉區域與邊界區域的比率
}
let observer = new IntersectionObserver(fucntion(entries){
    // ...
}, config)

new IntersectionObserver(function(entries, self))
  • 在entries咱們獲得咱們的回調函數做爲Array是特殊類型的:IntersectionObserverEntry 首先IntersectionObserverEntry含有三個不一樣的矩形的信息
  • 此外,IntersectionObserverEntry還提供了isIntersecting,這是一個方便的屬性,返回觀察元素是否與捕獲框架相交,
  • 另外,IntersectionObserverEntry提供了利於計算的遍歷屬性intersctionRatio:返回intersectionRect 與 boundingClientRect 的比例值.

圖片懶加載實現代碼

  • 以加載圖片爲例子,咱們須要將img標籤中設置一個data-src屬性,它指向的是實際上咱們須要加載的圖像,而img的src指向一張默認的圖片,若是爲空的話也會向服務器發送請求。
<img src="default.jpg" data-src="www.example.com/1.jpg">
const images = document.querySelectorAll('[data-src]')
const config = {
    rootMargin: '0px',
    threshold: 0
};
let observer = new IntersectionObserver((entries, self)=>{
    entries.forEach(entry => {
        if(entry.isIntersecting){
         // 加載圖像
         preloadImage(entry.target);
         // 解除觀察
           self.unobserve(entry.target)
        }
    })
}, config)

images.forEach(image => {
  observer.observe(image);
});

function preloadImage(img) {
  const src = img.dataset.src
  if (!src) { return; }
  img.src = src;
}

參考: 實現圖片懶加載

8. 什麼是函數節流和函數去抖?( 螞蟻金服一面 2019.03)

  • 函數去抖 debounce: 當調用函數n秒後,纔會執行該動做,若在這n秒內又調用該函數則將取消前一次並從新計算執行時間。
var debounce = function(delay, cb) {
    var timer;
    return function() {
        if (timer) clearTimeout(timer);
        timer = setTimeout(function() {
            cb();
        }, delay);
    }
}
  • 函數節流 throttle: 函數節流的基本思想是函數預先設定一個執行週期,當調用動做的時刻大於等於執行週期則執行該動做,而後進入下一個新週期
var throttle = function(delay, cb) {
    var startTime = Date.now();
    return function() {
        var currTime = Date.now();
        if (currTime - startTime > delay) {
            cb();
            startTime = currTime;
        }
    }
}

9.如何實現對一個DOM元素的深拷貝,包括元素的綁定事件?

//使用cloneNode,可是在元素上綁定的事件不會拷貝
function clone(origin) {
    return Object.assign({},origin);
}
//實現了對原始對象的克隆,可是隻能克隆原始對象自身的值,不能克隆她繼承的值,若是想要保持繼承鏈,能夠採用以下方法:
function clone(origin) {
    let originProto=Object.getPrototypeOf(origin);
    return Object.assign(Object.create(originProto),origin);
}

10. script標籤如何異步加載?

  • 默認狀況下,瀏覽器是同步加載 JavaScript 腳本,即渲染引擎遇到 script 標籤就會停下來,等到執行完腳本,再繼續向下渲染。若是是外部腳本,還必須加入腳本下載的時間。若是腳本體積很大,下載和執行的時間就會很長,所以形成瀏覽器堵塞,用戶會感受到瀏覽器「卡死」了,沒有任何響應。
<script src="path/to/myModule.js" defer></script>
<script src="path/to/myModule.js" async></script>
  • defer與async的區別是:
  1. defer要等到整個頁面在內存中正常渲染結束(DOM 結構徹底生成,以及其餘腳本執行完成),纔會執行;async一旦下載完,渲染引擎就會中斷渲染,執行這個腳本之後,再繼續渲染。一句話,defer是「渲染完再執行」,async是「下載完就執行」。
  2. 另外,若是有多個defer腳本,會按照它們在頁面出現的順序加載,而多個async腳本是不能保證加載順序的。

11. 講一下let、var、const的區別,談談如何凍結變量

  • var 沒有塊級做用域,支持變量提高。
  • let 有塊級做用域,不支持變量提高。不容許重複聲明,暫存性死區。
  • const 有塊級做用域,不支持變量提高,不容許重複聲明,暫存性死區。聲明一個變量一旦聲明就不能改變,改變報錯。const保證的變量的內存地址不得改動。若是想要將對象凍結的話,使用Object.freeze()方法
const foo=Object.freeze({});
foo.prop=123;
console.log(foo.prop);//混雜模式undefined,不起做用

12. 談談js事件循環機制 ( 螞蟻金服一面 2019.03)

  • 程序開始執行以後,主程序則開始執行 同步任務,碰到 異步任務 就把它放到任務隊列中,等到同步任務所有執行完畢以後,js引擎便去查看任務隊列有沒有能夠執行的異步任務,將異步任務轉爲同步任務,開始執行,執行完同步任務以後繼續查看任務隊列,這個過程是一直 循環 的,所以這個過程就是所謂的 事件循環,其中任務隊列也被稱爲事件隊列。經過一個任務隊列,單線程的js實現了異步任務的執行,給人感受js好像是多線程的。

13.如何攔截變量屬性

  • 使用proxy。new Proxy() 表示生成一個 Proxy 實例,target 參數表示所要攔截的目標對象,handler 參數也是一個對象,用來定製攔截行爲。
var proxy = new Proxy({}, {
  get: function(target, property) {
    return 35;
  }
});
let obj = Object.create(proxy);
obj.time // 35

14.箭頭函數和普通函數的區別是什麼?(阿里巴巴 2019.8.5)

  • 普通函數this:
  1. this老是表明它的直接調用者。
  2. 在默認狀況下,沒找到直接調用者,this指的是window。
  3. 在嚴格模式下,沒有直接調用者的函數中的this是undefined。
  4. 使用call,apply,bind綁定,this指的是綁定的對象。
  • 箭頭函數this:
  1. 在使用=>定義函數的時候,this的指向是 定義時所在的對象,而不是使用時所在的對象;
  2. 不可以用做構造函數,這就是說,不可以使用new命令,不然就會拋出一個錯誤;
  3. 不可以使用 arguments 對象;
  4. 不能使用 yield 命令;

15.函數柯里化理解 ( 螞蟻金服一面 2019.03)

  • 只傳遞給函數一部分參數來調用它,讓它返回一個函數去處理剩下的參數。
  • 用途:1.延遲計算;2.參數複用;3.動態生成函數
const curry = (fn, currArgs=[]) => {
    return function() {
        let args = Array.from(arguments);
        [].push.apply(args,currArgs);
        if (args.length < fn.length) {
            return curry.call(this,fn,...args);
        }
        return fn.apply(this,args);
    }
}

16.講講對d3的理解,講講d3與echarts的區別 (騰訊二面 2019.06)

  • d3正如其名 Data Driven Documents,其本質是將數據與 DOM 綁定,並將數據映射至 DOM 屬性上;
  • d3與echarts的區別:
  1. d3經過svg繪製圖形,能夠自定義事件。svg不依賴分辨率,繼續xml繪製圖形,能夠操做dom。支持事件處理器,複雜度高,會減慢頁面的渲染速度。

  2. echarts經過canvas來繪製圖形,用戶經過配置 options 參數,就可很容易繪製指定圖表。canvas依賴分辨率,基於js繪製圖形,不支持事件處理,能以png或者jpg的格式保存圖片。

框架( react anglar vue等)

Vue

一、vuex原理 (百度前端 字節跳動 騰訊 網易)

Vuex 是一個專爲 Vue.js 應用程序開發的狀態管理模式。每個 Vuex 應用的核心就是 store(倉庫)。「store」 基本上就是一個容器,它包含着你的應用中大部分的狀態 ( state )。

(1)Vuex 的狀態存儲是響應式的。當 Vue 組件從 store 中讀取狀態的時候,若 store 中的狀態發生變化,那麼相應的組件也會相應地獲得高效更新。

(2)改變 store 中的狀態的惟一途徑就是顯式地提交 (commit) mutation。這樣使得咱們能夠方便地跟蹤每個狀態的變化。

vuex的store有State、 Getter、Mutation 、Action、 Module五種屬性;

  • state 爲單一狀態樹,在state中須要定義咱們所須要管理的數組、對象、字符串等等
  • getters 相似vue的計算屬性,主要用來過濾一些數據。
  • mutation 更改store中state狀態的惟一方法就是提交mutation,store.commit。
  • action actions能夠理解爲經過將mutations裏面處裏數據的方法變成可異步的處理數據的方法,簡單的說就是異步操做數據。view 層經過 store.dispath 來分發 action。
  • module module其實只是解決了當state中很複雜臃腫的時候,module能夠將store分割成模塊,每一個模塊中擁有本身的state、mutation、action和getter。

2. vue數據雙向綁定(騰訊 2019.04)

<body>
    <div id="app">
    <input type="text" id="txt">
    <p id="show"></p>
</div>
</body>
<script type="text/javascript">
    var obj = {}
    Object.defineProperty(obj, 'txt', {
        get: function () {
            return obj
        },
        set: function (newValue) {
            document.getElementById('txt').value = newValue
            document.getElementById('show').innerHTML = newValue
        }
    })
    document.addEventListener('keyup', function (e) {
        obj.txt = e.target.value
    })
</script>

3. 父子組件如何通訊,兄弟組件如何通訊(騰訊 2019.04 依圖 貓眼電影 bilibili)

父組件經過props屬性與子組件通訊

父組件:

<parent>
    <single-voice  ref="singleVoiceRef" :parent-to-child="singleVoiceData"/>
</parent>

data(){
    return {
        singleVoiceData:'來自父組件的數據'
    }
}

// 父組件調用子組件中的方法,將值傳遞給子組件

CSSmethods:{`
`this.$refs.singleVoiceRef.openSingleVoice(this.singleVoiceData)`
`}`

子組件經過props來接受數據

props: {parentToChild: {type: String,required: true}},methods:{openSingleVoice(SingleVoice) {console.log(SingleVoice)}}

子組件向父組件傳值

vue2.0只容許單向數據傳遞,咱們經過出發事件來改變組件的數據

子組件代碼:

<template>
    <div @click="open"></div>
</template>

methods: {
   open() {
        this.$emit('showbox','the msg'); //觸發showbox方法,'the msg'爲向父組件傳遞的數據
    }
}

父組件代碼:

<child @showbox="toshow" :msg="msg"></child> //監聽子組件觸發的showbox事件,而後調用toshow方法

methods: {
    toshow(msg) {
        this.msg = msg;
    }
}

兄弟組件之間的通訊

咱們能夠實例化一個vue實例,至關於一個第三方

eventVue.$emit(‘function1’,value)
eventVue.$on(‘function1’, (message) => { // 箭頭函數接收
})

建立一個公共橋樑 eventVue.js

import Vue from 'vue'
export default new Vue()

兄弟組件內引入 eventVue.js

兄弟組件一

import eventVue from './eventVue.js'
export default {
  methods: {
 // 點擊通信錄與員工進行語音聊天
    handleChatStaff(staffInfo) {
      console.log(staffInfo)
      this.staffInfo = staffInfo
      eventVue.$emit('updateChatList', this.staffInfo)
    },
  }
}

兄弟組件二

import eventVue from './eventVue.js'
export default {
 created() {
    this.updateList()
  },
  methods: {
    updateList() {
      eventVue.$on('updateChatList', (message) => { // 與phoneBook組件通訊
        console.log(message)
        this.updateChatListEvent()
      })
    },
    // 更新聊天列表
    updateChatListEvent() {},
    }

其餘參考地址 :

https://www.imooc.com/article/68394?block_id=tuijian_wz

http://www.javashuo.com/article/p-dtiquxjs-mz.html

四、vue如何將一個組件打包上傳 (騰訊 2019.04)

參考地址:

http://www.javashuo.com/article/p-hkoypzim-mz.html

https://www.jianshu.com/p/2d47396c775c

五、談談你對 Vue 生命週期的理解?(網易)

​ Vue 實例有一個完整的生命週期,也就是從開始建立、初始化數據、編譯模版、掛載 Dom -> 渲染、更新 -> 渲染、卸載等一系列過程,咱們稱這是 Vue 的生命週期。

beforeCreate 組件實例被建立之初,組件的屬性生效以前

created 組件實例已經徹底建立,屬性也綁定,但真實 dom 尚未生成,$el 還不可用

beforeMount 在掛載開始以前被調用:相關的 render 函數首次被調用 mounted el 被新建立的 vm.$el 替換,並掛載到實例上去以後調用該鉤子

beforeUpdate 組件數據更新以前調用,發生在虛擬 DOM 打補丁以前

update 組件數據更新以後

activited keep-alive 專屬,組件被激活時調用

deactivated keep-alive 專屬,組件被銷燬時調用

beforeDestory 組件銷燬前調用

destoryed 組件銷燬後調用

六、父組件能夠監聽到子組件的生命週期嗎?

好比有父組件 Parent 和子組件 Child,若是父組件監聽到子組件掛載 mounted 就作一些邏輯處理,能夠經過如下寫法實現:

// Parent.vue
<Child @mounted="doSomething"/>
    
// Child.vue
mounted() {
  this.$emit("mounted");
}
複製代碼

以上須要手動經過 $emit 觸發父組件的事件,更簡單的方式能夠在父組件引用子組件時經過 @hook 來監聽便可,以下所示:

//  Parent.vue
<Child @hook:mounted="doSomething" ></Child>

doSomething() {
   console.log('父組件監聽到 mounted 鉤子函數 ...');
},
    
//  Child.vue
mounted(){
   console.log('子組件觸發 mounted 鉤子函數 ...');
},    
    
// 以上輸出順序爲:
// 子組件觸發 mounted 鉤子函數 ...
// 父組件監聽到 mounted 鉤子函數 ...     
複製代碼

固然 @hook 方法不只僅是能夠監聽 mounted,其它的生命週期事件,例如:created,updated 等均可以監聽。

七、Vue 組件間通訊有哪幾種方式?

Vue 組件間通訊是面試常考的知識點之一,這題有點相似於開放題,你回答出越多方法固然越加分,代表你對 Vue 掌握的越熟練。Vue 組件間通訊只要指如下 3 類通訊:父子組件通訊、隔代組件通訊、兄弟組件通訊,下面咱們分別介紹每種通訊方式且會說明此種方法可適用於哪類組件間通訊。

(1)props / $emit 適用 父子組件通訊

這種方法是 Vue 組件的基礎,相信大部分同窗耳聞能詳,因此此處就不舉例展開介紹。

(2)ref$parent / $children 適用 父子組件通訊

  • ref:若是在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;若是用在子組件上,引用就指向組件實例
  • $parent / $children:訪問父 / 子實例

(3)EventBus ($emit / $on) 適用於 父子、隔代、兄弟組件通訊

這種方法經過一個空的 Vue 實例做爲中央事件總線(事件中心),用它來觸發事件和監聽事件,從而實現任何組件間的通訊,包括父子、隔代、兄弟組件。

(4)$attrs/$listeners 適用於 隔代組件通訊

  • $attrs:包含了父做用域中不被 prop 所識別 (且獲取) 的特性綁定 ( class 和 style 除外 )。當一個組件沒有聲明任何 prop 時,這裏會包含全部父做用域的綁定 ( class 和 style 除外 ),而且能夠經過 v-bind="$attrs" 傳入內部組件。一般配合 inheritAttrs 選項一塊兒使用。
  • $listeners:包含了父做用域中的 (不含 .native 修飾器的) v-on 事件監聽器。它能夠經過 v-on="$listeners" 傳入內部組件

(5)provide / inject 適用於 隔代組件通訊

祖先組件中經過 provider 來提供變量,而後在子孫組件中經過 inject 來注入變量。 provide / inject API 主要解決了跨級組件間的通訊問題,不過它的使用場景,主要是子組件獲取上級組件的狀態,跨級組件間創建了一種主動提供與依賴注入的關係。

(6)Vuex 適用於 父子、隔代、兄弟組件通訊

Vuex 是一個專爲 Vue.js 應用程序開發的狀態管理模式。每個 Vuex 應用的核心就是 store(倉庫)。「store」 基本上就是一個容器,它包含着你的應用中大部分的狀態 ( state )。

  • Vuex 的狀態存儲是響應式的。當 Vue 組件從 store 中讀取狀態的時候,若 store 中的狀態發生變化,那麼相應的組件也會相應地獲得高效更新。
  • 改變 store 中的狀態的惟一途徑就是顯式地提交 (commit) mutation。這樣使得咱們能夠方便地跟蹤每個狀態的變化。

八、你有對 Vue 項目進行哪些優化?

(1)代碼層面的優化**

  • v-if 和 v-show 區分使用場景
  • computed 和 watch 區分使用場景
  • v-for 遍歷必須爲 item 添加 key,且避免同時使用 v-if
  • 長列表性能優化
  • 事件的銷燬
  • 圖片資源懶加載
  • 路由懶加載
  • 第三方插件的按需引入
  • 優化無限列表性能
  • 服務端渲染 SSR or 預渲染

(2)Webpack 層面的優化

  • Webpack 對圖片進行壓縮
  • 減小 ES6 轉爲 ES5 的冗餘代碼
  • 提取公共代碼
  • 模板預編譯
  • 提取組件的 CSS
  • 優化 SourceMap
  • 構建結果輸出分析
  • Vue 項目的編譯優化

(3)基礎的 Web 技術的優化

  • 開啓 gzip 壓縮
  • 瀏覽器緩存
  • CDN 的使用
  • 使用 Chrome Performance 查找性能瓶頸

九、vuejs與angularjs以及react的區別?(天壤智能)

angularjs的區別:

1****、Angular.js的學習成本高,好比增長了Dependency Injection特性,而Vue.js自己提供的API都比較簡單、直觀。

2****、在性能上,Angular.js依賴對數據作髒檢查,因此watcher越多越慢。

3****、Vue.js使用基於依賴追蹤的觀察而且使用異步隊列更新。全部的數據都是獨立出發的。

對於龐大的應用來講,這個優化差別仍是比較明顯的。

與reactjs的區別:

React 依賴Virtual DOM,而Vue.js使用的是DOM模板。React採用的Virtual DOM會對渲染出來的結果作髒檢查。
Vue.js在模板中提供了指令,過濾器等,能夠很是方便,快捷地操做Virtual DOM

十、 的做用是什麼,如何使用?

包裹動態組件時,會緩存不活動的組件實例,主要用於保留組件狀態或避免從新渲染;

使用:簡單頁面時

緩存:

不緩存:

使用:複雜項目時

路由字典中定義{path:’/detail’,meta:{keepAlive:false/true}} 是否緩存

根目錄中:

11 、scss是什麼?在vue.cli中的安裝使用步驟是?有哪幾大特性?

css的預編譯。

使用步驟:

​ 第一步:用npm 下三個loader(sass-loader、css-loader、node-sass)

​ 第二步:在build目錄找到webpack.base.config.js,在那個extends屬性中加一個拓展.scss

​ 第三步:仍是在同一個文件,配置一個module屬性

​ 第四步:而後在組件的style標籤加上lang屬性 ,例如:lang=」scss」

有哪幾大特性:

​ 一、能夠用變量,例如($變量名稱=值);

​ 二、能夠用混合器,例如:定義了字體的混合器

@mixin font-dpr($font-size){
	$font:$font-size/2;
	font-size: $font;
	[data-dpr="2"] & { font-size: $font+2px;}
	[data-dpr="3"] & { font-size: $font+4px;}
}

使用方法以下

.div{

  @include font-dpr(24px);

}

​ 三、能夠嵌套

十二、vuex原理

  • vuex的store有State、 Getter、Mutation 、Action、 Module五種屬性;
  • state 爲單一狀態樹,在state中須要定義咱們所須要管理的數組、對象、字符串等等
  • getters 相似vue的計算屬性,主要用來過濾一些數據。
  • mutation 更改store中state狀態的惟一方法就是提交mutation,store.commit。
  • action actions能夠理解爲經過將mutations裏面處裏數據的方法變成可異步的處理數據的方法,簡單的說就是異步操做數據。view 層經過 store.dispath 來分發 action。
  • module module其實只是解決了當state中很複雜臃腫的時候,module能夠將store分割成模塊,每一個模塊中擁有本身的state、mutation、action和getter。

1三、 vue數據雙向綁定

<body>
    <div id="app">
    <input type="text" id="txt">
    <p id="show"></p>
</div>
</body>
<script type="text/javascript">
    var obj = {}
    Object.defineProperty(obj, 'txt', {
        get: function () {
            return obj
        },
        set: function (newValue) {
            document.getElementById('txt').value = newValue
            document.getElementById('show').innerHTML = newValue
        }
    })
    document.addEventListener('keyup', function (e) {
        obj.txt = e.target.value
    })
</script>

react

一、爲何選擇使用框架而不是原生

框架的好處:

​ 組件化: 其中以 React 的組件化最爲完全,甚至能夠到函數級別的原子組件,高度的組件化能夠是咱們的工程易於維護、易於組合拓展。
​ 自然分層: JQuery 時代的代碼大部分狀況下是麪條代碼,耦合嚴重,現代框架無論是 MVC、MVP仍是MVVM 模式都能幫助咱們進行分層,代碼解耦更易於讀寫。
​ 生態: 如今主流前端框架都自帶生態,無論是數據流管理架構仍是 UI 庫都有成熟的解決方案。
​ 開發效率: 現代前端框架都默認自動更新DOM,而非咱們手動操做,解放了開發者的手動DOM成本,提升開發效率,從根本上解決了UI 與狀態同步問題.

虛擬DOM的優劣如何?
優勢:

​ 保證性能下限: 虛擬DOM能夠通過diff找出最小差別,而後批量進行patch,這種操做雖然比不上手動優化,可是比起粗暴的DOM操做性能要好不少,所以虛擬DOM能夠保證性能下限
無需手動操做DOM: 虛擬DOM的diff和patch都是在一次更新中自動進行的,咱們無需手動操做DOM,極大提升開發效率
​ 跨平臺: 虛擬DOM本質上是JavaScript對象,而DOM與平臺強相關,相比之下虛擬DOM能夠進行更方便地跨平臺操做,例如服務器渲染、移動端開發等等

​ 缺點:

​ 沒法進行極致優化: 在一些性能要求極高的應用中虛擬DOM沒法進行鍼對性的極致優化,好比VScode採用直接手動操做DOM的方式進行極端的性能優化

二、爲何虛擬dom會提升性能? (美團 )

虛擬dom至關於在js和真實dom中間加了一個緩存,利用dom diff算法避免了沒有必要的dom操做,從而提升性能。虛擬DOM本質上是JavaScript對象,是對真實DOM的抽象,狀態變動時,記錄新樹和舊樹的差別,最後把差別更新到真正的dom中

具體實現步驟以下:

1.用 JavaScript 對象結構表示 DOM 樹的結構;而後用這個樹構建一個真正的 DOM 樹,插到文檔當中;

2.當狀態變動的時候,從新構造一棵新的對象樹。而後用新的樹和舊的樹進行比較,記錄兩棵樹差別;

把2所記錄的差別應用到步驟1所構建的真正的DOM樹上,視圖就更新了

三、react生命週期函數 (曠世面試 2019.06 拍拍貸 天壤智能)

​ 組件加載以前,組件加載完成,以及組件更新數據,組件銷燬。觸發的一系列的方法 ,這就是組件的生命週期函數

​ 一、初始化階段:

​ getDefaultProps:獲取實例的默認屬性

​ getInitialState:獲取每一個實例的初始化狀態

​ componentWillMount:組件即將被裝載、渲染到頁面上

​ render:組件在這裏生成虛擬的DOM節點

​ componentDidMount:組件真正在被裝載以後

​ 二、運行中狀態:

​ componentWillReceiveProps:組件將要接收到屬性的時候調用

​ shouldComponentUpdate:組件接受到新屬性或者新狀態的時候(能夠返回false,接收數據後不更新,阻止render調用,後面的函數不會被繼續執行了)

​ componentWillUpdate:組件即將更新不能修改屬性和狀態

​ render:組件從新描繪

​ componentDidUpdate:組件已經更新

​ 三、銷燬階段:

​ componentWillUnmount:組件即將銷燬

必須記住的生命週期函數:

*加載的時候:componentWillMount、 render 、componentDidMount(dom操做)

更新的時候:componentWillUpdate、render、componentDidUpdate

*銷燬的時候: componentWillUnmount

四、什麼是Diff算法? (美團 )

diff算法做爲Virtual DOM的加速器,其算法的改進優化是React整個界面渲染的基礎和性能的保障,同時也是React源碼中最神祕的,最難以想象的部分

傳統diff算法經過循環遞歸對比差別,算法複雜度爲O(n3)。react diff算法制定了三條策略,將算法複雜度從 O(n3)下降到O(n)。

  • WebUI中DOM節點跨節點的操做特別少,能夠忽略不計。
  • 擁有相同類的組件會擁有類似的DOM結構。擁有不一樣類的組件會生成不一樣的DOM結構。
  • 同一層級的子節點,能夠根據惟一的ID來區分。

針對這三個策略,react diff實施的具體策略是:

  1. diff對樹進行分層比較,只對比兩棵樹同級別的節點。跨層級移動節點,將會致使節點刪除,從新插入,沒法複用。
  2. diff對組件進行類比較,類相同的遞歸diff子節點,不一樣的直接銷燬重建。diff對同一層級的子節點進行處理時,會根據key進行簡要的複用。兩棵樹中存在相同key的節點時,只會移動節點。

五、React性能優化方式

因爲react中性能主要耗費在於update階段的diff算法,所以性能優化也主要針對diff算法。

1.減小diff算法觸發次數

​ A、 setState機制在正常運行時,因爲批更新策略,已經下降了update過程的觸發次數。
所以,setState優化主要在於非批更新階段中(timeout/Promise回調),減小setState的觸發次數。
常見的業務場景即處理接口回調時,不管數據處理多麼複雜,保證最後只調用一次setState。

​ B、父組件的render必然會觸發子組件進入update階段(不管props是否更新)。此時最經常使用的優化方案即爲shouldComponentUpdate方法。最多見的方式爲進行this.props和this.state的淺比較來判斷組件是否須要更新。或者直接使用PureComponent,原理一致。須要注意的是,父組件的render函數若是寫的不規範,將會致使上述的策略失效。

​ C、使用shouldComponentUpdate鉤子,根據具體的業務狀態,減小沒必要要的props變化致使的渲染。如一個不用於渲染的props致使的update。
另外, 也要儘可能避免在shouldComponentUpdate 中作一些比較複雜的操做, 好比超大數據的pick操做等。

合理設計state,不須要渲染的state,儘可能使用實例成員變量。

二、正確使用diff算法

​ 不使用跨層級移動節點的操做。

​ 對於條件渲染多個節點時,儘可能採用隱藏等方式切換節點,而不是替換節點。

​ 儘可能避免將後面的子節點移動到前面的操做,當節點數量較多時,會產生必定的性能問題。

性能檢測工具
React官方提供的:React.addons.Perf

六、你瞭解React嗎?

React是facebook搞出來的一個輕量級的組件庫,用於解決前端視圖層的一些問題,就是MVC中V層的問題,它內部的Instagram網站就是用React搭建的。

解決了三個問題: 1.組件複用問題, 2.性能問題,3.兼容性問題:

React 會建立一個虛擬 DOM(virtual DOM)。當一個組件中的狀態改變時,React 首先會經過 "diffing" 算法來標記虛擬 DOM 中的改變,第二步是調節(reconciliation),會用 diff 的結果來更新 DOM。

優勢:

​ 1.只需查看 render 函數就會很容易知道一個組件是如何被渲染的

​ 2.JSX 的引入,使得組件的代碼更加可讀,也更容易看懂組件的佈局,或者組件之間是如何互相引用的

​ 3.支持服務端渲染,這能夠改進 SEO 和性能

​ 4.易於測試

​ 5.React 只關注 View 層,因此能夠和其它任何框架(如Backbone.js, Angular.js)一塊兒使用

angular

一、React 與 Angular 有何不一樣

Angular是一個成熟的MVC框架,帶有不少特定的特性,好比服務、指令、模板、模塊、解析器等等。React是一個很是輕量級的庫,它只關注MVC的視圖部分。

Angular遵循兩個方向的數據流,而React遵循從上到下的單向數據流。React在開發特性時給了開發人員很大的自由,例如,調用API的方式、路由等等。咱們不須要包括路由器庫,除非咱們須要它在咱們的項目。

二、angular 核心?

AngularJS是爲了克服HTML在構建應用上的不足而設計的。 AngularJS有着諸多特性,最爲核心的是:

  • MVC
  • 模塊化
  • 自動化雙向數據綁定
  • 語義化標籤、依賴注入等等

三、簡述angular的數據綁定

  Angular 在 scope 模型上設置了一個監聽隊列,用來監聽數據變化並更新 view 。每次綁定一個東西到 view 上時 AngularJS 就會往 $watch 隊列裏插入一條 $watch ,用來檢測它監視的 model 裏是否有變化的東西。當瀏覽器接收到能夠被 angular context 處理的事件時, $digest 循環就會觸發,遍歷全部的 $watch ,最後更新 dom。

四、AngularJS的數據雙向綁定是怎麼實現的?

  一、每一個雙向綁定的元素都有一個watcher
  二、在某些事件發生的時候,調用digest髒數據檢測。
    這些事件有:表單元素內容變化、Ajax請求響應、點擊按鈕執行的函數等。
  三、髒數據檢測會檢測rootscope下全部被watcher的元素。
    $digest函數就是髒數據監測

五、單頁應用有哪些優缺點?(網易雷火)

單頁 Web 應用 (single-page application 簡稱爲 SPA) 是一種特殊的 Web 應用。它將全部的活動侷限於一個Web頁面中,僅在該Web頁面初始化時加載相應的HTML、JavaScript 和 CSS。一旦頁面加載完成了,SPA不會由於用戶的操做而進行頁面的從新加載或跳轉。取而代之的是利用 JavaScript 動態的變換HTML的內容,從而實現UI與用戶的交互。因爲避免了頁面的從新加載,SPA 能夠提供較爲流暢的用戶體驗。

一、優勢:

1).良好的交互體驗

用戶不須要從新刷新頁面,獲取數據也是經過Ajax異步獲取,頁面顯示流暢。

2).良好的先後端工做分離模式

單頁Web應用能夠和RESTful規約一塊兒使用,經過REST API提供接口數據,並使用Ajax異步獲取,這樣有助於分離客戶端和服務器端工做。更進一步,能夠在客戶端也能夠分解爲靜態頁面和頁面交互兩個部分。

3).減輕服務器壓力

服務器只用出數據就能夠,不用管展現邏輯和頁面合成,吞吐能力會提升幾倍;

4).共用一套後端程序代碼
不用修改後端程序代碼就能夠同時用於Web界面、手機、平板等多種客戶端;
二、缺點:

1).SEO難度較高

因爲全部的內容都在一個頁面中動態替換顯示,因此在SEO上其有着自然的弱勢,因此若是你的站點對SEO很看重,且要用單頁應用,那麼就作些靜態頁面給搜索引擎用吧。

2).前進、後退管理

因爲單頁Web應用在一個頁面中顯示全部的內容,因此不能使用瀏覽器的前進後退功能,全部的頁面切換須要本身創建堆棧管理,固然此問題也有解決方案,好比利用URI中的散列+iframe實現。

3).初次加載耗時多

爲實現單頁Web應用功能及顯示效果,須要在加載頁面的時候將JavaScript、CSS統一加載,部分頁面能夠在須要的時候加載。因此必須對JavaScript及CSS代碼進行合併壓縮處理,若是使用第三方庫,建議使用一些大公司的CDN,所以帶寬的消耗是必然的。

結語

還有2件事拜託你們
一:求贊 求收藏 求分享 求留言,讓更多的人看到這篇內容
二:歡迎添加個人我的微信
備註「資料」, 300多篇原創技術文章,海量的視頻資料便可得到
備註「加羣」,我會拉你進技術交流羣,羣裏大牛學霸具在,哪怕您作個潛水魚也會學到不少東西

相關連接

金三銀四,磨礪鋒芒;劍指大廠,揚帆起航(2020年最全大廠WEB前端面試題精選)上
金三銀四,磨礪鋒芒;劍指大廠,揚帆起航(2020年最全大廠WEB前端面試題精選)中
金三銀四,磨礪鋒芒;劍指大廠,揚帆起航(2020年最全大廠WEB前端面試題精選)下

參考資料

11道瀏覽器原理面試題

這兒有20道大廠面試題等你查收

2020 前端面試 | 「HTML + CSS + JS」專題

圖解瀏覽器的工做原理(史上最全)

BAT前端經典面試問題:史上最最最詳細的手寫Promise教程

webpack 中文網

相關文章
相關標籤/搜索