畢業(yè)設(shè)計軟件開發(fā)網(wǎng)站開發(fā)手機做網(wǎng)頁的軟件
摘要
馬上就要畢業(yè)啦,沒有參加2023年的秋招,準備在最近開始找全職或者實習工作,然后也馬上過年了,總結(jié)和理一下自己的知識要點,參加2024年的春招。
1. JS的執(zhí)行流程
- 瀏覽器的V8引擎收到到執(zhí)行的JS代碼
- V8結(jié)構(gòu)化這段代碼,生成AST(抽象語法樹),同時生成相關(guān)作用域
- 生成字節(jié)碼(介于AST和機器碼之間)
- 解釋器,按照順序執(zhí)行字節(jié)碼,并輸出執(zhí)行結(jié)果
JS代碼流程:先編譯后執(zhí)行
2. 基本數(shù)據(jù)類型
- undefined
- null
- Boolean
- String
- Number
- Symbol
- BigInt
- Object:只有他存在堆里面
3. 判斷數(shù)據(jù)類型的方式(TTIC)
- typeof:判斷基本數(shù)據(jù)類型,判斷null時,會返回
object
- Object.prototype.toString.call(xx):返回一個
[object 數(shù)據(jù)類型]
- instanceof:
A instanceof B
:判斷A和B是否有血緣關(guān)系,不僅僅根據(jù)父子關(guān)系。 - constructor
4. ES6的新特性
const
和let
- 解構(gòu)賦值
- 模板字符串
- 函數(shù)的擴展:默認值、rest參數(shù)、函頭函數(shù)
- 數(shù)組的拓展:Array.from()將類數(shù)組轉(zhuǎn)換為數(shù)組、find()、findIndex()、entries()、keys()、values(),includes()
- 對象擴展:屬性名可以用表達式、Object.assign()、Object.keys()、Object.values()、Object.entries()
- Symbol
- Set、Map
- Promise
- Iterator和for…of
- Generator 和 async await
箭頭函數(shù)和普通函數(shù)
- 語法更加簡潔清晰
- 箭頭函數(shù)沒有 prototype、所以箭頭函數(shù)沒有
this
- 箭頭函數(shù)不會創(chuàng)建自己的this,
會自動繼承最外層的this
call | apply | bind
無法改變箭頭指向- 箭頭函數(shù)不能作為構(gòu)造函數(shù)
- 箭頭函數(shù)不綁定arguments,用rest(…)取代,來訪問箭頭函數(shù)列表
- 箭頭函數(shù)不用用作Generator,不能使用yield關(guān)鍵字
5. Promise 和 async/await
Promise
Promise對象為了解決
回調(diào)地獄
而提出,不是新的語法功能,而是一種新的寫法,允許將回調(diào)函數(shù)嵌套,改成鏈式調(diào)用
流程:
- Promise 接受一個executor(),在new的時候立刻執(zhí)行
- executor()內(nèi)部的異步任務(wù)被放入
宏\微任務(wù)
,等待執(zhí)行 - then,收集\失敗回調(diào)
- executor的
異步任務(wù)被執(zhí)行
,觸發(fā)resolve\reject
,從失敗和成功隊列中取出依次執(zhí)行。
其實是設(shè)計模式中的一種觀察者模式
:
- 收集依賴 (then收集)
- 觸發(fā)通知 (觸發(fā)resolve)
- 取出依賴執(zhí)行 ( resolve執(zhí)行)
async await
是對Generator(生成器)的封裝,是個語法糖
*/yield
和async/await
的區(qū)別:
- async/await
自帶執(zhí)行器
,不需要next()
就能下一步 - async 返回的是Promise對象,而Generator返回的是
生成器對象
- await能夠返回
Promise
的 reject/resolve的值
注意:無論await后面跟的什么,后面的代碼都會被阻塞
和Promise區(qū)別
Promise解決了回調(diào)地獄,但是他的語法問題縱向發(fā)展形成了一個回調(diào)鏈,遇到復(fù)雜的業(yè)務(wù)場景,這樣的語法顯然是不美觀的。
async await看起來簡潔一些,看起來像同步代碼
,其實它出現(xiàn)的意義就是提供異步的效果
兩者其實都是非阻塞
的
6. Generator
核心: 保存上下文,函數(shù)在真正意義中沒有被掛起,每一次yield
,其實都執(zhí)行了一邊生成器函數(shù)、在這個過程中用了一個context
存儲上下文,每次執(zhí)行生成器函數(shù)的時候,都可以從上一個執(zhí)行結(jié)果開始執(zhí)行
。
用babel編譯后生成regeneratorRuntime
mark()
方法為生成器函數(shù)綁定了一系列原型wrap()
相當于給Generator
增加一個_invoke
方法
7. 迭代器
模式: 可以把有些結(jié)構(gòu)稱為可迭代對象,它們正式實現(xiàn)了Iterable
接口,可以通過迭代器消費,是按需創(chuàng)建的一次性對象
,每個迭代器都會關(guān)聯(lián)一個可迭代對象
協(xié)議: 可迭代協(xié)議需要具備兩種能力
- 支持迭代的
自我識別能力
- 創(chuàng)建實現(xiàn)
Iterator
接口的對象的能力
是一次性使用對象,用于迭代與其關(guān)聯(lián)的可迭代對象
迭代器api提供一個next()
方法,這個方法會返回兩個屬性:
- done:是否還能取得下個值
- value:可迭代對象下一個值
默認實現(xiàn)了Iterable的類型
- String
- Array
- Map
- Set
- arguments
- NodeList等Dom集合類型
接受可迭代對象的原生語言特性包括
- for of
- 數(shù)組結(jié)構(gòu)
- 擴展操作符
- Array.from()
- Set
- Map
- Promise.all()
- Promise.race()
- yield
8. 設(shè)計模式
三類:(C5S7B11)
- 創(chuàng)建型模式:五種: 工廠方法、抽象工廠、單例、建造則、原型
- **結(jié)構(gòu)型模式:七種:**適配器、裝飾器、代理、外觀、橋接、組合、享元
- **行為型模式:十一種:**策略、模板方法、觀察者(發(fā)布訂閱)、迭代子、責任鏈、命令、備忘錄、狀態(tài)、訪問者、中介者、模板方法、解釋器
9. WebGL
Canvas
是畫布一般可以獲取2D上下文
和3D上下文
,3D上下文
一般就是WebGL
,當然WebGL
也能用于2D繪制,并且WebGL
提供硬件渲染加速,性能更好。但是支持性不是特別好,在不支持的情況下最好還是用Canvas
,可以用一些兜底的庫,如threehs、PIXI
等
10. CommonJS和ES6 Module
首先,CommonJS
是同步加載
,ES6
是異步加載
,前者主要用于Node.js服務(wù)端編程
,模塊文件一般已經(jīng)存在于本地硬盤
,所以記載比較快。而后者是異步加載
所以適用于瀏覽器,不會造成堵塞。
其次,CommonJS
模塊輸出的是一個值的拷貝,也就是說一旦輸出一個值,模塊內(nèi)部變化就影響不到這個值
,ES6
模塊輸出的是值的引用,V8引擎在對JS進行靜態(tài)分析的時候,遇到import命令,會等到腳本真正執(zhí)行時,才回到被加載模塊中取值。
最后,前者是運行時加載
,后者是編譯時輸出接口
注意:CommonJS不適用于瀏覽器
11. 聲明變量的方式
ES5
- var
- function
ES6
- let
- const
- import
- class
12. 函數(shù)聲明
- function fn(…args) {}
- var fn = function(…args){}
- new Function(‘x’,‘y’,‘return x+y’)
13. Object/Map/WeakMap區(qū)別
Map
是ES6
提供的一種新特性,是一種鍵不局限于字符串的一種鍵值對集合
,對于Object
來說他的鍵只能使用字符串。
WeakMap
結(jié)構(gòu)和Map
有點類似,但是有兩點區(qū)別:
- 他只接受對象為鍵(null除外)
- 鍵名所指向的對象,不計入垃圾回收機制
總之,WeakMap
專用場合就是,它的鍵所對應(yīng)的對象,可能會在將來消失,WeakMap
結(jié)構(gòu)有助于防止內(nèi)存泄露。
14. JS深淺復(fù)制
淺復(fù)制
- 擴展運算符
- Object.assign()
- Object,getOwnPropertyDescriptors()+Object.defineProperties()
深復(fù)制
- 通過嵌套擴展運算符
- 使用JSON
- 手動實現(xiàn)(FHT)
- 利用
for-in
對對象的屬性進行遍歷(自身屬性+繼承屬性
) source.hasOwnProperty(i)
判斷是否非繼承
和可枚舉
類型typoeof source[i]==='object
判斷值的類型,如果是對象,遞歸處理
- 利用
15. 閉包
閉包
就是在JS種,根據(jù)語法作用域規(guī)則,內(nèi)部函數(shù)總是可以訪問到其外部函數(shù)中聲明的變量,當通過調(diào)用
一個外部函數(shù)返回
一個內(nèi)部函數(shù)后,即使該外部函數(shù)已經(jīng)執(zhí)行結(jié)束了。但是內(nèi)部函數(shù)引用外部函數(shù)的變量依然保存在內(nèi)存中,就把這些變量的集合成為閉包。
16. Event Loop
也就是事件循環(huán)
,會不聽從微/宏任務(wù)隊列中
取出對應(yīng)任務(wù)的循環(huán)函數(shù)。在某種情況中,你可以把它稱為一個永動機
。這些它取出的任務(wù)并將其推送到調(diào)用棧
種執(zhí)行,主要有四個主要步驟:
- 執(zhí)行Scirpt:用同步的方式執(zhí)行
script
,直到調(diào)用???/code>才停下來。(還會執(zhí)行預(yù)編譯操作。如:變量提升)
- 執(zhí)行一個宏任務(wù):挑選
最老
的到調(diào)用棧中執(zhí)行,直到調(diào)用棧為空
- 執(zhí)行所有微任務(wù):挑選
最老
的到調(diào)用棧中執(zhí)行,直到調(diào)用棧為空
。(但是,繼續(xù)從微任務(wù)隊列種獲取最老的執(zhí)行。重復(fù)) - UI渲染:然后跳到
第二步
,挑選宏任務(wù)執(zhí)行。
Event Loop 單次迭代過程被稱為tick。
宏任務(wù) (Task Queue)
也被稱為{回調(diào)隊列| Callback queue}
,調(diào)用棧適用于跟蹤
正在被執(zhí)行函數(shù),宏任務(wù)則是跟蹤
將要被執(zhí)行函數(shù)。
事件循環(huán)不停
的運行著,并且按照一定規(guī)則
從宏任務(wù)隊列中不停的去除對象。
宏任務(wù)是一個
FIFO
,存儲的宏任務(wù)會被事件循環(huán)探查
到。記得!這些人物都是阻塞
的。
微任務(wù)(Microtask Queue)
和宏任務(wù)一樣,他也是FIFO
,同樣會被探查
到。不同的地方是,微任務(wù)是在一個
宏任務(wù)完成后,在UI渲染之前被觸發(fā)。它是專門處理ES6
中Promise回調(diào)的。
17. GC
也就是垃圾回收機制
。
如何實現(xiàn)(算法)
- 通過
GC Root
標記空間中活動對象
和非活動對象
V8
采用可訪問性算法,來判斷對象是否為活動對象
- 是將一些
GC Root
作為初始存活
的對象的集合 - 從
GC Root
出發(fā)然后遍歷所有對象 - 通過遍歷所得到的對象,認為該對象是否為
活動對象
- 通過遍歷所得到的對象,認為該對象是否為
非活動對象
- 瀏覽器環(huán)境中,
GC Root
包括1.全局的window對象 2. 文檔DOM樹 3.存放棧上變量
- 回收
非活動對象
所占據(jù)的內(nèi)存 - 內(nèi)存整理
代際假說
是GC領(lǐng)域中的一個重要術(shù)語
兩個特點:
- 大部分對象都是朝生夕死的
- 不死的對象,會獲得很久
堆空間
V8會把堆
分為兩個部分
- 新生代
- 存放的是生存時間短的
- 1~8M容量
- 副垃圾回收器,負責新生代的垃圾回收
- 老生代
- 存放時間久的對象
- 主垃圾回收器,負責老生代的垃圾回收
副垃圾回收器
用Scavenge
算法來處理,九十八新生代區(qū)域分為兩個區(qū)域:對象區(qū)域
和空閑區(qū)域
。
當對象區(qū)域要被寫滿的時候,就做一次垃圾清理操作:
- 首先對對象區(qū)域的垃圾
做標記
- 然后把這些對象復(fù)制一份然后,有序的丟到空閑區(qū)域
- 然后復(fù)制結(jié)束后,兩者角色互換
副垃圾回收器采用對象晉升策略:移動那些經(jīng)過兩次垃圾回收依然還活著的對象到老生代中
主垃圾回收器
負責老生代的垃圾回收,除了新生代晉升的,大的對象也會直接被存到老生代
中,有兩個特點:
- 活得久
- 大得很
標記|清除 算法
- 標記過程:從根元素遍歷,能夠達到的為活動對象,沒有達到的為非活動對象
- 垃圾清理過程:主回收器直接把非活動對象清除
標記 - 整理
- 標記可回收
- 清除:不是對可回收對象清理,二十讓所有的活動對象向一端移動,清理掉除了這里以外的內(nèi)存。
18. 內(nèi)存問題
內(nèi)存泄漏: 不需要的內(nèi)存數(shù)據(jù)但是依然被其他對象引用著。
常見的: 函數(shù)中聲明變量時沒有用var、let、const
導(dǎo)致this指向window,直接賦值到window對象中。
19. 作用域
3大類:
- 聲明式:函數(shù)作用域、module作用域
- 對象
- 全局
聲明式作用域
通過var/const/let/class/module/import/function
生成,常說的ES6塊級作用域和函數(shù)作用域都屬于函數(shù)式作用域
全局作用域
全局對象使用兩個ER管理:
- 對象ER:將變量存儲在
全局對象
中,頂層作用域下,var
和function
聲明的變量被綁定在對象ER中(瀏覽器為window
) - 聲明式ER:使用內(nèi)部對象來存儲,頂層作用于下,
const/let/class
聲明的變量被綁定在聲明ER中
兩者存在相同名的變量時,聲明式ER
優(yōu)先級更高。
20. this
this
是和上下文綁定的,主要分為三種:全局執(zhí)行、函數(shù)執(zhí)行、eval執(zhí)行
全局
一般指向window
對象,這是this
和作用域鏈唯一焦點,作用域低端包含window
對象
函數(shù)
默認情況調(diào)用一個函數(shù),他的上下文也是指向window
通過call/bind/apply設(shè)置上下文:
let bar = {myName : " mango ",test1 : 1
}
function foo(){this.myName = " test "
}
foo.call(bar)
console.log(bar) // mango
console.log(myName) // not defined
this的設(shè)計缺陷
嵌套函數(shù)中,內(nèi)部函數(shù)的this
不會從外層函數(shù)中繼承
解決方法:
- 將this轉(zhuǎn)化為作用域體系。
- 使用
ES6
中的this函數(shù),他不會創(chuàng)建自己的上下文,所以取決于他的外部函數(shù)。
普通函數(shù)中的 this
默認指向全局對象 window
可以設(shè)置嚴格模式,函數(shù)上下文都是undefined
21. 圖片懶加載
通過HTML提供的data-
屬性來嵌入自定義數(shù)據(jù)。
然后利用offsetTop計算位置。當圖片出現(xiàn)在可視區(qū)域的時候,加載圖片,也就是給img標簽設(shè)置src
。
22. 數(shù)組常用方法
改變原數(shù)組
- push
- pop
- shift
- unshift
- reverse
- sort
- splice
不會改變
- concat
- join
- slice
- filter
- reduce
- find
- findIndex