2019年 -- 最新前端面試題攻略

1、html和css部分

一、如何理解CSS的盒子模型?

  • 每一個HTML元素都是長方形盒子。 
  • (1)盒子模型有兩種:IE盒子模型、標準W3C盒子模型;IE的content部分包含了border和pading。 
  • (2)標準W3C盒模型包含:內容(content)、填充(padding)、邊界(margin)、邊框(border)。

二、用純 CSS 建立一個三角形的原理是什麼?

  • 把上、左、右三條邊隱藏掉
  • 顏色設爲 transparent
  • #demo { width:0; height: 0; border-width: 20px; border-style: solid; border-color: transparent transparent red transparent; }

三、CSS3中translate、transform、translation和animation的區別

  • translate 移動 經過 translate() 方法,元素從其當前位置移動,根據給定的 left(x 座標) 和 top(y 座標) 位置參數:
  1. transform: translate(50px, 100px);
  2. -ms-transform: translate(50px,100px);
  3. -webkit-transform: translate(50px,100px);
  4. -o-transform: translate(50px,100px);
  5. -moz-transform: translate(50px,100px);
  • transform 改變、變形
  1. 旋轉:rotate() 順時針旋轉給定的角度,容許負值 rotate(30deg)
  2. 扭曲:skew() 元素翻轉給定的角度,根據給定的水平線(X 軸)和垂直線(Y 軸)參數:skew(50deg,20deg)
  3. 縮放:scale() 放大或縮小,根據給定的寬度(X 軸)和高度(Y 軸)參數: scale(2,4)
  4. 移動:translate() 平移,傳進 x,y值,表明沿x軸和y軸平移的距離
  • animation 動畫 語法 animation: name duration timing-function delay iteration-count direction;
  1. animation-name 規定須要綁定到選擇器的 keyframe 名稱。。
  2. animation-duration 規定完成動畫所花費的時間,以秒或毫秒計。
  3. animation-timing-function 規定動畫的速度曲線。
  4. animation-delay 規定在動畫開始以前的延遲。
  5. animation-iteration-count 規定動畫應該播放的次數。
  6. animation-direction 規定是否應該輪流反向播放動畫。

四、使用flex佈局使一個div水平垂直局中

 

父級:#container{
    display:flex;
    justify-content:center;
    align-items: center;
    width: 200px;
    height: 200px;
}
子級:#center{
    width: 100px;
    height: 100px;
    background: red;
}

 

 

五、使用過flex佈局嗎?flex-grow和flex-shrink屬性的做用是什麼? 

  • flex-grow: 屬性決定了父元素在空間分配方向上還有剩餘空間時,如何分配這些剩餘空間。其值爲一個權重(也稱擴張因子),默認爲 0(純數值,無單位),剩餘空間將會按照這個權重來分配。  
  • flex-shrink:這個屬性其實就是定義一個子容器的壓縮比例(當父容器放不下子容器時,不會自動換行,每一個子容器會適當的壓縮,這個值就是設置壓縮的比例的)。他的默認值是1

 

 

2、js代碼面試題

一、數組slice()和splice()方法的區別

 

  • slice() 方法:可從已有的數組中返回選定的元素。slice(開始截取位置,結束截取位置)
var movePos=[11,22,33];
var arr=movePos.slice(1,2);
document.write(arr)  //返回截取的元素:[22]
document.write(arr.length)  //返回數組長度1,截取的數組的長度

 

 

  • splice() :方法向/從數組中添加/刪除項目,而後返回被刪除的項目。
var movePos=[11,22,33,44];
var arr=movePos.splice(1,2);//movePos.splice(開始刪除的下表位置,刪除數組元素的個數);
document.write(arr) ; //返回新的數組:[22,33]
11document.write(arr.length) ;//返回數組長度2

 

 

splice() 方法可刪除從 index 處開始的零個或多個元素,而且用參數列表中聲明的一個或多個值來替換那些被刪除的元素。css

var movePos =[111,222,333,444];    
movePos.splice(2,1,"666")
//movePos.splice(開始刪除的下表位置,刪除數組元素的個數,向數組添加的新項目。);
//從下標2開始刪除一位,並用666替換刪除下表位置的元素

 

 

二、實現add(3)(4)和add(3,4)都輸出7,請實現add方法

function add(x,y){
    var sum = x;
    if(y){
        return (sum + y);
    }
    else
    {
        var add2 = function(z){
            return (sum + z);
        }
        return add2;
    }
} 

 

but這個方法不能擴展成add(3)(4)(5)...和add(3,4,5...)都輸出他們的和,歡迎你們評論區留言,寫一個擴展後的。html

 

 

三、求n的階乘值n!?

 

  • 方案一:利用while循環
function factorial(num){
    var result = 1;
    while(num){
        result *= num;
        num--;
    }
    return result;
}

 

 

 

  • 方案二:使用遞歸

 

function factorial(num){
    if(num <= 0){
        return 1;
    }else{
        return num*arguments.callee(num-1);
    }
}

 

 

四、求1234567890.32格式化爲:1,234,567,890.32。

 

  • 方法一:利用字符串截取的方法
function formatNumber(str) {
    let arr = [];
    let lastStr = str.substring(str.indexOf('.'));
    let formatStr = str.substring(0,str.indexOf('.'))
    let count = formatStr.length
    while (count >= 3) {
        arr.unshift(formatStr.slice(count - 3, count))
        count -= 3
    }
    // 若是是否是3的倍數就另外追加到上去
    formatStr.length % 3 && arr.unshift(formatStr.slice(0, formatStr.length % 3))
    return arr.toString()+lastStr;
}

 

  

 

  • 方法二:使用reduce函數

 

function formatNumber(str) {
    let lastStr = str.substring(str.indexOf('.'));
    let formatStr = str.substring(0,str.indexOf('.'))
    // ["0", "9", "8", "7", "6", "5", "4", "3", "2", "1"]
    return formatStr.split("").reverse().reduce((prev, next, index) => {
        return ((index % 3) ? next : (next + ',')) + prev
    })+lastStr;
}

 

 

 

 

五、評價一下三種方式實現繼承的有缺點並改進;

function Animal(){}
function Cat(){}
方法1:
Cat.prototype = new Animal();方法2:
Cat.ptototype = Animal.prototype;方法3:
Cat.prototype = Object.create(Animal.prototype);

 

 

 

方法1:web

  • 優勢
  1. 正確設置原型鏈實現繼承
  2. 父類實例屬性獲得繼承,原型鏈查找效率提升,也能爲一些屬性提供合理的默認值
  • 缺點
  1. 父類實例屬性爲引用類型時,不恰當地修改會致使全部子類被修改 
  2. 沒法傳遞參數

方法二:面試

  • 優勢
  1. 正確設置原型鏈實現繼承
  • 缺點
  1. 父類構造函數原型與子類相同。修改子類原型添加方法會修改父類

方法三:編程

  • 優勢
  1. 正確設置原型鏈且避免方法1.2中的缺點
  • 缺點
  1. ES5方法須要注意兼容性

改進:數組

 

  • 全部三種方法應該在子類構造函數中調用父類構造函數實現實例屬性初始化
function Cat() {    
    Animal.call(this);
}

 

 

 

  • 封裝一個原型繼承的方法
function extend(Child, Parent) {
    var F = function(){};
    F.prototype = Parent.prototype;
    Child.prototype = new F();
    //用新建立的對象替代子類默認原型,設置Rect.prototype.constructor = Rect;保證一致性
    Child.prototype.constructor = Child;  
}

 

 

六、寫出下列代碼執行的輸出值

var a = 100;
 function test(){
    alert(a);
    var a = 10;
    alert(a);
}
test();

 

 

輸出:undefined,10瀏覽器

var a = 100;
 function test(){
    alert(a);
    var a = 10;
    alert(a);
}
test();

 

 

 

輸出:undefined,10bash

var a = 100;
function test2(){
    alert(a);
    let a = 10;
    alert(a);
}

 

 

輸出:報錯 a is not defined,10多線程

alert(3>2>1);

輸出:false 3>2是true,隱式類型轉換,變成1,1>1確定是false啦閉包

 

 七、談一談JavaScript做用域鏈

  • 當執行一段JavaScript代碼(全局代碼或函數)時,JavaScript引擎會建立爲其建立一個做用域又稱爲執行上下文(Execution Context),在頁面加載後會首先建立一個全局的做用域,而後每執行一個函數,會創建一個對應的做用域,從而造成了一條做用域鏈。每一個做用域都有一條對應的做用域鏈,鏈頭是全局做用域,鏈尾是當前函數做用域。
  • 做用域鏈的做用是用於解析標識符,當函數被建立時(不是執行),會將this、arguments、命名參數和該函數中的全部局部變量添加到該當前做用域中,當JavaScript須要查找變量X的時候(這個過程稱爲變量解析),它首先會從做用域鏈中的鏈尾也就是當前做用域進行查找是否有X屬性,若是沒有找到就順着做用域鏈繼續查找,直到查找到鏈頭,也就是全局做用域鏈,仍未找到該變量的話,就認爲這段代碼的做用域鏈上不存在x變量,並拋出一個引用錯誤(ReferenceError)的異常。

 

八、如何理解JavaScript原型鏈

  • JavaScript中的每一個對象都有一個__proto__屬性(函數對象即有__proto__,又有prototype,prototype指向本身的原型而__proto__指向父級的原型)咱們稱之爲原型,而原型的值也是一個對象,所以它也有本身的原型,這樣就串聯起來了一條原型鏈,原型鏈的鏈頭是Object.prototype.__proto_,它的值比較特殊,值爲null。
  • 原型鏈的做用是用於對象繼承,函數A的原型屬性(prototype property)是一個對象,當這個函數被用做構造函數來建立實例時,該函數的原型屬性將被做爲原型賦值給全部對象實例,好比咱們新建一個數組,數組的方法便從數組的原型上繼承而來。
  •  當訪問對象的一個屬性時, 首先查找對象自己, 找到則返回; 若未找到, 則繼續查找其原型對象的屬性(若是還找不到實際上還會沿着原型鏈向上查找, 直至到根). 只要沒有被覆蓋的話, 對象原型的屬性就能在全部的實例中找到,若整個原型鏈未找到則返回undefined;

 

九、js閉包

  • 閉包,官方對閉包的解釋是:一個擁有許多變量和綁定了這些變量的環境的表達式(一般是一個函數),於是這些變量也是該表達式的一部分。
  • 閉包的特色:
  1. 做爲一個函數變量的一個引用,當函數返回時,其處於激活狀態。
  2. 一個閉包就是當一個函數返回時,一個沒有釋放資源的棧區。
  簡單的說,Javascript容許使用內部函數---即函數定義和函數表達式位於另外一個函數的函數體內。並且,這些內部函數能夠訪問它們所在的外部函數中聲明的全部局部變量、參數和聲明的其餘內部函數。當其中一個這樣的內部函數在包含它們的外部函數以外被調用時,就會造成閉包。
 

 

十、js爲何是單線程語言,怎麼模擬多線程

  • JavaScript的單線程,與它的用途有關。做爲瀏覽器腳本語言,JavaScript的主要用途是與用戶互動,以及操做DOM。這決定了它只能是單線程,不然會帶來很複雜的同步問題。好比,假定JavaScript同時有兩個線程,一個線程在某個DOM節點上添加內容,另外一個線程刪除了這個節點,這時瀏覽器應該以哪一個線程爲準?
  • 爲了利用多核CPU的計算能力,HTML5提出Web Worker標準,容許JavaScript腳本建立多個線程,可是子線程徹底受主線程控制,且不得操做DOM。因此,這個新標準並無改變JavaScript單線程的本質。

 

十一、const a = 1 a = 2 這樣會報錯,可是 對於複合類型來講 const foo = {a:1} foo.a = 2 這樣就不會報錯,爲何?

  • 複合類型的變量,變量名不指向數據,而是指向數據所在的地址。const命令只是保證變量名指向的地址不變,並不保證該地址的數據不變,因此將一個對象聲明爲常量必須很是當心。

如下是其它面試題的詳細

一、深拷貝和淺拷貝

juejin.im/post/5c400a…

二、Object.defineProperty()的用法 

juejin.im/post/5c3870…

三、JS實現AOP 面向切面編程 

juejin.im/post/5c3865…

四、http請求頭以及響應頭詳解

juejin.im/post/5c17d3…

五、瀏覽器輸入一個網址回車後,發生了什麼

juejin.im/post/5c1c52…

六、call,apply和bind模擬實現

juejin.im/post/5c7fe2…

 

連接:https://juejin.im/post/5c7f5923f265da2dd218f195

相關文章
相關標籤/搜索