面試分享:2018阿里巴巴前端面試總結(題目+答案)

blog.ihoey.com發表於2018-03-05

1、使用css實現一個持續的動畫效果

animation:mymove 5s infinite;

@keyframes mymove {

    from {top:0px;}
    
    to {top:200px;}

}

主要考: animation 用法

值    描述
animation-name    規定需要繫結到選擇器的 keyframe 名稱。
animation-duration    規定完成動畫所花費的時間,以秒或毫秒計。
animation-timing-function    規定動畫的速度曲線。
animation-delay    規定在動畫開始之前的延遲。
animation-iteration-count    規定動畫應該播放的次數。
animation-direction    規定是否應該輪流反向播放動畫。    

2、使用js實現一個持續的動畫效果

最開始的思路是用定時器實現,最後沒有想的太完整,面試官給出的答案是用 requestAnimationFrame。

    var e = document.getElementById('e')
    
    var falg = true;
    
    var left = 0;
    
    setInterval(() => {
    
        left == 0 ? falg = true : left == 100 ? falg = false : ''
    
        falg ? e.style.left = ` ${left++}px` : e.style.left = ` ${left--}px`
    
    }, 1000 / 60)
    
requestAnimationFrame 由於之前沒有用過這個 API 所以是現學的。
//相容性處理

window.requestAnimFrame = (function(){

  return  window.requestAnimationFrame       ||

          window.webkitRequestAnimationFrame ||

          window.mozRequestAnimationFrame    ||

          function(callback){

            window.setTimeout(callback, 1000 / 60);

          };

})();


var e = document.getElementById("e");

var flag = true;

var left = 0;


function render() {

    left == 0 ? flag = true : left == 100 ? flag = false : '';

    flag ? e.style.left = ` ${left++}px` :

        e.style.left = ` ${left--}px`;

}


(function animloop() {

    render();

    requestAnimFrame(animloop);

})();

不足之處請指正(畢竟是現學的)順便查了一下優勢:

瀏覽器可以優化並行的動畫動作,更合理的重新排列動作序列,並把能夠合併的動作放在一個渲染週期內完成,從而呈現出更流暢的動畫效果

解決毫秒的不精確性

避免過度渲染(渲染頻率太高、 tab 不可見暫停等等) 注: requestAnimFrame 和 定時器一樣也頭一個類似的清除方法cancelAnimationFrame。

3、右邊寬度固定,左邊自適應

第一種:

<style>

    div {

        height: 200px;

    }

    .left {

        float: right;

        width: 200px;

        background-color: rebeccapurple;

    }

    .right {

        margin-right: 200px;

        background-color: red;

    }

</style>

<body>

    <div class="left"></div>

    <div class="right"></div>

</body>

4、水平垂直居中 

第一種

#container{

    position:relative;

}

#center{

    width:100px;

    height:100px;

    position:absolute;

    top:50%;

    left:50%;

    transform: translate(-50%,-50%);

}

第二種

#container{

    position:relative;

}

#center{

    width:100px;

    height:100px;

    position:absolute;

    top:50%;

    left:50%;

    margin:-50px 0 0 -50px;

}

第三種

#container{

    position:relative;

}

#center{

    position:absolute;

    margin:auto;

    top:0;

    bottom:0;

    left:0;

    right:0;
}

第四種 flex

#container{

    display:flex;

    justify-content:center;

    align-items: center;

}

5、四種定位的區別

static 是預設值

relative 相對定位 相對於自身原有位置進行偏移,仍處於標準文件流中

absolute 絕對定位 相對於最近的已定位的祖先元素, 有已定位(指 position不是 static的元素)祖先元素, 以最近的祖先元素為參考標準。如果無已定位祖先元素, 以 body元素為偏移參照基準, 完全脫離了標準文件流。

fixed 固定定位的元素會相對於視窗來定位,這意味著即便頁面滾動,它還是會停留在相同的位置。一個固定定位元素不會保留它原本在頁面應有的空隙。

6、Flex佈局用的多嗎?

因為專案考慮相容 IE9 所以直接說用的不多

7、移動端適配怎麼做的?

使用媒體查詢做的響應式佈局,根據不同螢幕寬度載入不同 css.

8、let與var的區別?

let 為 ES6 新新增申明變數的命令,它類似於 var,但是有以下不同: 

var 宣告的變數,其作用域為該語句所在的函式內,且存在變數提升現象

let 宣告的變數,其作用域為該語句所在的程式碼塊內,不存在變數提升

let 不允許重複宣告.

9、為什麼 var 可以重複宣告?(這個就不知道了)

當我們執行程式碼時,我們可以簡單的理解為新變數分配一塊兒記憶體,命名為 a,並賦值為 2,但在執行的時候編譯器與引擎還會進行兩項額外的操作:判斷變數是否已經宣告:

首先編譯器對程式碼進行分析拆解,從左至右遇見 var a,則編譯器會詢問作用域是否已經存在叫 a 的變數了,如果不存在,則招呼作用域宣告一個新的變數 a,若已經存在,則忽略 var 繼續向下編譯,這時 a = 2被編譯成可執行的程式碼供引擎使用。

引擎遇見 a=2時同樣會詢問在當前的作用域下是否有變數 a,若存在,則將 a賦值為 2(由於第一步編譯器忽略了重複宣告的var,且作用域中已經有 a,所以重複宣告會發生值得覆蓋而並不會報錯)。若不存在,則順著作用域鏈向上查詢,若最終找到了變數 a則將其賦值 2,若沒有找到,則招呼作用域宣告一個變數 a並賦值為 2。 參考連結

10、封裝一個函式,引數是定時器的時間,.then執行回撥函式。

function sleep (time) {

  return new Promise((resolve) => setTimeout(resolve, time));

}

11、一個關於 this 指向的問題

obj = {

    name: 'a',

    getName : function () {

        console.log(this.name);

    }

}


var fn = obj.getName

obj.getName()

var fn2 = obj.getName()

fn()

fn2()

12 CommonJS 中的 require/exports 和 ES6 中的 import/export 區別?

CommonJS 模組的重要特性是載入時執行,即指令碼程式碼在 require 的時候,就會全部執行。一旦出現某個模組被”迴圈載入”,就只輸出已經執行的部分,還未執行的部分不會輸出。

ES6 模組是動態引用,如果使用 import 從一個模組載入變數,那些變數不會被快取,而是成為一個指向被載入模組的引用,需要開發者自己保證,真正取值的時候能夠取到值。

import/export 最終都是編譯為 require/exports 來執行的。

CommonJS 規範規定,每個模組內部, module 變數代表當前模組。這個變數是一個物件,它的 exports 屬性(即module.exports )是對外的介面。載入某個模組,其實是載入該模組的 module.exports 屬性。

export 命令規定的是對外的介面,必須與模組內部的變數建立一一對應關係。

13、 一行程式碼實現陣列去重?

[...new Set([1,2,3,1,'a',1,'a'])]

14、使用addEventListener點選li彈出內容,並且動態新增li之後有效(這個題沒答出來??)

<ul>

    <li>1</li>

    <li>2</li>

    <li>3</li>

    <li>4</li>

</ul>


var ulNode = document.getElementById("ul");

    ulNode.addEventListener('click', function (e) {

        if (e.target && e.target.nodeName.toUpperCase() == "LI") {

            alert(e.target.innerHTML);

        }

    }, false);

15、怎麼判斷兩個物件相等?

    obj={

    a:1,

    b:2

}

obj2={

    a:1,

    b:2

}

obj3={

    a:1,

    b:2

}

最開始的思路是遍歷來判斷,但是最後好像沒有說清楚,查了下,好像可以轉換為字串來判斷。

JSON.stringify(obj)==JSON.stringify(obj2);//true

JSON.stringify(obj)==JSON.stringify(obj3);//false

16、專案做過哪些效能優化?

減少 HTTP 請求數

減少 DNS 查詢

使用 CDN

避免重定向

圖片懶載入

減少 DOM 元素數量

減少 DOM 操作

使用外部 JavaScript 和 CSS

壓縮 JavaScript 、 CSS 、字型、圖片等

優化 CSS Sprite

使用 iconfont

字型裁剪

多域名分發劃分內容到不同域名

儘量減少 iframe 使用

避免圖片 src 為空

把樣式表放在 中

把指令碼放在頁面底部 歡迎補充。。。

17、模組化開發是怎麼做的?

使用名稱空間。

18、有沒有使用過webpack?

我說Vue專案中使用了,然後就沒問了。

19、gulp自己寫過任務嗎?還是都用的模組?

不知道怎麼怎麼回答,不都是使用模組來寫的麼,然後就說是使用模組。

router.go(1)

router.push('/')
router.go(1)
router.push('/')

21、Vue router 跳轉和 location.href 有什麼區別?

router 是 hash 改變 location.href 是頁面跳轉,重新整理頁面

22、Vue 雙向繫結實現原理?

通過 Object.defineProperty 實現的

23、你能實現一下雙向繫結嗎? 

<body>

    <div id="app">

        <input type="text" id="txt">

        <p id="show-txt"></p>

    </div>

    <script>

        var obj = {}

        Object.defineProperty(obj, 'txt', {

            get: function () {

                return obj

            },

            set: function (newValue) {

                document.getElementById('txt').value = newValue

                document.getElementById('show-txt').innerHTML = newValue

            }

        })

        document.addEventListener('keyup', function (e) {

            obj.txt = e.target.value

        })

    </script>

</body>

24、 React 和 Vue 有什麼區別?

25、 Set 和 Map 資料結構

ES6 提供了新的資料結構 Set 它類似於陣列,但是成員的值都是唯一的,沒有重複的值。

ES6 提供了 Map 資料結構。它類似於物件,也是鍵值對的集合,但是“鍵”的範圍不限於字串,各種型別的值(包括物件)都可以當作鍵。也就是說, Object 結構提供了“字串—值”的對應, Map 結構提供了“值—值”的對應,是一種更完善的 Hash結構實現。

26、WeakMap 和 Map 的區別?

WeakMap 結構與 Map 結構基本類似,唯一的區別是它只接受物件作為鍵名( null 除外),不接受其他型別的值作為鍵名,而且鍵名所指向的物件,不計入垃圾回收機制。

WeakMap 最大的好處是可以避免記憶體洩漏。一個僅被 WeakMap 作為 key 而引用的物件,會被垃圾回收器回收掉。

WeakMap 擁有和 Map 類似的 set(key, value) 、 get(key)、has(key)、 delete(key) 和 clear() 方法, 沒有任何與迭代有關的屬性和方法。

27、重排和重繪

部分渲染樹(或者整個渲染樹)需要重新分析並且節點尺寸需要重新計算。這被稱為重排。注意這裡至少會有一次重排-初始化頁面佈局。

由於節點的幾何屬性發生改變或者由於樣式發生改變,例如改變元素背景色時,螢幕上的部分內容需要更新。這樣的更新被稱為重繪。

28、什麼情況會觸發重排和重繪?

新增、刪除、更新 DOM 節點

通過 display: none 隱藏一個 DOM 節點-觸發重排和重繪

通過 visibility: hidden 隱藏一個 DOM 節點-只觸發重繪,因為沒有幾何變化

移動或者給頁面中的 DOM 節點新增動畫

新增一個樣式表,調整樣式屬性

使用者行為,例如調整視窗大小,改變字號,或者滾動。

29、瀏覽器快取

瀏覽器快取分為強快取和協商快取。當客戶端請求某個資源時,獲取快取的流程如下: 

先根據這個資源的一些 http header 判斷它是否命中強快取,如果命中,則直接從本地獲取快取資源,不會發請求到伺服器;

當強快取沒有命中時,客戶端會傳送請求到伺服器,伺服器通過另一些 request header驗證這個資源是否命中協商快取,稱為 http再驗證,如果命中,伺服器將請求返回,但不返回資源,而是告訴客戶端直接從快取中獲取,客戶端收到返回後就會從快取中獲取資源;

強快取和協商快取共同之處在於,如果命中快取,伺服器都不會返回資源;

區別是,強快取不對傳送請求到伺服器,但協商快取會。

當協商快取也沒命中時,伺服器就會將資源傳送回客戶端。

當 ctrl+f5 強制重新整理網頁時,直接從伺服器載入,跳過強快取和協商快取;

當 f5 重新整理網頁時,跳過強快取,但是會檢查協商快取;

強快取

Expires(該欄位是 http1.0 時的規範,值為一個絕對時間的 GMT 格式的時間字串,代表快取資源的過期時間)

Cache-Control:max-age(該欄位是 http1.1 的規範,強快取利用其 max-age 值來判斷快取資源的最大生命週期,它的值單位為秒)

協商快取

Last-Modified(值為資源最後更新時間,隨伺服器response返回)

If-Modified-Since(通過比較兩個時間來判斷資源在兩次請求期間是否有過修改,如果沒有修改,則命中協商快取)

ETag(表示資源內容的唯一標識,隨伺服器response返回)

If-None-Match(伺服器通過比較請求頭部的If-None-Match與當前資源的ETag是否一致來判斷資源是否在兩次請求之間有過修改,如果沒有修改,則命中協商快取)

如果喜歡請給個贊吧,您的贊會是我們繼續分享的動力!

相關文章