天天看點

前端可能問到的面試題(ts,js,css,es6)

1.void,null,undefined,never,NaN

void:無傳回值,隻能指派undefined和null

null:空值,表示不存在

undefined:未定義,聲明了但沒有指派,對象沒有指派的屬性,對象沒有傳回值

never:永不存在的值的類型,是

抛出異常或根本沒有傳回值的函數表達式

的傳回值類型

NaN:和任何值都不相等,包括自身

2.const和readonly

const:修飾的常量是靜态屬性。聲明時必須指派,指派後不能再改變,實際上是變量至指向的記憶體位址所儲存的資料不改動,對于簡單類型,值就儲存在變量指向的記憶體位址。對于

複合類型的資料(引用類型)

,const隻能保證這個指針是固定的,至于指針指向的資料結構是否可變就不能控制。

readonly :修飾的常量是動态屬性(值在運作的時候獲得)。可以在聲明或構造函數中初始化

3.接口和泛型

接口:定義了要遵循的類的文法,實作接口的類必須實作它的所有成員。不同類之間公有的屬性和方法可以抽象為一個接口

泛型:解決類,接口,方法的複用性(

傳入什麼類型就傳回什麼類型

),以及對不特定資料類型的支援

4.匿名函數和箭頭函數

匿名函數:聲明是沒有任何命名辨別符的函數,在運作時動态聲明的,可以接受輸入和傳回輸出,在初始建立之後通常是不可通路的

let fun=function(x:number,y:number):number{
	return x+y;
}
           

箭頭函數:相當于匿名函數并且簡化了函數的定義。沒有prototype原型,所有箭頭函數本身沒有this,this在箭頭函數中已經按照詞法作用域綁定了,this指向是固定的。沒有構造函數

箭頭函數的this指向該函數所在的作用域指向的對象

5.findindex(),indexof(),forEach()

findindex()對于空數組不執行,也不使适用于字元串。範圍更廣,可以根據不同條件進行查詢。傳回的是符合查詢條件的第一個值的

索引

.

let arr = [1, 1, 2, 2, 8, 8,5,4]
function check(a) {
    return a>1
}
let result = arr.findIndex(check)
console.log(result)  //2
           

indexof()傳回某個指定的字元串值在字元串中首次出現的位置。空數組和字元串都會執行。

forEach() 對于空數組不執行,用于調用數組的每個元素,并将元素傳遞給回調函數。

示例代碼

6.浏覽器重定向頁面,浏覽器打開新頁面

重定向頁面

window.location.href="https://www.baidu.com/"
window.location.replace("https://www.baidu.com/")
           

打開新頁面,視窗

7.splice()與slice()

splice(2,7) 表示從索引2開始的位置,截取7個長度,

會傳回截取後的資料

slice(2,7) 表示從索引2開始的位置,截取到6索引的位置(不包含7),

不會改變原數組

8.promise

promise:是一個構造函數,可以執行個體化promise執行個體。有兩個函數resolve(成功時的回調函數)和reject(失敗後的回調函數)。在promise的構造函數的prototype屬性上有then()方法。

9.px,em,rem

px:像素px是相對于顯示器螢幕分辨率而言的。缺點沒有彈性,IE可能不相容

em:參考物是父元素的font-size,具有繼承的特點。相對于目前對象内文本的字型尺寸。如目前對行内文本的字型尺寸未被人為設定,則相對于浏覽器的預設字型尺寸。

rem:rem是相對于根元素html, 不會被它的父元素影響

10.css選擇器

标簽選擇器div 類選擇器. id選擇器# 子類選擇器> 兄弟選擇器~ 全局選擇器* 相鄰選擇器+ 包含選擇器 僞類選擇器(:hover nth-child(n):)

僞類(before,after)與僞類選擇器根本差別:是否建立了新元素

11.position有哪些屬性

relative:相對于原來位置移動,元素設定此屬性之後仍然處在文檔流中,不影響其他元素的布局

absolute:元素會脫離文檔流,如果設定偏移量,會影響其他元素的位置定位。絕對定位是相對于元素最近的已定位的祖先元素(即是設定了絕對定位或者相對定位的祖先元素)。如果元素沒有已定位的祖先元素,那麼它的位置則是相對于最初的包含塊(body)

fixed:相對于浏覽器視窗,生成固定定位

inherit:繼承父元素的position 屬性的值

static:預設值。沒有定位,元素出現在正常的流中

sticky:粘性定位,該定位基于使用者滾動的位置。

12.垂直水準居中

<body>
    <div id="aaa">
        <div id="bbb"></div>
    </div>
</body>
           

方法一 相對絕對定位

body{
        margin: 0px;
        padding: 0px;
    }
    #aaa{
        position: relative;
        width: 500px;
        height: 500px;
        background: red;
    }
    #bbb{
        position:absolute;
        width: 300px;
        height: 300px;
        background: pink;
        margin: auto;
        left: 0;
        right: 0;
        top: 0;
        bottom: 0;
    }
           

方法2 flex布局

body {
      margin: 0px;
      padding: 0px;
    }
    #aaa {
      display: flex;
      width: 500px;
      height: 500px;
      justify-content: center;
      align-items: center;
      background-color: red;
    }
    #bbb {
      width: 300px;
      height: 300px;
      background-color: pink;
    }
           

13.清除浮動

方法一:添加額外标簽,并在标簽中使用clear:both (不推薦)

方法二:添加僞類元素(::after),設定clear:both。注意必須塊級元素且IE8以上

14.行内元素與塊級元素

塊級元素:獨占一行,預設情況下,其寬度自動填滿其父元素寬度

塊級元素可以設定width,height,margin,padding

行内元素:不會獨占一行,行内元素設定width,height屬性無效,它的長度高度主要根據内容決定。行内元素的margin和padding屬性

水準方向有效果,垂直方向沒有效果

15.js與ts的差別

ts是js的超集。js是腳本語言,ts是面向對象程式設計語言。ts支援可選參數,靜态類型,接口,js不支援。ts在編譯時就能報錯,js運作時才暴報錯。ts是強類型語言,可以明确知道參數類型。

16.axios,ajax,fetch

axios 基于promise用于浏覽器和node.js的http用戶端。是對ajax的封裝,安全性更高。有then鍊,可以異步程式設計

function Callback<T>(promise: Promise<T>) {
    return promise
        .then((data) => { data })
        .catch((err) => { err })
}

function test() {
    return Callback(axios.get(""))
}
           

fetch隻對網絡請求報錯,對400,500都當做成功的請求,需要封裝去處理,是原生js,沒有使用XMLHttpRequest對象

ajax底層使用XMLHttpRequest,

Ajax引擎在用戶端運作,特點是實作局部重新整理,支援異步請求的技術。不支援浏覽器back,暴露了與伺服器互動的細節

XmlHttpRequest可以在使用JavaScript向伺服器提出請求并處理響應,而不阻塞使用者。通過XMLHttpRequest對象,Web開發人員可以在頁面加載以後進行頁面的局部更新。

$.ajax({
   type: 'POST',
   url: url,
   data: data,
   dataType: dataType,
   success: function () {},
   error: function () {}
});
           

17.http狀态碼

2xx:伺服器成功處理請求

例如:200 (成功)表示用戶端發送的請求在伺服器被正常的處理了。

3xx:狀态碼用于重定向

例如:301 永久性重定向,請求的資源被配置設定了新的URI,以後都使用這個。

302 臨時性重定向,請求的資源被配置設定了新的URI,本次使用這個。

4xx:請求錯誤,用戶端或許有錯誤

例如:404 伺服器找不到資源 403 請求的資源通路被拒絕

5xx:伺服器錯誤

例如:500 伺服器執行請求時發送異常 503 伺服器暫時無法處理請求

18.a标簽的href和target屬性

href屬性用于指定超連結目标的url

target屬性規定在何處打開連結文檔

_blank 在新視窗打開連結

_self 在目前視窗打開連結(預設)

_top 在整個視窗中打開連結

_parent 在父架構集中打開連結

alt屬性規定在圖像無法顯示時的替代文本

title屬性規定的是在滑鼠以上元素時顯示的文本

19.for in 與 for of

for in 适合周遊對象,數組,通常用來周遊對象的鍵名,原型鍊上所有屬性都會呗通路,用hasOwnProperty()解決

for of (es6)适合周遊樹,數組,數組對象,字元串等,通常用來周遊鍵值

20.for循環與setTimeout()

https://www.jb51.net/article/122489.htm

21.網站的登入狀态是如何儲存的,完整的登入流程是什麼?

通過cookie儲存登入狀态。cookie存儲token,每次請求到後端伺服器都會帶上token,進而驗證使用者是否登入。

1.用戶端請求背景登入接口。

2.背景驗證通過後,将使用者的登入狀态儲存至cookie并寫入用戶端。

3.用戶端再次登入網站,請求login接口時,背景直接從用戶端擷取到該使用者寫入cookie的登入狀态。

4.通過對該狀态的驗證,确認使用者是否需要再次登入。

5.如cookie過期,則跳轉至登入頁;如未過期,則直接顯示為已登入狀态。

22.DOCTYPE作用

聲明位于文檔中最前面的位置,處于标簽之前。可以告知浏覽器文檔使用何種規範解析頁面(html,xhtml)

23.call,apply,bind

let a=[1,2,3,4,5]
console.log(Math.Max,call(null,2,3,4,5,6)) //6
console.log(Math.Max,apply(null,[2,3,4,5,6])) //6
let b=Math.Max,bind(null,2,3,4,5,6)
b() //6
           

call和apply直接執行,bind事先将方法的this改為我們想要的結果,需要時再調用執行。apply的第二個參數是以數組形式傳入的。call和bind以清單參數傳遞。

23.src,href

href是元素或文檔與指定資源聯通,需要的時候再引用

src是下載下傳後嵌入構成文檔直接内容

24. get post

get:長度限制為2k,參數在url可見,速度更快

post:沒有長度限制,參數寫在請求頭裡面,安全性更高,速度不如get(因為在第三次握手時,會發送post請求頭,伺服器才會傳回100 continue ,用戶端此時才發送資料。而get在第三次握手時就已經攜帶了資料)

25.三次握手

why:為了保證可靠的資料傳輸,防止無效的請求又發送到伺服器。

ACK=1 确認号有效

SYN=1 請求建立連接配接

seq 序列号

ack 期望下一次接收到的序列号

前端可能問到的面試題(ts,js,css,es6)

26.jsonp跨域

用戶端通過script标簽的src屬性發送請求,并且定義一個回調函數。伺服器端響應請求後會傳入參數動态執行回調函數,就實作了跨域。因為是script标簽,是以傳回的資料會直接當作js語言執行就會産生錯誤,是以需要回調函數的存在,關鍵是伺服器傳回的資料外層需要需要包裹一層函數

react 使用代理中間件 http-proxy-middleware實作跨域請求

const proxy = require('http-proxy-middleware')
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function (app) {

    app.use(createProxyMiddleware('/api',{
        target:'http://localhost:3300',
        changeOrigin: true
    }))

};
           

27.xss,CSRF攻擊

xss:跨站腳本攻擊,利用網站對使用者輸入沒有進行限制或過濾,進而在頁面中嵌入某些代碼,當别的使用者通路到該網頁時,會執行對應的代碼,進而使得攻擊者可以擷取。

防禦:設定Cookie的屬性為Http only,這樣js就無法擷取Cookie值

CSRF攻擊:跨域請求僞造,

防禦:使用随機token或驗證碼

28.浏覽器輸入url到渲染的過程

1.首先是域名解析,解析到對應的ip位址

2.三次握手,請求建立連接配接

3.發送http請求,伺服器響應請求,浏覽器擷取html源碼

4.解析html并且建構DOM樹

5.解析css生成css對象模型

6.dom樹和css附着在一起呈現reader tree(重排和重繪)

7.浏覽器計算節點的位置和樣式進行布局

29.重排reflow和重繪repaint

重排:元素的規模,位置和隐藏等改變時,都會引起回流。

引起重排的條件:首次渲染,删除或增加dom元素,元素位置的改變,尺寸的改變,視窗尺寸的改變,讀取某些元素的值。一定會引起重繪。

重繪:元素的外觀改變觸發的浏覽器行為,浏覽器會根據元素的新屬性重新繪制,呈現新的外觀。如:color

優化:

1.合并多次dom的修改

2.直接改變元素的類名,切換類名

3.經常進行重排的元素設定position:absolute和fixed ,脫離文檔流,不會影響到其他元素

4.避免使用table布局,一個小改動會引起整個table重新布局

5.經常通路元素屬性的操作時,将屬性賦給局部變量進行計算。

30.new一個對象的過程

其實是一種繼承的方式, 通過new,執行個體與構造函數通過原型鍊連接配接了起來出來,是以執行個體能通路到構造函數的屬性。改變了構造函數的this指向

ps:

每個對象的__proto__屬性都指向原型對象

每個構造函數都有prototype原型對象

prototype原型對象裡都有constructor指向它的構造函數

31.盒子模型

所有的html元素都可以看作為盒模型,即content+padding+border+margin

1.标準模型:box-sizing:content-box

内容大小(寬高):content的大小,即width和height

設定padding時,content大小不變,整體變大

2.IE模型:box-sizing:border-box

内容大小:content(width,height)+padding+border

因為是包括padding的,是以設定padding時,元素會被擠壓,整體不變

32.什麼是flex布局

彈性布局,任何元素都可以指定為flex,随着網頁的大小自适應布局。采用flex布局的元素稱為容器,子元素稱為項目。設定了flex之後,float,clear等屬性失效。

flex(flex-grow、flex-shrink、flex-basis):

flex-grow定義項目的放大比例,預設為0,即如果存在剩餘空間,也不放大

flex-shrink 定義了項目的縮小比例,預設為1,即如果空間不足,該項目将縮小

flex-basis給上面兩個屬性配置設定多餘空間之前, 計算項目是否有多餘空間, 預設值為 auto, 即項目本身的大小

flex:auto代表 1 1 auto

flex:1代表 1 1 0

33.BFC

塊級上下文,獨立的渲染區域。區域内部與外部無關。BFC中的所有子元素的左外邊都會與父塊的左邊接觸。

作用:

1.防止被浮動的元素擋住

2.解決margin塌陷的問題。因為同一BFC的兩個box之間的margin以大的為準

3.自适應兩欄布局

4.清除浮動(BFC計算高度時會包括浮動的高度,會清除内部子元素浮動的影響,父元素在計算其高度時,加入了浮動元素的高度,“順便”達成了清除浮動的目标,是以父元素就包裹住了子元素)

如何建立BFC:

1.float不為none

2.overflow不為visible

3.position不為static或relative

4.display是lnline-block,inline-flex,flex,table-cell,table-caption

34.typyof和instanceof

typeof用來判斷基本資料類型,傳回的是字元串,但是對于null,object和array傳回的都是object。

instanceof一個變量是否屬于某個對象的執行個體,傳回的是Boolean類型,判斷某個構造函數的prototype屬性是否存在對象的原型鍊上。

下面手寫實作一下instanceof方法

function test_instanceof(L, R) {
    let LL = L.__proto__
    let RR = R.prototype
    while (true) {
        if (LL === null) return false
        if (RR === LL) return true
        LL=LL.__proto__
    }
}
function t() {   }
let a = new t()
console.log(test_instanceof(a,t)) //true
console.log(test_instanceof(a,Object)) //true
           

35.構造函數和普通函數的差別

構造函數可以生成執行個體對象

調用方式不同:構造函數用new關鍵字調用

首字母大小寫:構造函數首字母一般大寫

this指向不同:普通函數this指向window,構造函數的this指向建立的執行個體對象。

36.原型,原型對象

原型對象:構造函數prototype指向的就是原型對象

原型:函數有原型,函數的這個原型指向一個對象即原型對象

37.js繼承

1.原型鍊繼承:父類的執行個體充當子類的原型對象

缺點:父類的屬性是所有子類共享的,不能多繼承

function father() {  }
function son() {}
son.prototype=new father()
           

2.構造函數繼承:借用父類的構造函數來增強子類執行個體,等于是把父類的執行個體屬性複制一份給子類執行個體,可以多繼承

缺點:無法實作函數的複用,執行個體并不是父類的執行個體,隻是子類的執行個體,隻繼承父類,不繼承原型

function Super(val){
  this.val = val;//可以傳遞參數
  this.arr = [1];
}
function Sub(val){
    Super.call(this,val);//核心代碼
    //通過call()和apply()方法在新建立的對象上執行構造函數
}
           

3.組合式繼承:使用原型鍊實作對原型屬性和方法的繼承,而通過構造函數來實作對執行個體屬性的繼承。

function Parent(name){
            this.name = name;
            this.colors = ['red', 'blue', 'green'];
        }
        Parent.prototype.getName = function(){
            console.log(this.name);
        }
        function Child(name,age){
            Parent.call(this,name);// 第二次調用 Parent()
            this.age = age;
        }
        Child.prototype = new Parent(); // 第一次調用 Parent()
           

38.call,apply,bind

第一個參數都是this要指向的對象,call第二個參數是參數清單的方式傳入,apply第二個參數是數組的方式傳入

call與apply是立即調用,bind是傳回對應函數,需要時調用

function show(x){
			console.log(x);
		}
		let person={
			name:"aa",
		};
		show.call(person,"男");
		show.apply(person,["女"]);
		let ss=show.bind(person,"111");
		ss()
           

bind的實作

39.深拷貝的實作

40.promise

Promise,就是一個對象,用來傳遞異步操作的消息,可以進行異步操作

async await 解決回調地獄,文法糖

async function test1(){
    console.log("11")
    await test()
    console.log("22")
}
test1()
new Promise(function (resolve) {
    console.log("33")
       resolve();
}).then(function () {
    console.log("44")
})
function test() {
    console.log("test")
}
//11 test 33 22 44
           

macro-task(宏任務):包括整體代碼script,setTimeout,setInterval

micro-task(微任務):Promise.then,process.nextTick

補充一個宏任務和微任務

前端可能問到的面試題(ts,js,css,es6)
前端可能問到的面試題(ts,js,css,es6)

41.強緩存和協商緩存

浏覽器第一次向伺服器發起請求時,伺服器響應請求後,浏覽器端會進行緩存。伺服器會将最後一次修改時間last-modified發送給用戶端進行記錄,同時還會生成并發送Etag

強緩存

:浏覽器請求資源時,會擷取該資源緩存的header資訊,根據cache-control判斷是否從緩存中擷取資源。

cache-control:max-age=31536000,public,immutable
           

max-age:緩存時間(s)

public:伺服器和浏覽器都可以緩存

immutable:資源永遠改變(使用者重新整理浏覽器也不發送請求)

協商緩存

:浏覽器每次請求資源時,向伺服器發送請求并且攜帶header中的Etag和last-modified,伺服器判斷是否改變,如果改變就傳回新的資源和新的etag,last-modified以及200狀态碼。如果沒有改變,傳回304狀态碼,浏覽器就讀取本地資源。

注意伺服器端header會改變

// response header
etag: '5c20abbd-e2e8'
last-modified: Mon, 24 Dec 2018 09:49:49 GMT

// request header 變為
if-none-matched: '5c20abbd-e2e8'
if-modified-since: Mon, 24 Dec 2018 09:49:49 GMT
           

已經有last-modified為什麼要使用etag

1.有些資源的改變在1s内改變多次,last-modified對這種操作無法精确

2.某些請求是周期性的,沒有修改内容,

3.某些伺服器無法精确到最後修改時間

42.JSON.parse()和JSON.stringity()

JSON.parse():一個字元串中解析出json

JSON.stringity():從一個對象中解析出字元串

繼續閱讀