前端面試題總結 2019---持續更新

題目來自於https://www.jianshu.com/p/eb0f269098d5以及來自個人的整理,答案是參考不同的資料寫的,會不斷完善。

題目是目前前端的一些核心知識點,即使不面試,複習一下也很好。

 

【CSS篇】

1. CSS盒子模型,絕對定位和相對定位

盒模型比較全面的理解:https://www.cnblogs.com/clearsky/p/5696286.html
盒模型即box model,其包含content,padding,border,margin。元素實際佔有的總寬度包含這些所有。而默認的盒模型標準(box-sizing:content-box),只認定內容部分爲width,爲了方便計算,一般在初始會reset 爲:box-sizing:border-box.此時設定的寬度包含了border在內的所有部分。

絕對定位:相對於最近的已經定位的元素進行定位;脫離文檔流。如果沒有最近的定位元素,則相對於body.

相對定位:相對自身定位;不脫離文檔流。

固定定位:相對於瀏覽器窗口;脫離文檔流。

 2.清除浮動,什麼時候需要清除浮動,清除浮動都有哪些方法。

清除浮動詳解,這篇解釋清晰:https://www.jianshu.com/p/5a7854a73298

浮動可以滿足我們需要的佈局,即元素在左右位置排列,但會造成影響。因爲其浮動後,脫離了原來的文檔流,父元素會出現高度坍塌。

清除浮動常用方法:

(1)僞元素,使父元素默認還有一個元素,並且給僞元素添加clear:both,即此元素的左右兩邊均不允許出現浮動元素,此元素會位於浮動元素的下方,從而使父元素被撐開。

.fixed::afer{

         content:'';

         display:table;

         clear:both;

}

(2) 父元素設置:overflow:hidden;其本質是將父元素變爲BFC塊級格式化上下文,其高度包含浮動元素。

 3. 浮層水平垂直居中

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

1) flex佈局

.parent{
    width:100%;
    display:flex;
    justify-content:center;//水平
    align-items:center;//垂直
}
.children{
    width:100px;
    height:100px;
    ...
}

2) 絕對定位

.parent{
    position:abosolute;
    width:100%;
    height:100%;
    ...
}
.children{
    width:100px;
    height:100px;
    position:absolute;
    top:50%;
    left:50%;
    transform:translate(-50%,-50%);
}

3)定位+margin:auto

.parent{
    width:100%;
    position:relative;
}
.child{
    width:100px;
    height:100px;
    position:absolute;
    top:0;
    left:0;
    bottom:0;
    margin:auto;
}

 

 4. display的取值和用法

這裏列舉較常用的,實際很多;

display:none;元素不被顯示

display:block;塊級元素,前後有換行符

display:inline;內聯元素,前後無換行符

display:inline-block;行內塊

display:table;塊級表格,類似表格,前後換行符

可以通過document.getElementById().style.display進行設置

 

5. 選擇器優先級,樣式衝突時,如何解決。

內聯樣式要高於style中的樣式, 引入的樣式文件優先級最低。

!important 要高於其它選擇器的各種組合。權重上 #id爲100,.class爲10,元素本身爲 1,選擇器的權重最大者,樣式衝突時,則會優先選擇其樣式。權重相同時,就近選擇樣式。

 6.對動畫有何瞭解,canvas和svg的區別,CSS3新增僞類有哪些

Css3動畫http://www.w3school.com.cn/css3/css3_animation.asp

animation屬性,可以設置動畫的 animation-name,animation-duration,animation-timing-function,animation-delay,animation-iteration-count,animation-direction.

使用@keyframes定義動畫的名字以及在某個時間點該元素的樣式,(可以定義時間0~100%中的任意點)

如下 @keyframes animationName{

         0%: {},

        100%:{}

}

canvas和svg的區別:canvas 使用javascript進行繪製,所有繪製在js中實現,其內部圖形沒有DOM概念,無法綁定事件,適合圖像密集型遊戲,依賴於分辨率;svg是基於xml繪製,每個圖形元素都是一個DOM,可以綁定事件,不依賴於分辨率,其在放大或是改變尺寸情況下,圖像清晰度不變。

新增僞類舉例::nth-child,:only-child, :first-of-type; :last-of-type

 7. px, em, rem, %的區別, CSS中link和@import的區別

px是像素,一般是固定大小,em,相對於其父元素設置的font-size,若未設置,則爲16px,

 rem是相對於根元素的font-size,若未設置,則爲16px;設置方法爲document.documentElement.style.fontSize,

%是相對於父元素的尺寸的百分比。

link寫在html中:<link href="style.css"  ref="stylesheet" type="text/css">

@import寫在style,或css文件中, @import(style.css)

 

8.瞭解過Flex嗎?

基本上會參考這裏:http://www.runoob.com/w3cnote/flex-grammar.html 其中,還有參考文章,需要深入瞭解的應多加練習。

flex組要是進行頁面的佈局,未來會成爲較主要的佈局方式。

在父元素設置 display:flex屬性之後,其子元素的float,vertical-align,clear屬性將失效。

比如說設置子元素在父元素中水平居中,在其父元素中指定justify-content:center,垂直居中:align-items:center;align-items定義其在交叉軸上的位置關係。在這之前,同flex-direction,來指定主軸是水平還是垂直。

flex屬性較多,需要練習中積累注意。

 

 Javascript篇

1. Javascript裏有哪些數據類型,解釋清楚null 和 undefined,解釋清楚原始類型和引用數據類型。

有原始數據類型和對象類型,原始類型又包含number,string,boolean,null,undefind。 undefined就是這個變量沒有值,比如這個變量定義了,卻沒有賦值;null則是將變量的值清空。可以先定義一個變量,給其賦值爲null。引用類型的值是對象,js不允許直接操作對象的內存空間,實際是操作其引用。定義引用類型的變量,實際上的值是指向對象的指針。

 2.prototype是什麼,怎麼理解原型鏈。

prototype稱之爲對象的原型。每個javescript對象(null除外)都會和另一個對象相關聯,這個另一個對象就是“原型”,每個對象都從“原型”繼承屬性。比如,{},其就可以從Object.Prototype中繼承屬性。對於原型鏈,形成一系列鏈接的原型對象,就是原型鏈。比如new Array() 創建的對象的原型是Array.prototype。其又繼承自Object.prototype.這就形成了鏈接。

從構造函數和原型對象的角度來講。構造函數中有一個屬性是prototype,指向原型對象,共有的屬性會寫在原型對象中。實例有一個屬性__proto__指向其原型對象,原型對象本身也有屬性__proto__指向其原型,這樣就形成了原型鏈

 3.函數的this是什麼含義,什麼情況,怎麼用?

https://blog.csdn.net/qq_33988065/article/details/68957806

1. 全局作用域或者是普通函數中的this,指向全局對象window。

2.方法調用時,誰調用指向誰。

//對象調用 var person={ run:function(){console.log(this)}}; person.run() // person

//事件綁定 btn.οnclick=function(){console.log(this)}//btn

3.構造函數中的this指向未來構造函數創造的實例

4.箭頭函數 this,指向外層作用域。箭頭函數的作用就是統一內外層作用域,無需擔心this指向其它。

4. apply 和 call的用處

讓函數能夠在某個指定的對象下運行。

如:

var obj={x:1};

function foo(){console.log(this.x));

foo.call(obj)//結果爲1

call,apply第一個參數,都是運行函數的作用域,第二個call接受的是一個一個的參數,apply是數組。

https://blog.csdn.net/caseywei/article/details/81746953

https://www.cnblogs.com/ly0612/p/6821124.html

 

 5.數組和對象有哪些原生方法(操作數據)

/****數組中添加和刪除*****/
//1)push:在數組的末尾增加一個或多個元素
var a=[];
a.push("thanks");
console.log(a); // [ 'thanks' ]
a.push("one","two");
console.log(a); // [ 'thanks', 'one', 'two' ]
//2)pop:刪除數組最後一個元素,減小長度並返回它刪除的值
a.pop()
console.log(a);//[ 'thanks', 'one' ]



//3) Array.join() 將數組中的元素都轉化成字符串並通過某字符連接起來,返回生成的字符串。
//不指定分隔符時默認爲此操作不改變原數組
a=[1,2,3];
var b=a.join('-');
console.log(b);//1-2-3
console.log(a)//[1,2,3]


//4)Array.reverse()  將原數組顛倒順序
b=a.reverse();
console.log(b);//[3,2,1]

/**********排序***** */

//5) array.sort()  將數組元素按照字母表順序進行排序,
a=['banana','apple','cherry'];
b=a.sort();
console.log(b);//[ 'apple', 'banana', 'cherry' ]
//5.1) 講數組元素按照數值大小進行排序
a=[33,1,3,23];
b=a.sort((a,b)=>(a-b))
console.log(b) //[ 1, 3, 23, 33 ]
//5.2)不區分大小寫的按照字母表順序進行排序
a=['ant','Dog','Bug','cat'];
b=a.sort((s,t)=>{
    var a=s.toLowerCase();
    var b=t.toLowerCase();
    if (a<b) return -1;
    if (a>b) return 1;
    return 0
})
console.log(b)  // [ 'ant', 'Bug', 'cat', 'Dog' ]


//6)array.concat()數組連接
a=[1,2];
b=[4,5,6];
var c=[7];
var d=a.concat(b);
var e=a.concat(b,c)

console.log(d,e)//[ 1, 2, 4, 5, 6 ] [ 1, 2, 4, 5, 6, 7 ]

//7)slice選取數組中的一個片段 arr.splice(m,n),選取(m,n-1)這幾個元素,如果沒有n,則默認到末尾
a=[1,2,3,4,5,6,7];
b=[1,2,3,4,5,6,7];
c=a.slice(2,4)
console.log(c)//[3,4]
d=b.slice(2)
console.log(d)//[3,4,5,6,7]



/********splice刪除/插入數組,原數組被改變********* */
//array.splice()第一個參數表示開始刪的位置,第二個參數是刪幾個,後面的參數可選,有的話則插入到被刪的位置
a=[1,2,3,4,5];
b=a.splice(1,3) 
console.log(a,b) //[ 1, 5 ] [ 2, 3, 4 ] 
c=a.splice(1)
console.log(a,c)//[ 1 ] [ 5 ]
d=a.splice(0,1,20,[10,15]) 
console.log(a) //[20,[10,15]]


6. 怎樣避免全局污染?箭頭函數的特點是什麼?

可以在一個對象區域內定義變量,這樣所有定義的變量都承載在這一個大變量之下,就不存在全局變量。可以借鑑jQuery的方式,使用匿名函數,在其內部定義變量,(function(){})() 。也可以使用let,這樣定義的變量僅在一個大括號內起作用。

詳見此篇文章:https://www.cnblogs.com/hjvsdr/p/7485592.html

箭頭函數的常用特點:function f1(a,b){  }可以被寫成 (a,b)=>{},這樣保證函數體內的this,同此函數外的this,保持一致。箭頭函數沒有原型(prototype)

7.js怎樣實現一個類?

js中有對象的概念,就是一個個屬性的集合。對於類,js中並沒有明確的定義,可以通過原型對象的方式來實現類,以用來共享一些方法。一般方法是(1)創建構造函數,構造函數的名字即是類名,首字母大寫。構造函數中的屬性值針對於實例後的實例,是專屬於實例的。(2)通過函數名.prototype來添加共享的方法或者重寫預定義的原型對象。(3)通過new關鍵字就可以實例化構造函數,實例中的 __proto__指向原型並繼承原型中的方法。es6通過關鍵字class,從形式上更加方便的實現了類,但本質上並沒有改變。

詳見本人另一篇博客:https://blog.csdn.net/mia1106/article/details/89260735

8.閉包是什麼含義?

閉包可以讀取函數內部的變量。閉包的形成:在一個函數體中,包含另外一個函數,內部函數裏使用了外層函數的變量,同時外層函數把內層函數作爲返回值返回。當外部執行這個返回到外部的內層函數時,會形成閉包。由於內層函數被返回到全局且引用了函數體內的變量,這樣在函數體外部,就可以讀到函數體內的變量了。

因此,閉包有兩個作用,一是可以讀取到函數內部的變量。二是可以將變量保存在內存中。

9.數組去重怎麼實現?

//數組去重
var arr=[2,3,4,3,3,3,5,13,4,31,2];
//
var arrNew=[]
for(let i=0;i<arr.length;i++){
    //如果arrNew中不存在,則放置到arrNew之中
    let flag=0;
    for(let j=0;j<arrNew.length;j++){
        if(arr[i]==arrNew[j]){
            flag=1;
            break;
        }
    }
    if(!flag){
        arrNew.push(arr[i]);
    }
}
console.log(arrNew)

10.深拷貝和淺拷貝的區別,怎麼實現?

深拷貝主要應用於對象和數組。因爲對象和數組,如果直接拷貝,即淺拷貝,賦值過去的是地址。這樣兩個變量會互相影響。對於其它類型的數據,直接拷貝即可。深拷貝實現的兩種方法,見下。

這篇文章,也有較詳盡的敘述https://www.cnblogs.com/echolun/p/7889848.html

//深拷貝與淺拷貝
//淺拷貝舉例
var obj={a:1,b:[2,3]};
var obj1=obj;
obj.a=10;
console.log(obj1,obj)//{ a: 10, b: [ 2, 3 ] } { a: 10, b: [ 2, 3 ] } 兩組變量互相影響
//深拷貝
var obj2={a:1,b:{c:3,d:{f:4}},e:[11,12]};

//方法一
function deepClone(obj){
    var objCopy=Array.isArray(obj)?[]:{};
    for(let k in obj){
        if(typeof(obj[k])=='object'){
            objCopy[k]=deepClone(obj[k])
        }else{
            objCopy[k]=obj[k]
        }
    }
    return objCopy;
}
console.log(deepClone(obj2));//{ a: 1, b: { c: 3, d: { f: 4 } }, e: [ 11, 12 ] }
//方法二
function deepCopy(obj){
    return JSON.parse(JSON.stringify(obj));
}
console.log(deepCopy({a:1,b:[3,4]}))//{a:1,b:[3,4]}

11.下面代碼的輸出是什麼?

for(let i=0;i<10;i++){

    setTimeout(
        
       ()=>{ console.log(i)},1000)
}



for(var i=0;i<5;i++){
    setTimeout(
        ()=>{console.log(i)},1000
    )
}

 

 

其它

1. Ajax 跨域有哪些方法,jsonp 的原理是什麼?

1)使用jsonp。jsonp的原理是script本身就允許加載跨域的js文件。

前端所作設置:

<script>

function doSomething(data){

.....處理data

}

</script>

<script url?callback="doSomething(data)"></script>

後端也需要做處理。

只適用於get請求

2)後端做響應頭設置,前端不做任何設置

後端需要在響應頭增加 : 
Access-Control-Allow-Origin:http://localhost:8081 
Access-Control-Allow-Methods:GET 
兩個字段都可以填寫*表示所有域名和請求都可以跨域

3)jQuery有做jsonp的封裝

參考:https://blog.csdn.net/yewenxiang/article/details/80115103

2.Http協議的頭字段瞭解哪些?一個完整的http請求是什麼?

頭字段:Accept-Charset,希望服務器端返回的編碼格式;Content-type:服務器端返回的內容的類型以及編碼格式

Accept-language,希望服務器端返回的語言類型;Content-language:服務器端返回的語言類型

http請求:瀏覽器建立 TCP連接,瀏覽器向服務器發送請求命令,瀏覽器發送請求頭,服務器端應答,服務器端發送應答頭,服務器端發送內容,服務器端關閉TCP連接。(https://www.cnblogs.com/linjiqin/p/3560152.html

常見的協議頭字段:https://www.cnblogs.com/le220/p/8661934.html

關於 Http的知識詳解:https://www.cnblogs.com/ranyonsue/p/5984001.html

3.cookies,sessionStorage和localStorage的區別

共同點:都是在瀏覽器端存儲數據

區別:(1)webStorage 存儲數據更大,且僅在客戶端存儲數據。cookies每次都會隨同http請求,在客戶端與服務器之間傳送,會佔用帶寬。

(2)localStorage 如果不特別刪除設置,會一直保存在客戶端。sessionStorage會隨着瀏覽器關閉,而消失。

(3)sessionStorage不在不同的瀏覽器窗口共享。另外兩者,只要是同源的,不同窗口的數據可以共享。

4. 如何解決瀏覽器的兼容性問題?

 

5.瞭解 promise嗎?

 

前端框架

1. Vue的生命週期是什麼?

Vue的生命週期有beforeCreated,這時創建了vue實例,但是並沒有初始化$data,$el;created,此時data屬性已經創建,$el並未初始化;beforeMounted,掛載dom之前,此時$el已經初始化;mounted,掛載完成,其中的值也被真正的值填充;beforeUpdated,出現更新之前;updated,出現更新之後;beforeDestroyed組件銷燬之前。destroyed,組件銷燬之後。

參考文章:https://segmentfault.com/a/1190000008010666

2. Vue的實現原理是什麼?是否看過源碼

Vue主要是基於MVVM原理。 View-model以及View之間實現雙向綁定。

實現這個原理又基於Observer,Compiler,Water。

1.Observer: 能夠對數據對象的所有屬性進行監聽,內部函數可以定義setter,getter.如果屬性有變化,可拿到最新值並通知訂閱者。

2.compile:對元素的每個節點的指令進行掃描和解析,根據指定模板替換數據,以及綁定相應的更新函數

3. watcher:作爲observer和compile的橋樑,能夠訂閱並收到每個屬性變化的同制,執行指定綁定的相應的回調函數,從而更新視圖。

可參考別人的文章:https://segmentfault.com/a/1190000013294870

https://www.cnblogs.com/tylerdonet/p/9893065.html

 

 

前端工程化

1. 爲什麼要前端工程化?

(1)是其模塊化/組件化

從軟件工程的角度來考慮,我們希望我們的項目是“高內聚,低耦合”,原有的前端模式,代碼會分別寫在html,css,js文件中,所有的內容都基本上分佈在這三個地方,這樣每份文件都擔負巨大的代碼,不便於書寫,不便於維護,不便於管理。工程化之後,將項目模塊化/組件化,可以分工協作一個項目,也便於管理和維護。

(2)重視代碼規範

工程化中,前端代碼的規範性也會被提到。這也有利於團隊的協作和維護。

(3)其它等

前端工程化還包含分支管理,自動化測試,構建和部署。

前端的工程化,是一個需要長期累積的實踐經驗,首先,可以打開工程化的項目,看其主要的結構模式,其次,我們很多時候練習的是web應用開發,可以在開發的過程,擴展理解的層面,從整個開發到部署的整個工程去學習與認識。

以下這篇文章是對於前端工程化的理解:

https://www.cnblogs.com/fsyz/p/8274727.html

https://www.jianshu.com/p/171996f5b12c

 

 

歡迎對問題進行討論,如果對您有用,別忘記點贊喔。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章