let、const、var的使用區(qū)別
1.var定義變量,沒(méi)有塊的概念,可以跨塊訪問(wèn),不能跨函數(shù)訪問(wèn),不初始化出現(xiàn)undefined,不會(huì)報(bào)錯(cuò)。
2.let定義變量,只能在塊作用域里訪問(wèn),也不能跨函數(shù)訪問(wèn),對(duì)函數(shù)外部無(wú)影響。
3.const定義常量,只能在塊作用域里訪問(wèn),也不能跨函數(shù)訪問(wèn),使用時(shí)必須初始化(即必須賦值),而且不能修改。
變量提升和函數(shù)提升
- 變量聲明的提升是以變量所處的第一層詞法作用域?yàn)椤皢挝弧钡?,即全局作用域中聲明的變量?huì)提升至全局最頂層,函數(shù)內(nèi)聲明的變量只會(huì)提升至該函數(shù)作用域最頂層
- 函數(shù)提升只會(huì)提升函數(shù)聲明,而不會(huì)提升函數(shù)表達(dá)式
- 函數(shù)提升優(yōu)先于變量提升
Map與普通對(duì)象的區(qū)別
JavaScript 的對(duì)象(Object),本質(zhì)上是鍵值對(duì)的集合(Hash 結(jié)構(gòu)),但是傳統(tǒng)上只能用字符串當(dāng)作鍵。這給它的使用帶來(lái)了很大的限制。為了解決這個(gè)問(wèn)題,ES6 提供了 Map 數(shù)據(jù)結(jié)構(gòu)。它類似于對(duì)象,也是鍵值對(duì)的集合,但是“鍵”的范圍不限于字符串,各種類型的值(包括對(duì)象)都可以當(dāng)作鍵。也就是說(shuō),Object 結(jié)構(gòu)提供了“字符串—值”的對(duì)應(yīng),Map 結(jié)構(gòu)提供了“值—值”的對(duì)應(yīng),是一種更完善的 Hash 結(jié)構(gòu)實(shí)現(xiàn)。如果你需要“鍵值對(duì)”的數(shù)據(jù)結(jié)構(gòu),Map 比 Object 更合適。
外部函數(shù)調(diào)用之后其變量對(duì)象本應(yīng)該被銷毀,但閉包的存在使我們?nèi)匀豢梢栽L問(wèn)外部函數(shù)的變量對(duì)象
輸入一個(gè)網(wǎng)址,直到網(wǎng)址打開并加載結(jié)束,這個(gè)過(guò)程瀏覽器發(fā)生了什么
查看瀏覽器中是否有緩存,有的話直接訪問(wèn)緩存
如果緩存過(guò)期或者沒(méi)有緩存,重新請(qǐng)求
在發(fā)送http請(qǐng)求前,需要域名解析,獲取相應(yīng)的IP地址
瀏覽器想服務(wù)器發(fā)起tcp鏈接,與瀏覽器建立tcp三次握手
握手成功后,瀏覽器向服務(wù)器發(fā)送http請(qǐng)求,請(qǐng)求數(shù)據(jù)包
服務(wù)器處理收到的請(qǐng)求,將數(shù)據(jù)返回至瀏覽器
瀏覽器收到HTTP響應(yīng)
讀取頁(yè)面內(nèi)容,瀏覽器渲染,解析html源碼
rem是根據(jù)根的font-size變化,而em是根據(jù)父級(jí)的font-size變化
基本數(shù)據(jù)類型:number,string,null,undefined,boolean,symbol,bigInt
引用數(shù)據(jù)類型: object
call,apply,bind的作用區(qū)別
作用:用來(lái)改變函數(shù)this指向
相同處:第一個(gè)參數(shù)都是this要指向的對(duì)象
區(qū)別一:call()和apply()都是對(duì)函數(shù)的直接地調(diào)用,而bind()本身返回一個(gè)函數(shù),后面還需要()進(jìn)行調(diào)用
區(qū)別二:call()和bind()傳參可以一個(gè)一個(gè)傳入,但是apply()要以數(shù)組格式傳參
bind 函數(shù)
Function.prototype.bind = function() {
var self = this;
var context = Array.prototype.shift.call(arguments)
var args = Array.prorotype.slice.call(arguments)
return function() {
self.apply(context, Array.prototype.concat.call(args, Array.prorotype.slice.call(arguments)))
}
}
js調(diào)用機(jī)制
- JavaScript的單線程
- 任務(wù)隊(duì)列
- 同步任務(wù)
- 異步任務(wù)
(1)所有同步任務(wù)都在主線程上執(zhí)行,形成一個(gè)執(zhí)行棧(execution context stack)。
(2)主線程之外,還存在一個(gè)"任務(wù)隊(duì)列"(task queue)。只要異步任務(wù)有了運(yùn)行結(jié)果,就在"任務(wù)隊(duì)列"之中放置一個(gè)事件。
(3)一旦"執(zhí)行棧"中的所有同步任務(wù)執(zhí)行完畢,系統(tǒng)就會(huì)讀取"任務(wù)隊(duì)列",看看里面有哪些事件。那些對(duì)應(yīng)的異步任務(wù),于是結(jié)束等待狀態(tài),進(jìn)入執(zhí)行棧,開始執(zhí)行。
(4)主線程不斷重復(fù)上面的第三步。
具體運(yùn)行機(jī)制可以理解為,當(dāng)主線程的異步函數(shù)在被調(diào)用的時(shí)候,會(huì)請(qǐng)求工作線程的幫助。工作線程接收這個(gè)任務(wù)并執(zhí)行。主線程可以繼續(xù)運(yùn)行后面的函數(shù),而不必阻塞在這。
瀏覽器線程
- 主進(jìn)程
- gpu進(jìn)程
- 第三方插件進(jìn)程
- 渲染進(jìn)程
- gui線程
如果修改了一些元素的顏色或者背景色,頁(yè)面就會(huì)重繪(Repaint),如果修改元素的尺寸,頁(yè)面就會(huì)回流(Reflow),當(dāng)頁(yè)面需要Repaing和Reflow時(shí)GUI多會(huì)執(zhí)行,進(jìn)行頁(yè)面繪制。 - js引擎線程:
js引擎線程就是js內(nèi)核,負(fù)責(zé)解析與執(zhí)行js代碼,也稱為主線程。瀏覽器同時(shí)只能有一個(gè)JS引擎線程在運(yùn)行JS程序,所以js是單線程運(yùn)行的。 - 事件循環(huán)線程
管理著一個(gè)事件隊(duì)列(task queue),當(dāng)js執(zhí)行碰到事件綁定和一些異步操作時(shí),會(huì)把對(duì)應(yīng)的事件添加到對(duì)應(yīng)的線程中(比如定時(shí)器操作,便把定時(shí)器事件添加到定時(shí)器線程),等異步事件有了結(jié)果,便把他們的回調(diào)操作添加到事件隊(duì)列,等待js引擎線程空閑時(shí)來(lái)處理。 - 定時(shí)器線程
由于js是單線程運(yùn)行,所以不能抽出時(shí)間來(lái)計(jì)時(shí),只能另開辟一個(gè)線程來(lái)處理定時(shí)器任務(wù),等計(jì)時(shí)完成,把定時(shí)器要執(zhí)行的操作添加到事件任務(wù)隊(duì)列尾,等待js引擎線程來(lái)處理。這個(gè)線程就是定時(shí)器線程。 - 異步請(qǐng)求線程
當(dāng)執(zhí)行到一個(gè)http異步請(qǐng)求時(shí),便把異步請(qǐng)求事件添加到異步請(qǐng)求線程,等收到響應(yīng)(準(zhǔn)確來(lái)說(shuō)應(yīng)該是http狀態(tài)變化),把回調(diào)函數(shù)添加到事件隊(duì)列,等待js引擎線程來(lái)執(zhí)行
- gui線程
BFC(Block formatting context)直譯為"塊級(jí)格式化上下文"
內(nèi)部的Box會(huì)在垂直方向,一個(gè)接一個(gè)地放置。
Box垂直方向的距離由margin決定。屬于同一個(gè)BFC的兩個(gè)相鄰Box的margin會(huì)發(fā)生重疊。
每個(gè)盒子(塊盒與行盒)的margin box的左邊,與包含塊border box的左邊相接觸(對(duì)于從左往右的格式化,否則相反)。即使存在浮動(dòng)也是如此。
BFC的區(qū)域不會(huì)與float box重疊。
BFC就是頁(yè)面上的一個(gè)隔離的獨(dú)立容器,容器里面的子元素不會(huì)影響到外面的元素。反之也如此。
計(jì)算BFC的高度時(shí),浮動(dòng)元素也參與計(jì)算。
如何創(chuàng)建BFC
1、float的值不是none。
2、position的值不是static或者relative。
3、display的值是inline-block、table-cell、flex、table-caption或者inline-flex
4、overflow的值不是visible
BFC就是頁(yè)面上的一個(gè)隔離的獨(dú)立容器,容器里面的子元素不會(huì)影響到外面的元素
箭頭函數(shù)
箭頭函數(shù)相當(dāng)于匿名函數(shù), 不綁定this、沒(méi)有prototype屬性、不綁定arguments
this 是指向詞法作用域,由上下文確定
Array
# 改變?cè)瓟?shù)組的方法
pop, push, shift. unshift, sort, reverse, splice
# 不改變?cè)瓟?shù)組的方法
concat, valueOf, join, slice,lastIndexOf, toLocaleString // 返回新數(shù)組
詞法作用域和動(dòng)態(tài)作用域
- 詞法作用域(靜態(tài)作用域)是在
書寫代碼或者說(shuō)定義時(shí)確定的,而動(dòng)態(tài)作用域是在運(yùn)行時(shí)確定的。
詞法作用域關(guān)注函數(shù)在何處聲明,而動(dòng)態(tài)作用域關(guān)注函數(shù)從何處調(diào)用,其作用域鏈?zhǔn)腔谶\(yùn)行時(shí)的調(diào)用棧的。
// 詞法作用域
function foo() {
console.log(a) //2
}
function bar() {
var a = 3
foo()
}
var a = 2
bar()
// 動(dòng)態(tài)作用域
function foo() {
console.log(a) //3
}
function bar() {
var a = 3
foo()
}
var a = 2
bar()