1怎披、原型、原型鏈
原型:js中一切皆對(duì)象瓶摆,對(duì)象都有一個(gè)隱式的屬性_proto_,它指向該對(duì)象的原型-prototype(原型對(duì)象)
原型鏈:我們調(diào)用對(duì)象的某個(gè)屬性凉逛,如果該對(duì)象上沒有該屬性,則會(huì)向上在該對(duì)象的原型對(duì)象上找群井,有則返回状飞,如果沒有的話繼續(xù)向原型的原型上找,直到Object的原型书斜,Object的prototype為null诬辈,如果沒有找到該屬性則返回undefind。我們把整個(gè)訪問(wèn)的過(guò)程稱為原型鏈
tips: 通過(guò)Object.create(null) 創(chuàng)建的對(duì)象沒有原型對(duì)象
varA=function(){}
A.prototype.n=1
var b=new A()
A.prototype={n:2,m:3}
varc=newA()
console.log(b.n,b.m,c.n,c.m)? ?//1 undefind 2 3
varF=function(){};
Object.prototype.a=function(){
????console.log('a()')
};
Function.prototype.b=function(){
????console.log('b()')
}
var f=newF();
f.a()//荐吉? a()f.b()//焙糟? errF.a()//? a()F.b()//样屠? b()
2酬荞、閉包、閉包的優(yōu)缺點(diǎn)瞧哟、閉包的應(yīng)用場(chǎng)景
閉包:js的作用域中內(nèi)部函數(shù)可以訪問(wèn)外部函數(shù)的變量混巧,反之則不行,但是我們?yōu)槟軌蜻_(dá)到這一目的勤揩,就使用內(nèi)部函數(shù)應(yīng)用外部函數(shù)的變量咧党,把該內(nèi)部函數(shù)通過(guò)外部函數(shù)return到外部去執(zhí)行,就形成了閉包陨亡。
缺點(diǎn):長(zhǎng)期占用內(nèi)存傍衡、容易造成內(nèi)存泄漏
優(yōu)點(diǎn):私有話屬性或變量深员、避免外部環(huán)境污染
應(yīng)用場(chǎng)景:
A、防抖(清除舊定時(shí)器蛙埂,開始新的定時(shí)器)倦畅、節(jié)流(上一個(gè)定時(shí)器沒有結(jié)束,則return 不執(zhí)行新的定時(shí)器)
B绣的、函數(shù)柯里化
C叠赐、<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
給li循環(huán)綁定點(diǎn)擊事件,彈出 i
3屡江、字符串的常用方法
indexOf() ?查找某字符串對(duì)應(yīng)的下標(biāo)芭概,如果找不到返回-1
split(sep) ?將字符串按照指定的字符切割成數(shù)組元素,sep表示指定的字符
slice(start,end) ?截取字符串惩嘉,start開始的下標(biāo)罢洲,end結(jié)束的下標(biāo),不包含end本身文黎;如果end為空截取到最后惹苗,如果為負(fù)數(shù)表示倒數(shù)。
substr(start,count) ?截取字符串耸峭,start開始的下標(biāo)鸽粉,count截取的長(zhǎng)度,如果count為空截取到最后抓艳,如果start為負(fù)值表示倒數(shù)
substring(start,end) ?截取字符串触机,start開始的下標(biāo),end結(jié)束的下標(biāo)玷或,不包含end本身儡首,如果end為空截取到最后;如果下標(biāo)為負(fù)數(shù)偏友,自動(dòng)轉(zhuǎn)為0
4蔬胯、Set、Map位他、和Array的異同氛濒、用法
Set:創(chuàng)建類似數(shù)組的數(shù)據(jù)結(jié)構(gòu),但成員是唯一(基本數(shù)據(jù)類型無(wú)重復(fù)鹅髓,應(yīng)用數(shù)據(jù)類型可以重復(fù))
常用方法:size()舞竿、add()、delete()窿冯、clear()骗奖、has()可以使用該方法求交集/差集、keys()、values()执桌、entries()鄙皇、forEach()
Map:以鍵值對(duì)的行書存儲(chǔ)數(shù)據(jù),key可以是任何數(shù)據(jù)類型
常用方法:size()仰挣、set(key伴逸,value)、get(key)膘壶、delete()错蝴、clear()、has()香椎、keys()、values()禽篱、entries()畜伐、forEach()
Set/Map轉(zhuǎn)Array:
Array.from(set)
const arr = [ ...set ]
const arr = [ ...map.values ]
5、類數(shù)組轉(zhuǎn)成數(shù)組的方法
const arr = Array.from(args)
const arr = Array.prototype.slice.call(args)或者[].splice.call(args)
const arr = [ ...args ]
6躺率、宏任務(wù)微任務(wù)
js是單線程玛界,但是它有個(gè)事件隊(duì)列機(jī)制來(lái)處理異步操作,事件隊(duì)列中有包含宏任務(wù)和微任務(wù)悼吱。像常用的setTimeout慎框,setInterval就是宏任務(wù),Promise()的.then(()=>{})/.catch(()=>{})/.finally(()=>{}) 回調(diào)都是微任務(wù)后添。js先執(zhí)行主線程任務(wù)笨枯,然后看如果有可以執(zhí)行的微任務(wù)就會(huì)被執(zhí)行,再看如果有宏任務(wù)就被執(zhí)行遇西,執(zhí)行完繼續(xù)主線程任務(wù)-然后就一遍一遍這循環(huán)執(zhí)行馅精,這也就是它的事件循環(huán)機(jī)制
7、深拷貝粱檀、淺拷貝
js的數(shù)據(jù)類型分為基本數(shù)據(jù)類型(Number/String/Boolean/Null/undefind)和引用數(shù)據(jù)類型Object(包含F(xiàn)unction
/Array/Date/Regex)洲敢。淺拷貝對(duì)基本數(shù)據(jù)類型來(lái)說(shuō)拷貝的是值,但對(duì)引用數(shù)據(jù)類型來(lái)說(shuō)拷貝的只是引用茄蚯, 深拷貝針對(duì)的是引用數(shù)據(jù)類型压彭,拷貝的是值。
我們常用的拷貝方法有:
1渗常、Object.assgin()? 僅第一層是深拷貝
2壮不、ES6的擴(kuò)展運(yùn)算符(...)僅第一層是深拷貝
3、JSON.parse( JSON.stringify(target) )? 會(huì)丟失函數(shù)皱碘、會(huì)把時(shí)間對(duì)象變成字符串忆畅、會(huì)把正則對(duì)象變成空對(duì)象
4、利用遞歸手寫深拷貝方法
function deepClone1(obj) {
? var objClone = Array.isArray(obj) ? [] : {};
? if (obj && typeof obj === "object") {
? ? for (key in obj) {
? ? ? if (obj.hasOwnProperty(key)) {
? ? ? ? if (obj[key] && typeof obj[key] === "object") {
? ? ? ? ? objClone[key] = deepClone1(obj[key]);
? ? ? ? } else {
? ? ? ? ? objClone[key] = obj[key];
? ? ? ? }
? ? ? }
? ? }
? }
? return objClone;
}
8、數(shù)組去重
1家凯、利用對(duì)象訪問(wèn)屬性的方法缓醋,判斷對(duì)象中是否存在key
2、利用reduce方法遍歷數(shù)組绊诲,reduce第一個(gè)參數(shù)是遍歷需要執(zhí)行的函數(shù)送粱,第二個(gè)參數(shù)是item的初始值
varobj={};
vararr=arr.reduce(function(item,next) {
obj[next.key]?'':obj[next.key]=true&&item.push(next);
returnitem;
?}, []);
3、利用new Set() 去重掂之,去重之后可以通過(guò)Array.from(set)或者 [...set] 把set轉(zhuǎn)回?cái)?shù)組
9抗俄、cookie sessionstorage localstorage 的異同
相同點(diǎn):都可以存儲(chǔ)數(shù)據(jù)
不同點(diǎn):
存儲(chǔ)大小:cookie 4KB
? ? sessionstorage和localstorage 5MB
生命周期:
cookie 可以手動(dòng)設(shè)置過(guò)期時(shí)間
sessionstorage 當(dāng)前會(huì)話世舰,關(guān)閉窗口或?yàn)g覽器就被刪除
localstorage 永久保存 除非手動(dòng)刪除
使用api:
cookie 操作的是字符串 比較麻煩需要手動(dòng)封裝方法
sessionstorage和localstorang的話有自己的getItem()和setItem()动雹、clear()方法,使用起來(lái)比較方便
10跟压、跨域
因?yàn)闉g覽器存在同源策略胰蝠,協(xié)議+域名+端口 必須完全一致不然就會(huì)受到瀏覽器同源策略限制造成跨域。
跨域有如下常用方法:
1震蒋、proxy
2茸塞、jsonp 原理是利用<script src="https://xxx/a.html?callback=fnName"></script>不是同源策略限制
3、跨域資源貢獻(xiàn)(CORS)服務(wù)端設(shè)置Access-Control-Allow-Origin即可
4查剖、window.name + iframe 原理是window.name保存的字符串?dāng)?shù)據(jù)可以跨不同頁(yè)面和不同的域
5钾虐、h5的postMessage() + window.onmessage() 再不同頁(yè)面(或iframe)之間發(fā)送消息和接受消息
6、nginx代理 原理是因?yàn)榭缬蚴谴嬖谂c瀏覽器端笋庄,所以通過(guò)反向代理通過(guò)服務(wù)端獲取數(shù)據(jù)
11效扫、apply()、call()直砂、bind() 之間的異同
相同點(diǎn):三個(gè)都是改變this指向的荡短。
區(qū) ? 別:call()和apply()第一個(gè)參數(shù)是指定的對(duì)象,call()之后的參數(shù)是傳入該函數(shù)的值
apply()第二個(gè)參數(shù)是數(shù)組哆键,數(shù)組中是函數(shù)執(zhí)行需要的參數(shù)
bind()和call()的參數(shù)相同掘托,不同的是bind()改變this的指向后不會(huì)立即執(zhí)行,其他兩個(gè)是立即執(zhí)行的
tips ? :使用bind()的時(shí)候最好不要直接綁定在Dom上籍嘹,避免當(dāng)Dom變化時(shí)需要重新綁定
12闪盔、防抖、節(jié)流函數(shù)
防抖:代碼實(shí)現(xiàn)重在清零clearTimeout
functiondebounce(f,wait) {
lettimer
return(...args)=>{
clearTimeout(timer)
timer=setTimeout(()=>{
f(...args)
},wait)
?}
}
節(jié)流:代碼實(shí)現(xiàn)重在開鎖關(guān)鎖timer=timeout; timer=null
functionthrottle(f,wait) {
lettimer
return(...args)=>{
if(timer) {return}
timer=setTimeout(()=>{
f(...args)
timer=null
},wait)
?}
}
13辱士、數(shù)組降維
Array.prototype.concat.apply([],targetArr);
14泪掀、判斷數(shù)據(jù)類型
function toType(obj) {
? return ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase()
}
15、箭頭函數(shù)和普通function的區(qū)別
1颂碘、寫法不同
2异赫、this指向不同
function中的this執(zhí)行環(huán)境的不同而不同
箭頭函數(shù)的this是它自己執(zhí)行環(huán)境最近非箭頭函數(shù)的this
3、function可以被new 實(shí)例化,箭頭函數(shù)不可以
4塔拳、function可以被聲明提前鼠证,箭頭函數(shù)不可以,必須先聲明后使用不然會(huì)報(bào)錯(cuò)
16靠抑、數(shù)組的常用方法
改變?cè)瓟?shù)組的:push()量九、pop()、unshift()颂碧、shift()荠列、splice() 、sort()载城、reverse()
不改變?cè)瓟?shù)組:join()肌似、slice()、map()诉瓦、filter()川队、forEach()、some()垦搬、every()呼寸、find()艳汽、reduce()
17猴贰、new 操作符具體做了什么
1、創(chuàng)建了一個(gè)空對(duì)象 let obj = {}
2河狐、繼承了該函數(shù)的原型 obj._ protp_= Fn.prototype
3米绕、改變了該函數(shù)的this指向 let result = Fn.call(obj,...args)
4、判斷該函數(shù)的返回值馋艺,如果該返回值是基本數(shù)據(jù)類型則 return obj ,否則 return result
18栅干、Promise
它用于異步操作,它是一個(gè)構(gòu)造函數(shù)捐祠,接收一個(gè)回調(diào)函數(shù)碱鳞,用于異步計(jì)算,可以將異步操作隊(duì)列化踱蛀,按照期望的順序執(zhí)行窿给,返回符合預(yù)期的結(jié)果而且可以在對(duì)象之間傳遞和操作promise,幫助我們處理隊(duì)列率拒。
有三個(gè)狀態(tài):
1崩泡、pending[待定]初始狀態(tài)
2、fulfilled[實(shí)現(xiàn)]操作成功
3猬膨、rejected[被否決]操作失敗
常用方法:
1角撞、then()、catch()、finally()
2谒所、all([])接收一個(gè)數(shù)組热康,當(dāng)所有的異步請(qǐng)求完成之后才完成,一旦有某個(gè)異步請(qǐng)求報(bào)錯(cuò)百炬,則直接catch
3褐隆、race([])也接收一個(gè)數(shù)組,但它是搶占執(zhí)行剖踊,一旦有一個(gè)異步請(qǐng)求完成就算完成了
19庶弃、函數(shù)柯里化
概念:把一個(gè)接收多個(gè)參數(shù)的函數(shù)變成接收單一參數(shù)?并且返回能夠接收新參數(shù)的函數(shù)?
add(1)(2)(3)(4)=10;
function add(num){
? ? var sum=num;
? ? var fn=function(v){
? ? ? ? sum+=v;
? ? ? ? return fn
? ? };
? ? fn.toString=function(){
? ? ? ? return sum
? ? };
? ? return fn
}
console.log(add(1)(2)(3)(4)) // 10
20、斐波那契數(shù)列
eg:1德澈、1歇攻、2、3梆造、5缴守、8、13...
function fibonacci(n) {
if(n == 1 || n == 2) {
return1
? ? };
returnfibonacci(n - 2) + fibonacci(n - 1);
}
fibonacci(30)
21镇辉、緩存策略
1屡穗、強(qiáng)緩存:
強(qiáng)緩存兩個(gè)相關(guān)字段:【Expires】-過(guò)期時(shí)間,【Cache-Control】-過(guò)期時(shí)長(zhǎng)忽肛。
強(qiáng)緩存分為兩種情況村砂,一種是發(fā)送HTTP請(qǐng)求,一種不需要發(fā)送屹逛。
首先檢查強(qiáng)緩存础废,這個(gè)階段不需要發(fā)送HTTP請(qǐng)求,通過(guò)查找不同的字段來(lái)進(jìn)行罕模,不同的HTTP版本不同
http1.0版本评腺,使用的是expires,http1.1使用的是cache-control
expires即過(guò)期時(shí)間淑掌,時(shí)間是相對(duì)于服務(wù)器的時(shí)間而言的蒿讥,存在于服務(wù)端返回的響應(yīng)頭中,在這個(gè)過(guò)期時(shí)間之·? ??? ??前可以直接從緩存里面獲取數(shù)據(jù)抛腕,無(wú)需再次請(qǐng)求芋绸。
cache-control,http1.1版本中兽埃,使用的是這字段侥钳,這個(gè)字段采用的時(shí)間是過(guò)期時(shí)長(zhǎng),對(duì)應(yīng)的是max-age
注意點(diǎn):當(dāng)expires和cache-control同時(shí)存在時(shí)柄错,優(yōu)先考慮cache-control舷夺。
當(dāng)緩存資源失效了苦酱,也就是沒有命中強(qiáng)緩存,接下來(lái)就進(jìn)入?yún)f(xié)商緩存
2给猾、協(xié)商緩存
強(qiáng)緩存失效后疫萤,瀏覽器在請(qǐng)求頭中攜帶響應(yīng)的緩存etag來(lái)向服務(wù)器發(fā)送請(qǐng)求,服務(wù)器根據(jù)對(duì)應(yīng)的tag敢伸,來(lái)決定是否使用緩存扯饶。
分為兩種,【last-modified】和【etag】池颈。兩者個(gè)有優(yōu)勢(shì)
last-modified:這個(gè)字段表示的是【最后修改時(shí)間】尾序,在瀏覽器第一次個(gè)服務(wù)器發(fā)送請(qǐng)求后,服務(wù)器會(huì)在響應(yīng)頭中加上這個(gè)字段躯砰。瀏覽器接收到后每币,【如果再次請(qǐng)求】,會(huì)在請(qǐng)求頭中攜帶 if-modified-since 這個(gè)字段琢歇,這個(gè)字段的值也就是服務(wù)器傳來(lái)的最后修改時(shí)間兰怠。服務(wù)器拿到請(qǐng)求頭中的 if-modified-since 的字段后,其實(shí)會(huì)和這個(gè)服務(wù)器中 該資源的最后修改時(shí)間 做對(duì)比:
如果請(qǐng)求頭中的這個(gè)值小于最后修改時(shí)間李茫,說(shuō)明要更新了揭保,返回新的資源,跟常規(guī)的http請(qǐng)求響應(yīng)的流程一樣魄宏,否則返回304秸侣,告訴瀏覽器直接使用緩存。
etag:etag是服務(wù)器根據(jù)當(dāng)前文件的內(nèi)容娜庇,對(duì)文件生成唯一的標(biāo)識(shí)塔次,比如md5算法方篮,只要里面的內(nèi)容有改動(dòng)名秀,這個(gè)值就會(huì)修改,服務(wù)器通過(guò)響應(yīng)頭把這個(gè)字段給瀏覽器藕溅。瀏覽器接收到etag值匕得,會(huì)在下次請(qǐng)求的時(shí)候,將這個(gè)值作為【if-none-match】這個(gè)字段的內(nèi)容巾表,發(fā)送給服務(wù)器汁掠。服務(wù)器接收到這個(gè)【if-none-match】字段后,會(huì)跟服務(wù)器上該資源的【etag】進(jìn)行比較集币。
如果兩者一樣的話考阱,直接返回304,告訴瀏覽器直接使用緩存鞠苟,如果不一樣的話乞榨,說(shuō)明內(nèi)容更新了秽之,返回新的資源,跟常規(guī)的http請(qǐng)求響應(yīng)的流程一樣吃既。
22考榨、301、302鹦倚、303河质、304狀態(tài)碼有什么區(qū)別
301表示永久重定向辕坝,請(qǐng)求的資源分配了新的url
302表示臨時(shí)重定向再膳,請(qǐng)求的資源分配了新的url,本次暫且使用新的url,下次請(qǐng)求可能會(huì)改變
303表示請(qǐng)求的資源路徑發(fā)生改變退腥,使用GET方法請(qǐng)求新url虐杯。她與302的功能一樣碎紊,但是明確指出使用GET方法請(qǐng)求新url甫恩。
304表示請(qǐng)求的資源未更新鸣个。該狀態(tài)碼不應(yīng)該認(rèn)為是一種錯(cuò)誤帅矗,而是對(duì)客戶端有緩存情況下服務(wù)端的一種響應(yīng)匣砖。
tips:新url指的是科吭,第一次請(qǐng)求返回的location
23、深度優(yōu)先猴鲫、廣度優(yōu)先
? 深度優(yōu)先遍歷:對(duì)每一個(gè)可能的分支路徑深入到不能再深入為止对人,而且每個(gè)結(jié)點(diǎn)只能訪問(wèn)一次。遞歸
? 要特別注意的是拂共,二叉樹的深度優(yōu)先遍歷比較特殊牺弄,可以細(xì)分為先序遍歷、中序遍歷宜狐、后序遍歷(我們前面使用的是先序遍歷)势告。具體說(shuō)明如下:
? ?先序遍歷:對(duì)任一子樹,先訪問(wèn)根抚恒,然后遍歷其左子樹咱台,最后遍歷其右子樹。
? ?中序遍歷:對(duì)任一子樹俭驮,先遍歷其左子樹回溺,然后訪問(wèn)根,最后遍歷其右子樹混萝。
? ?后序遍歷:對(duì)任一子樹遗遵,先遍歷其左子樹,然后遍歷其右子樹逸嘀,最后訪問(wèn)根车要。
? ?廣度優(yōu)先遍歷:又叫層次遍歷,從上往下對(duì)每一層依次訪問(wèn)崭倘,在每一層中翼岁,從左往右(也可以從右往左)訪問(wèn)結(jié)點(diǎn)维哈,訪問(wèn)完一層就進(jìn)入下一層,直到?jīng)]有結(jié)點(diǎn)可以訪問(wèn)為止 ?遍歷
24登澜、介紹一下webpack
webpack是模塊打包機(jī)(自動(dòng)化構(gòu)建工具)阔挠,我們常用webpack構(gòu)建我們的項(xiàng)目框架。在webpack中脑蠕,包含entry购撼,output,mode谴仙,module迂求,plugin,module中我們一般會(huì)引入各種loader幫助我們翻譯編譯代碼晃跺,(loader是從右往左執(zhí)行)plugin會(huì)引入各種插件揩局,優(yōu)化構(gòu)建出來(lái)的代碼,mode是模式掀虎,一般分為development和production凌盯。entry是入口,output是出口烹玉。