前端面試題

基礎

  1. Html是啥? Html超文本連接標示語言,WEB網頁設計語言,XHTML是一個基於XML的置標語言javascript

  2. 基本數據類型 undefined null Boolen String Number Object Symbol(表示獨一無二的值,由Symbol方法生成 let s = Symbol())css

  3. Mvvm是什麼html

  4. Call,apply,bind區別前端

    • 都是修改this指向
    • 其中apply與call的區別是:apply接收參數數組,而call接收參數列表
    • bind返回的是一個函數,其參數也是參數列表
  5. 模擬實現apply與call, bind(還未實現)html5

    Function.prototype.mycall = function(context){
    	var context = context || window;
    	var args = [];	
    	for(var i=1; i<arguments.length; i++){
    		args.push(arguments[i])
    	}
    	context.fn = this;
    	context.fn(...args);
    	delete context.fn;
    }
    
    Function.prototype.myapply = function(context, args){
    	var context = context || window;
    	context.fn = this;
    	if(!args){
    	    context.fn()
    	}else{
    	    if(!(args instanceof Array)) 
    	        thorw new Error("params must be array")
    	    context.fn(...args);
    	}
    	delete context.fn;
    }
    
    var bar = {
    	a: 1,
    	b:function() {
    		console.log(this.a)
        }
    }
    複製代碼
  6. 前端模塊化java

    js模塊化規範有commonJS、AMD、CMD以及ES6的模塊系統node

    • commonJs用同步方式加載模塊。主要應用於node
    • AMD用異步方式加載模塊,使用require.js實現。主要應用於前端(require.js在申明依賴的模塊時會在第一時間加載並執行模塊內的代碼)
    • CMD與AMD相似,不一樣的是AMD推崇依賴前置,提早執行,CMD推崇依賴就近,延後執行。(CMD規範是在sea.js推廣中產生的)
    • es6 module export import

    es6與commonJs的差別react

    • es6輸出的是值的引用,commonJs輸入的是值的拷貝
    • es6是編譯時加載,commonJs是運行時加載(es6模塊不是對象,是經過export顯示輸出的一段代碼,commonJs模塊是一個對象)
  7. Reduce實現mapwebpack

  8. 建立對象方式 構造函數, 原型模式,組合模式ios

    function People() {
        this.name = 'ye';
    }
    
    People.prototype = {
        constructor: People, 
        getName: function(){
            return this.name;
        }
    }
    
    var oPeople = new People();
    
    複製代碼
  9. 變量提高

    同名的變量與函數,函數提高優於變量提高,同名的變量不會覆蓋同名的函數,而同名的函數會覆蓋同名的變量

    console.log(fn);
    var fn = () => {}
    var fn;
    console.log(fn);
    var fn = 2
    console.log(fn);
    複製代碼
  10. 防抖與節流

    防抖:高頻事件在n秒內只執行一次,若是高頻事件在n秒內再次觸發,則從新計算時間(在搜索框內輸入文字)

    節流:高頻事件在n秒內只執行一次,下拉頁面時執行

    var fn = function(){
            console.log('fn')
        }
        window.onresize = debounce(fn,500)
        window.onresize = throttle(fn,500)
        function debounce(fn){
            var timer = null
            return function(){
                //timer第一次執行後會保存在內存裏 永遠都是執行器 直到最後被觸發
                if(timer){     
                    clearTimeout(timer)
                    timer = null
                }
                timer = setTimeout(function(){
                    fn()
                },100)
            }
        }
        function debounce(fn) {
            var timer = null
            return function(){
            if(!timer){
                clearTimout(timer);
                timer = null;
            }
            timer = setTimeout(function(){
                fn.aplly(this, arguments)
            }, 500)
                
            }
        }
        function throttle(fn) {
            var canRun = true;
            return function() {
                if(!canRun) return;
                canRun = false
                setTimeout(function(){
                    fn.apply(this, arguments);
                    canRun = true;
                }, 500);
            }
            
        }
    複製代碼

    節流

  11. 閉包理解及應用

    當函數能夠記住並訪問所在的詞法做用域時,就產生了閉包,即便函數是在當前詞法做用域以外執行。 閉包占用內存,會形成網頁性問題,在ie中可能致使內存泄露。要合理使用閉包,在退出函數前,將不使用的局部變量刪除 應用:

    • for循環中,定時器延時打印問題(使用自執行函數或es6)
    • 防抖函數
    • 使用閉包設計單例模式
    var person = (function() {
        var name = 'pan';
        var age = 18;
    	var instance = null;
     	function init(){
    		return{
                getName: function() {        
                    return name
                },
                getAge: function() {
                     return age
                }    
            }   
    	}
    	return {
    	    getInstance: function() {
    	        if(!instance){
    	            instance = init();
    	        }
    		    return instance;
    		}
    	}
    	})();
    複製代碼
  12. 瀏覽器渲染過程

    瀏覽器渲染進程是多線程的,分爲GUI渲染進程,js引擎線程,事件觸發線程,定時器線程及異步http線程。GUI渲染進程負責解析html與css,構建Dom樹和render樹,佈局與繪製等等。

    js分同步任務與異步任務。同步任務都在主線程執行,造成一個執行棧。主線程以外,事件觸發線程管理着一個任務隊列,異步任務執行有告終果,就會在任務隊列中放入一個事件。執行棧中的同步內容執行完畢以後,就會執行任務隊列中的內容

  13. 輸入URL到瀏覽器完成頁面渲染的發生了什麼

    • DNS域名解析
    • 創建TCP連接(三次握手)
    • 瀏覽器發送http請求
    • 服務器處理請求
    • 返回響應結果(四次揮手)
    • 瀏覽器解析html
    • 瀏覽器佈局渲染

    從瀏覽器多進程到JS單線程 輸入URL到瀏覽器完成頁面渲染的發生了什麼

  14. 性能優化

    • react優化
    • webpack優化
    • 減小http請求
    • 使用雪碧圖片
    • cdn
    • 減小沒必要要的dom
    • 減小重繪和迴流
    • 壓縮css,js
  15. 重繪與迴流

    重繪是更改樣式,迴流是從新構建 迴流必定會重繪,而重繪不必定會迴流。只有顏色改變只會重繪,不會引發迴流,

  16. 跨域

    瀏覽器的同源策略

    • jsonp:script不受同源策略影響,在js中動態生成script標籤,src爲請求資源地址+獲取函數字段名+
    • iframe
    • CORS(服務端設置Access-Control-Allow-Origin爲 )
    • node中間件跨域
    • ngix代理跨域
    • WINDOW.NAME
    • html5的window.postmessage
  17. 原型繼承實現方式

    • 定義新的構造函數,並在內部用call()調用但願「繼承」的構造函數,並綁定this(Parent.call(this, props);)
    • 藉助中間函數F實現原型鏈繼承,最好經過封裝的inherits函數完成;
    • 繼續在新的構造函數的原型上定義新方法

    原型繼承

  18. es5與es6繼承區別

    ES5繼承的本質:先建立實例對象this,再將父類方法添加到this上面。 思路:建立父類 建立子類 創建關係 通用繼承方法與super

    ES6繼承實質:先創造父類的實例對象this,用子類的構造函數修改this.

    ES5和ES6繼承的區別

  19. 深淺拷貝

    深拷貝: json的stringfy、parse實現 var obj2 = $.extend(true, {}, obj1) 使用遞歸複製對象的全部層級屬性

    擴展符、Object.assign可實現一層拷貝

  20. 前端框架選型

    前端框架選型

  21. a==1 && a==2 && a==3

    js的隱式轉換(默認調用valueOf方法)及==強制類型轉換

    var a = {
        num: 0,
        valueOf: function() {
            return this.num += 1;
        }
    }
    console.log(a==1 && a==2 && a==3)
    複製代碼
  22. 點擊li輸出index值

    • 給li添加點擊事件,可以使用let聲明塊級做用域或使用閉包或使用自執行函數
    • 給ul添加點擊事件,獲取全部的li並轉換爲數組,結合indexOf使用
    li添加事件
    
    
    
    ul添加事件
      var nodeList = document.getElementsByTagName('li') ,
        arrNodes = Array.prototype.slice.call(nodeList) ,
        nodeUls = document.getElementsByTagName('ul') ;
    nodeUls[0].addEventListener("click",function(event){
        var event = event || window.event;
        var target = event.target || event.srcElement;
        alert(arrNodes.indexOf(target))
    },false);
    複製代碼

    連接

  23. 含有length屬性的元素轉換爲數組

    • Array.prototype.slice.call(oLi);
    • Array.from(...new Set());
    • for循環
  24. addEventListener與click事件的區別

    • click
      • 是Dom0級規範,全部瀏覽器都支持
      • 定義多個click事件,只執行最後聲明的事件
    • addEventListener
      • 是Dom2級規範,只有支持Dom2級事件處理程序的瀏覽器(IE9,chrome,firefox,safari)才支持這個方法
      • 能夠爲一個事件註冊多個監聽器,它們前後運行且不被覆蓋
      • 其第三參數表示是在捕獲階段仍是在冒泡階段處理事件(默認值爲false,表明在冒泡階段處理,通常會省略)

###css

  1. css盒子模型 盒子模型包括:content、padding、margin、border。可經過box-sizing設置

    標準模型的寬高爲content的寬高 IE模型的寬高包括border

    js獲取盒模型的寬高:

    dom.style.width/height:內聯樣式的寬高
        dom.currentStyle.width/height:渲染後的最終寬高(IE)
        window.getComputedStyle(dom).width/height:DOM標準,不支持IE
        dom.getBoundingClientRect().width/height:計算元素的絕對位置(視窗左頂點爲起點,含left/right/height/width)
    複製代碼
  2. BFC是什麼? BFC是塊級格式化上下文,規則是

    • 內部的box會在垂直方向一個接一個的放
    • Box垂直方向的距離由margin決定,屬於同一個BFC的兩個相鄰box的margin會重疊
    • bfc的區域不會與float box重疊
    • BFC就是頁面中的隔離的一個獨立容器,容器中的子元素不會影響到外面的元素
    • BFC容器的高度,浮動元素也會參加
  3. BFC的使用場景

    • 高度坍塌:父元素在子元素浮動後高度變爲0
    • 左邊寬度固定,右邊自適應的兩欄佈局(BFC區域不會與浮動區域重疊,添加overflow:hidden auto可觸發BFC)示例
    • margin邊距合併,包括父子邊距
    • 上下邊距重疊
  4. 垂直居中

    • 使用absolute與margin實現
    • 使用absolute與transform實現
    • 使用flex實現:父元素flex,align-items:center;justify-content:center
  5. 流式佈局

    css
    
    
    複製代碼
  6. 移動端兼容性問題

    1. 1像素問題
    2. input框在fix佈局下,光標亂飛
    3. 穿透問題
    4. ios鍵盤彈起擋住輸入框
  7. rem

  8. 移動端適配方案:rem+media

  9. css3 translate, rotate, skew,border-radius,text-shadow

  10. html5引入庫html5shiv

es6

  1. promise

    promisepromise 8道面試題

    promise是異步編程的一種解決方案,比回調函數更加合理。如業界著名的Q 和 bluebird類庫。

    狀態:pending fufilled rejected,且狀態改變不可逆。

    Promise/A+是Promise的其中一個規範

    promise中:reject方法執行後必定會進入then的第二個方法,若是沒有定義,會直接進入catch。如有網絡異常,直接進入catch。

    promise實現步驟

  2. promise與settimeout及async await執行順序=> macrotask與microtask

    JavaScript 主線程擁有一個執行棧(緣由是js的用途就是與用戶互動並操做dom) 以及一個任務隊列,主線程會依次執行代碼,當遇到函數時,會先將函數 入棧,函數運行完畢後再將該函數 出棧,直到全部代碼執行完畢。

    而主線程則會在 清空當前執行棧後,按照先入先出的順序讀取任務隊列裏面的任務

    事件循環機制

    Tasks, microtasks, queues and schedules

    promise與settimeout及async await執行順序

    而事件循環每次只會入棧一個 macrotask ,主線程執行完該任務後又會先檢查 microtasks 隊列並完成裏面的全部任務後再執行 macrotask。在每一次事件循環中,macrotask 只會提取一個執行,而 microtask 會一直提取,直到 microtasks 隊列清空。 注:通常狀況下,macrotask queues 咱們會直接稱爲 task queues,只有 microtask queues 纔會特別指明。

    microtask在執行棧尾部執行: process.nextTick, Promises, , MutationObserver macrotask在任務隊列尾部添加事件:immediate庫是一個跨瀏覽器的microtask實現。 每執行一個macrotask,就會再將microtask任務執行完成

    process.nextTick方法可 以在當前"執行棧"的尾部----下一次Event Loop(主線程讀取"任務隊列")以前----觸發回調函數。也就是說,它指定的任務老是發生在全部異步任務以前。setImmediate方法則是在當前"任務隊列"的尾部添加事件,也就是說,它指定的任務老是在下一次Event Loop時執行

  3. promise與async/await

    帶 async 關鍵字的函數,它使得你的函數的返回值一定是 promise 對象

    用await聲明的Promise異步返回,必須「等待」到有返回值的時候,代碼才繼續執行下去。

  4. var與let、const

    • var聲明的變量會掛載在window上,而let和const聲明的變量不會:
    • var 存在變量提高,而let和const不會
    • let const存在暫時性死區(在聲明前不可以使用)
    • let const不可重複聲明
  5. set使用場景 let a = new Set([1, 2, 3]); let b = new Set([4, 3, 2]);

    • 數組去重
    • 求交集 [...a].filter(x => b.has(x))
    • 求差集 [...a].filter(x => !b.has(x))
    • 求並集 [...new Set([...a, ...b])]

http

  1. http狀態碼
    • 2** 請求成功 204請求成功,但返回響應報文無內容返回206進行範圍請求
    • 3** 重定向 304未修改 301永久重定向,302臨時重定向,307與302相同
    • 4** 客戶端問題 400請求報文存在語法錯誤,401未認證,403被服務器拒絕訪問
    • 5** 服務器錯誤 500服務器內部錯誤
  2. http與https區別

react&redux

  1. react生命週期 getDerivedStateFromProps讓組件在 props 變化時更新 state,它+componentDidUpdate可替代ComponentWillReceiveProps的全部用例

    getSnapshotBeforeUpdate+ComponentDidUpdate可替代ComponentWillUpdate的全部用例 (這個生命週期不是常常須要的,但能夠用於在恢復期間手動保存滾動位置的狀況。

    新增的這兩個新週期替代了三個舊的生命週期,緣由是:舊的生命週期常常被誤解和濫用,在異步渲染過程當中可能會有更大的問題

    (React16特性)[www.imooc.com/article/279…]

  2. setState原理

    爲何要異步?

    • 保證內部的一致性:由於批量處理對性能是有好處的。若是SetState同步更新,頁面還未渲染,props也不是最新的
    • 同步致使render屢次執行,浪費性能。

    注:setState並非真正的異步。若在react機制中,它爲異步;除此以外,它是同步的,如在定時器、ajax、元素的原生事件。由於setState的實現方法中,有一個變量isBatchingUpdates,它的默認值是false,即表示setState是同步執行。同時還有一個方法batchedUpdates,更改isBatchingUpdates的爲值爲true.當React在調用事件處理函數和自身生命週期以前就會調用這個batchedUpdates

    setState原理

  3. keys

    用於追蹤列表的元素是否被修改、被移動或是被刪除的標記

  4. diff算法

  5. 爲何虛擬dom會提升性能

  6. 更新最低版本包的辦法

  7. 純組件

    使用方法:class MyComponent extends PureComponent {...}

    pureComponent:改變了shouldComponentUpdate(默認返回true)方法,它會自動檢測是否須要調用render。只有當props或state發生變化時才調用會render.

    pure組件是淺比較,即嵌套對象與數組是沒法進行比較的。解決辦法:重寫shouldComponentUpdate或使用Immutable.js庫

  8. 函數式組件

    即無狀態組件,沒有任何生命週期。將數據展現與邏輯處理分開了

    即相同的輸入就會有相同的輸出

  9. 高階組件:輸入一個元組件,返回一個包裝後的組件

  10. Context Context 經過組件樹提供了一個傳遞數據的方法,從而避免了在每個層級手動的傳遞 props 屬性。

    用法:在父組件上定義getChildContext方法,返回一個對象,而後它的子組件就能夠經過this.context屬性來獲取

  11. react的事件機制 react並無將click事件綁定到dom上,而是在document處監聽全部事件。當事件冒泡到document時,將事件內容交給中間層。當事件觸發時,用統一的分發函數dispatchEvent將指定函數執行

  12. async await錯誤處理

    錯誤處理 async await與promise的執行順序

  13. 性能優化

    • 重寫shouldComponentUpdate來避免沒必要要的dom操做。
    • 使用 production 版本的react.js
    • 使用key來幫助react實現列表中的組件的變化
    • webpack優化
    • cdn
    • 減小http
  14. props.children.map函數來遍歷會收到異常提示,爲何?應該如何遍歷? this.props.children 的值有三種可能:

    • 當前組件沒有子節點,它就是 undefined;
    • 有一個子節點,數據類型是 object ;
    • 有多個子節點,數據類型就是 array 。 系統提供React.Children.map()方法安全的遍歷子節點對象
  15. 受控組件與非受控組件區別

    是否將全部數據託管於react 非受控組件有ref屬性,有回調方法

  16. 在什麼狀況下你會優先選擇使用 Class Component 而不是 Functional Component?

    組件須要包含生命週期函數或內部狀態時使用Class Component,不然使用函數式組件

webpack

  1. webpack優化
    • 生產環境與開發環境不要使用同一套配置,會影響打包效率(開發環境須要:熱更新,sourceMap,使用代理,代碼規範檢查。生產環境:提取公共代碼,壓縮混淆)
    • 優化sourcemap
    • 開發環境啓用熱更新
    • 提取第三方庫,利用緩存加載
    • 使用代碼壓縮插件
    • 服務端啓用gzip
    • Tree-shaking消除無用模塊
  2. loader與plugin loader將全部資源轉換爲webpack可處理的模塊,可讓webpack處理非js模塊。幾乎全部loader都須要安裝 plugin,具備apply屬性的js模塊。用於處理loader沒法處理的事情,幾乎能夠處理全部任務,從打包優化和壓縮,直到從新定義環境變量。plugin不須要安裝,可是須要在頭部引入

算法

  1. 數組去重

    • 使用indexOf去重
    • 使用es6的set方法去重
    • 使用對象屬性存在特性,若沒有該屬性就存入新數組
    • 將原數組排序,而後相鄰元素進行比較,若是沒有相同,若不一樣則存入新數組
  2. 數組亂序 洗牌:將數組的最後一個值隨機插入到前面

    var arr = [1,2,3,4,5,6];
    var len = arr.length;
    for(var i=len-1; i>=01; i--){
    	var random = parseInt(Math.random()*len);
    	var tmp = arr[i];
    	arr[i] = arr[random];
    	arr[random] = tmp;
    }
    console.log(arr)
    
    var arr = [1,2,3,4,5,6];
    var newArr = [];
    while(arr.length>0){
    	var random = parseInt(Math.random()*(arr.length-1));
    	newArr.push(arr[random]);
    	arr.splice(random, 1)
    }
    console.log(newArr)
    複製代碼
  3. 快速排序

  4. 數組亂序 洗牌:將數組的最後一個值隨機插入到前面

  5. 快速排序

    複製代碼

設計模式

相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息