亚洲农村老熟妇肥BBBB_无码人妻精品一区二区蜜桃色_精品亚洲AⅤ无码午夜在线观看_中文字幕熟妇人妻在线视频_囯产色无码精品视频免费

當(dāng)前位置: 首頁(yè) > 軍事新聞 >

前端面試干貨:四月份前端面試題總指南(下篇

時(shí)間:2020-08-05 17:45來(lái)源:網(wǎng)絡(luò)整理 瀏覽:
接著昨天的前端面試題總結(jié)寫(xiě)的哈,有在找工作的伙伴,建議仔細(xì)閱讀!10.什么是原型鏈原型:每個(gè)javascript創(chuàng)建的時(shí)候都會(huì)關(guān)聯(lián)另一個(gè)對(duì)象

接著昨天的前端面試題總結(jié)寫(xiě)的哈,有在找工作的伙伴,建議仔細(xì)閱讀!

10.什么是原型鏈

原型:每個(gè)javascript創(chuàng)建的時(shí)候都會(huì)關(guān)聯(lián)另一個(gè)對(duì)象,這個(gè)對(duì)象就是原型,對(duì)象會(huì)從原型繼承屬性構(gòu)造函數(shù)可以通過(guò)prototype去尋找他關(guān)聯(lián)的原型,A.prototype就是它關(guān)聯(lián)的原型對(duì)象,原型對(duì)象可以通過(guò)構(gòu)造器constructor來(lái)尋找與自身關(guān)聯(lián)的構(gòu)造函數(shù)

function A () {
}
A.prototype.constructor === A //true

原型鏈:原型鏈?zhǔn)怯稍蛯?duì)象組成,每個(gè)對(duì)象都有proto屬性,指向該構(gòu)造函數(shù)的原型,proto將對(duì)象連接起來(lái)組成了原型鏈原型鏈查找機(jī)制:當(dāng)查找對(duì)象的屬性時(shí),如果實(shí)例對(duì)象不存在該屬性,沿著原型鏈向上一級(jí)查找,直到找到object.prototype(也就是對(duì)象原型object.prototype為null),停止查找到返回undefined

function A () {
}
new A().__proto__ === A.prototype //true

原型上的屬性和方法被實(shí)例共享

function A () {
}
A.prototype.name = 'a'
var a = new A()
var b = new A()
a.name === b.name // true
a.__proto__.name === b.__proto__.name // true

instanceOf原理:instamceOf可以判斷實(shí)例對(duì)象的proto屬性與構(gòu)造函數(shù)的prototype是不是同一地址(如果網(wǎng)頁(yè)中有多個(gè)全局環(huán)境就會(huì)不準(zhǔn)確)

function _instanceOf(obj, type) {
var obj = obj.__proto__
var type = type.prototype
while(true) {
if (obj == null) {
return false
}
if (obj == type) {
return true
}
obj = obj.__proto__
}
}
var a = [1, 2, 3]
_instanceOf(a, Array)
11.深拷貝和淺拷貝

淺拷貝只是復(fù)制引用,新舊對(duì)象共享一塊內(nèi)存,一般把第一層拷貝到一個(gè)對(duì)象上,改變其中一個(gè)另一個(gè)也會(huì)改變

var obj = {
name: 'a',
age: 18,
arr: [1, 2]
}
function shallowCopy(obj) {
var newObj = {};
for (var prop in obj) {
if (obj.hasOwnProperty(prop)) { // 過(guò)濾掉原型上的屬性
newObj[prop] = obj[prop];
}
}
return newObj;
}
var obj1 = shallowCopy(obj)
var obj2 = obj
obj1.name = 'b'
obj2.age = 20
obj2.arr[0] = 3
obj1.arr[0] = 4
console.log(obj) // {name: "a", age: 20, arr: [4, 2]}
console.log(obj1) // {name: "b", age: 18, arr: [4, 2]}
console.log(obj2) // {name: "a", age: 20, arr: [4, 2]}

我們通過(guò)淺拷貝得到obj1,改變obj1的name,obj不會(huì)發(fā)生改變,通過(guò)賦值得到obj2,obj2改變age值obj的值也會(huì)被改變。說(shuō)明賦值得到的對(duì)象只是改變了指針,淺拷貝是創(chuàng)建了新對(duì)象。

我們通過(guò)obj2和obj1都改變的值,發(fā)現(xiàn)obj,ob1,obj2都發(fā)生了改變,所以無(wú)論是淺拷貝還是賦值都會(huì)改變?cè)紨?shù)據(jù)(淺拷貝只拷貝了一層對(duì)象的屬性)

深拷貝:復(fù)制并創(chuàng)建一個(gè)一摸一樣的對(duì)象(遞歸復(fù)制了所有層級(jí)),不共享內(nèi)存,改變其中一個(gè)另一個(gè)不會(huì)改變

var obj = {
name: 'a',
age: 18,
arr: [1, 2]
}
function copy (obj) {
var newobj = Array.isArray(obj) ? [] : {};
if(typeof obj !== 'object'){
return;
}
for(var i in obj){
if (obj.hasOwnProperty(i)) {
newobj[i] = typeof obj[i] === 'object' ? copy(obj[i]) : obj[i];
}
}
return newobj
}
var copyObj = copy(obj)
copyObj.arr[0] = 3
console.log(copyObj) //{name: "a", age: 20, arr: [3, 2]}
console.log(obj) //{name: "a", age: 20, arr: [1, 2]}
12.實(shí)現(xiàn)繼承

原型鏈繼承(在實(shí)例化一個(gè)類(lèi)時(shí),新創(chuàng)建的對(duì)象復(fù)制了父類(lèi)構(gòu)造函數(shù)的屬性和方法,并將proto指向父類(lèi)的原型對(duì)象,當(dāng)在子類(lèi)上找不到對(duì)應(yīng)的屬性和方法時(shí),將會(huì)在父類(lèi)實(shí)例上去找。)

function Big () {
this.age = [1, 2, 3]
}
Big.prototype.getAge = function () {
return this.age
}
function Small() {}
Small.prototype = new Big()
var small = new Small()
console.log(small.age) // [1, 2, 3]
console.log(small.getAge()) // [1, 2, 3]

缺點(diǎn)1:引用缺陷(修改其中一個(gè)Small實(shí)例的父類(lèi)變量會(huì)影響所有繼承Big的實(shí)例)

small.age[0] = 12
var small1 = new Small()
console.log(small1.age) // [12, 2, 3]
console.log(small.age) // [12, 2, 3]

缺點(diǎn)2:無(wú)法為不同的實(shí)例初始化繼承來(lái)的屬性

function Big (name) {
this.age = [1, 2, 3]
this.name = name
}
Big.prototype.getAge = function () {
return this.age
}
function Small() {}
Small.prototype = new Big('small')
var small = new Small()
var small1 = new Small()
console.log(small1.name) // small
console.log(small.name) // small

構(gòu)造函數(shù)繼承(在子類(lèi)的構(gòu)造函數(shù)中執(zhí)行父類(lèi)的構(gòu)造函數(shù),并為其綁定子類(lèi)的this,讓父類(lèi)的構(gòu)造函數(shù)把成員屬性和方法都掛到子類(lèi)的this上)

function Big (name) {
this.age = [1, 2, 3]
this.name = name
}
Big.prototype.getAge = function () {
return this.age
}
function Small(name) {
Big.apply(this, arguments)
}
var small = new Small('small')
var small1 = new Small('small1')
console.log(small.name) // small
console.log(small1.name) // small1
small.age[0] = 12
console.log(small.age) // [12, 2, 3]
console.log(small1.age) // [1, 2, 3]

缺點(diǎn):無(wú)法訪問(wèn)原型上的方法

small.getAge() //small.getAge is not a function組合式繼承(將原型鏈繼承和構(gòu)造函數(shù)繼承組合到一起, 綜合了原型鏈繼承和構(gòu)造函數(shù)繼承的優(yōu)點(diǎn))

function Big (name) {
this.age = [1, 2, 3]
this.name = name
}
Big.prototype.getAge = function () {
return this.age
}
function Small(name) {
Big.apply(this, arguments)
}
Small.prototype = new Big()
var small = new Small('small')
var small1 = new Small('small1')
console.log(small.name) // small
console.log(small1.name) // small1
small.age[0] = 12
console.log(small.age) // [12, 2, 3]
console.log(small1.age) // [1, 2, 3]
console.log(small.getAge()) // [12, 2, 3]
console.log(small1.getAge()) // [1, 2, 3]

小缺點(diǎn):調(diào)用了兩次父類(lèi)構(gòu)造函數(shù)

寄生組合式繼承(在組合繼承的基礎(chǔ)上減少一次多余的調(diào)用父類(lèi)構(gòu)造函數(shù))

function Big (name) {
this.age = [1, 2, 3]
this.name = name
}
Big.prototype.getAge = function () {
return this.age
}
function Small(name) {
Big.apply(this, arguments)
}
// 對(duì)父類(lèi)原型進(jìn)行拷貝,否則子類(lèi)原型和父類(lèi)原型指向同一個(gè)對(duì)象,修改子類(lèi)原型會(huì)影響父類(lèi)
Small.prototype = Object.create(Big.prototype)
var small = new Small('small')
var small1 = new Small('small1')
console.log(small.name) // small
console.log(small1.name) // small1
small.age[0] = 12
console.log(small.age) // [12, 2, 3]
console.log(small1.age) // [1, 2, 3]
console.log(small.getAge()) // [12, 2, 3]
console.log(small1.getAge()) // [1, 2, 3]

注意:對(duì)父類(lèi)原型進(jìn)行拷貝后賦值給子類(lèi)原型,因此Small上的constructor屬性被重寫(xiě),需要修復(fù)Small.prototype.constructor = Dog;

extends繼承(class和extends是es6新增的,class創(chuàng)建一個(gè)類(lèi),extends實(shí)現(xiàn)繼承)

class Big {
constructor(age) {
this.age = age;
}
getAge () {
return this.age
}
}
class Small extends Big {
constructor(age) {
super(age)
}
}
var small = new Small([1, 2, 3])
var small1 = new Small([12, 2, 3])
small.age[0] = 13
console.log(small.age) // [13, 2, 3]
console.log(small.getAge()) // [13, 2, 3]
console.log(small1.age) // [12, 2, 3]
console.log(small1.getAge()) // [12, 2, 3]
瀏覽器網(wǎng)絡(luò)1.常用http狀態(tài)碼

200 成功狀態(tài)碼301 永久重定向,302 臨時(shí)重定向400 請(qǐng)求語(yǔ)法錯(cuò)誤, 401 請(qǐng)求需要http認(rèn)證,403 不允許訪問(wèn)資源,404 資源未找到500 服務(wù)器內(nèi)部錯(cuò)誤,502 訪問(wèn)時(shí)出錯(cuò),503 服務(wù)器忙,無(wú)法響應(yīng)

2.https原理

http協(xié)議:客戶端瀏覽器與web服務(wù)器之間的應(yīng)用層通訊協(xié)議https協(xié)議:HTTP+SSL/TLS,http下加入SSL層,https安全基礎(chǔ)時(shí)SSL,用于安全的HTTP數(shù)據(jù)傳輸https優(yōu)勢(shì):內(nèi)容經(jīng)過(guò)對(duì)稱(chēng)加密,每個(gè)連接會(huì)生成唯一的加密密鑰,內(nèi)容經(jīng)過(guò)完整性校驗(yàn),第三方無(wú)法偽造身份使用對(duì)稱(chēng)加密(加密和解密使用的是同一個(gè)密鑰)被中間人攔截,中間人可以獲取密鑰,就可以對(duì)傳輸?shù)男畔⑦M(jìn)行窺視和篡改使用非對(duì)稱(chēng)密鑰(雙方必須協(xié)商一對(duì)密鑰,一個(gè)私鑰和一個(gè)公鑰)用私鑰加密的數(shù)據(jù),只有對(duì)應(yīng)的公鑰才能解密,用公鑰加密的數(shù)據(jù),只有對(duì)應(yīng)的私鑰才能解密,弊端:RSA算法很慢非對(duì)稱(chēng)密鑰+對(duì)稱(chēng)密鑰(結(jié)合兩者優(yōu)點(diǎn))客戶端獲取公鑰確認(rèn)服務(wù)器身份通過(guò)SSL證書(shū),客戶端接受到服務(wù)端發(fā)來(lái)的SSL證書(shū)給客戶端。

3.前端安全

XSS攻擊:注入惡意代碼來(lái)攻擊。攻擊者在目標(biāo)網(wǎng)站上注入惡意代碼,被攻擊者登陸網(wǎng)站執(zhí)行這些惡意代碼,這些腳本可以讀取 cookie,session tokens,或者其它敏感的網(wǎng)站信息,對(duì)用戶進(jìn)行釣魚(yú)欺詐(打開(kāi)新標(biāo)簽跳轉(zhuǎn),新標(biāo)簽存在惡意代碼,跳轉(zhuǎn)到偽造的頁(yè)面),網(wǎng)頁(yè)植入廣告等。XSS攻擊防御手段:禁止JavaScript讀取某些敏感cookie,限制輸入內(nèi)容和長(zhǎng)度控制,檢測(cè)是否有惡意代碼注入CSRF攻擊:誘導(dǎo)用戶進(jìn)入第三方,獲取到登錄憑證,冒充用戶對(duì)被攻擊的站點(diǎn)執(zhí)行操作,導(dǎo)致賬號(hào)被劫持防御CSRF攻擊:驗(yàn)證token(請(qǐng)求服務(wù)器時(shí),返回token,每個(gè)請(qǐng)求需要加上token),

5.瀏覽器緩存

瀏覽器每次發(fā)起請(qǐng)求,都會(huì)在瀏覽器緩存中查找請(qǐng)求結(jié)果和緩存標(biāo)識(shí),瀏覽器每次拿到的數(shù)據(jù)會(huì)將結(jié)果和標(biāo)識(shí)存入瀏覽器中強(qiáng)制緩存:當(dāng)瀏覽器向服務(wù)器發(fā)起請(qǐng)求時(shí),服務(wù)器會(huì)將緩存規(guī)則放入HTTP響應(yīng)報(bào)文的HTTP頭中和請(qǐng)求結(jié)果一起返回給瀏覽器,控制強(qiáng)制緩存的字段分別是Expires和Cache-Control,其中Cache-Control優(yōu)先級(jí)比Expires高。協(xié)商緩存:強(qiáng)制緩存失效后,瀏覽器攜帶緩存標(biāo)識(shí)向服務(wù)器發(fā)起請(qǐng)求,由服務(wù)器根據(jù)緩存標(biāo)識(shí)決定是否使用緩存的過(guò)程。(協(xié)商緩存生效,服務(wù)器返回304,資源未更新,協(xié)商緩存失效,服務(wù)器返回200,資源更新重新緩存)詳情可以看這篇文章徹底理解瀏覽器的緩存機(jī)制

框架1.什么是vue生命周期

每個(gè)vue實(shí)例在被創(chuàng)建之前都要經(jīng)過(guò)一系列初始化過(guò)程,這個(gè)過(guò)程就是vue生命周期。(開(kāi)始創(chuàng)建、初始化數(shù)據(jù)、編譯模板、掛載Dom→渲染、更新→渲染、卸載等一系列過(guò)程)beforeCreate: 完成實(shí)例初始化,this指向被創(chuàng)建的實(shí)例,data,computed,watch,mothods方法和數(shù)據(jù)都不可以訪問(wèn)created: 實(shí)例創(chuàng)建完成,data,computed,watch,methods可被訪問(wèn),未掛載dom,可對(duì)data進(jìn)行操作,操作dom需放到nextTick中beforeMount: 有了el,找到對(duì)應(yīng)的template編譯成render函數(shù)mounted: 完成掛載dom和渲染,可以對(duì)dom進(jìn)行操作,并獲取到dom節(jié)點(diǎn),可以發(fā)起后端請(qǐng)求拿到數(shù)據(jù)beforeUpdate: 數(shù)據(jù)更新之前訪問(wèn)現(xiàn)有dom,可以手動(dòng)移除已添加事件的監(jiān)聽(tīng)updated: 組件dom已完成更新,可執(zhí)行依賴(lài)的dom 操作,不要操作數(shù)據(jù)會(huì)陷入死循環(huán)activated: keep-alive緩存組件激活時(shí)調(diào)用deactivated keep-alive移除時(shí)調(diào)用beforeDestroy: 實(shí)例銷(xiāo)毀之前調(diào)用,可以銷(xiāo)毀定時(shí)器destroyed: 組件已經(jīng)被銷(xiāo)毀

2.第一次頁(yè)面加載會(huì)觸發(fā)哪幾個(gè)鉤子

會(huì)觸發(fā)beforeCreate, created, beforeMount, mounted

3.created和mounted的區(qū)別

created:在模板渲染成html前調(diào)用,即通常初始化某些屬性值,然后再渲染成視圖。mounted:在模板渲染成html后調(diào)用,通常是初始化頁(yè)面完成后,再對(duì)html的dom節(jié)點(diǎn)進(jìn)行一些需要的操作。

4.hash模式和history模式

在vue的路由配置中有mode選項(xiàng) 最直觀的區(qū)別就是在url中 hash 帶了一個(gè)很丑的 # 而history是沒(méi)有#的。hash 雖然出現(xiàn)在 URL 中,但不會(huì)被包括在 HTTP 請(qǐng)求中,對(duì)后端完全沒(méi)有影響,因此改變 hash 不會(huì)重新加載頁(yè)面。history利用了HTML5中新增的 pushState() 和 replaceState() 方法。這兩個(gè)方法應(yīng)用于瀏覽器的歷史記錄棧,在當(dāng)前已有的 back、forward、go 的基礎(chǔ)之上,它們提供了對(duì)歷史記錄進(jìn)行修改的功能。只是當(dāng)它們執(zhí)行修改時(shí),雖然改變了當(dāng)前的 URL,但瀏覽器不會(huì)立即向后端發(fā)送請(qǐng)求。history模式需要后臺(tái)配置支持

5.computed和watch區(qū)別

computed: 依賴(lài)的屬性值發(fā)生改變才會(huì)重新計(jì)算,得出最后的值watch: 當(dāng)依賴(lài)的data的數(shù)據(jù)變化,執(zhí)行回調(diào)(可以觀察數(shù)據(jù)的某些變化,來(lái)做一些事情)

6.vue中key的作用

key是給每一個(gè)vnode的唯一id,可以依靠key,更準(zhǔn)確, 更快的拿到oldVnode中對(duì)應(yīng)的vnode節(jié)點(diǎn)。

7.vue的兩個(gè)核心點(diǎn)

數(shù)據(jù)驅(qū)動(dòng):ViewModel,保證視圖的一致性組件系統(tǒng):組件化,封裝可復(fù)用的組件,頁(yè)面上每個(gè)獨(dú)立的區(qū)域都可以看成一個(gè)組件,組件可以自由組合成頁(yè)面

8.SPA首屏加載慢如何解決

使用路由懶加載使用SSR渲染優(yōu)化webpack打包體積圖片使用CDN加速

9.vue禁止彈窗后的屏幕滾動(dòng)

主要是是寫(xiě)一個(gè)點(diǎn)擊出現(xiàn)彈窗禁止屏幕滾動(dòng)的方法,關(guān)閉彈窗屏幕可以正常滾動(dòng)

methods : {
//禁止?jié)L動(dòng)
stop(){
var mo=function(e){e.preventDefault();};
document.body.style.overflow='hidden';
document.addEventListener("touchmove",mo,false);//禁止頁(yè)面滑動(dòng)
},
/取消滑動(dòng)限制/
move(){
var mo=function(e){e.preventDefault();};
document.body.style.overflow='';//出現(xiàn)滾動(dòng)條
document.removeEventListener("touchmove",mo,false);
}
}
10.Vuex中actions和mutations的區(qū)別

action主要處理的是異步的操作,mutation必須同步執(zhí)行,而action就不受這樣的限制,也就是說(shuō)action中我們既可以處理同步,也可以處理異步的操作action改變狀態(tài),最后是通過(guò)提交mutation

如果有錯(cuò)誤或者不嚴(yán)謹(jǐn)?shù)牡胤?,?qǐng)務(wù)必給予指正,十分感謝。


前端面試干貨:四月份前端面試題總指南(下篇)

推薦內(nèi)容