簡(jiǎn)答題:
settimeout 與 setInterval的區(qū)別, 及對(duì)他們的內(nèi)存的分析
區(qū)別
- setTimeout是在一段時(shí)間后調(diào)用指定函數(shù)(僅一次)
- setInterval是每隔一段時(shí)間調(diào)用指定函數(shù)(N次)
function run(){
// 其他代碼
setTimeout(function(){
run();
}, 10000);
}
run();
以上面的代碼來說, 雖然設(shè)置的是10s執(zhí)行一次, 但是實(shí)際時(shí)間卻是需要// 其他代碼的執(zhí)行時(shí)間來確定
即setTimeout的間隔時(shí)間是, // setTimeout 的間隔時(shí)間 === 最小時(shí)間是(10s+)
setInterval(function(){
run();
}, 10000);
而setInterval, 不會(huì)有上面的問題, 但是如果run()的執(zhí)行時(shí)間, 操作大于10s, 那么甚至可能跳過任務(wù);
setInterval 和 setTimeout 會(huì)產(chǎn)生內(nèi)存溢出
JavaScript setInterval()方法是否導(dǎo)致內(nèi)存泄漏昼浦?
關(guān)于內(nèi)存泄漏
內(nèi)存
程序的運(yùn)行需要內(nèi)存。只要程序提出要求雷滚,操作系統(tǒng)或者運(yùn)行時(shí)(runtime)就必須供給內(nèi)存均牢。
對(duì)于持續(xù)運(yùn)行的服務(wù)進(jìn)程(daemon),必須及時(shí)釋放不再用到的內(nèi)存辣恋。否則惫撰,內(nèi)存占用越來越高羔沙,輕則影響系統(tǒng)性能,重則導(dǎo)致進(jìn)程崩潰厨钻。
不再用到的內(nèi)存扼雏,沒有及時(shí)釋放坚嗜,就叫做內(nèi)存泄漏(memory leak)。
(比如 C 語(yǔ)言)必須手動(dòng)釋放內(nèi)存诗充,程序員負(fù)責(zé)內(nèi)存管理苍蔬。
char * buffer;
buffer = (char*) malloc(42);
//...
free(buffer) //手動(dòng)釋放內(nèi)存
上面是 C 語(yǔ)言代碼,malloc方法用來申請(qǐng)內(nèi)存蝴蜓,使用完畢之后碟绑,必須自己用free方法釋放內(nèi)存。
這很麻煩励翼,所以大多數(shù)語(yǔ)言提供自動(dòng)內(nèi)存管理,減輕程序員的負(fù)擔(dān)辜荠,這被稱為"垃圾回收機(jī)制"(garbage collector)汽抚。
垃圾回收機(jī)制
怎么知道哪些內(nèi)存不再需要呢?常用的方法是 '引用計(jì)數(shù)', 語(yǔ)言的引擎有一張 '引用表', 保存了內(nèi)存里面所有的資源(通常是各種值)的引用次數(shù)伯病,當(dāng)一個(gè)值的引用次數(shù)為 0 時(shí)造烁,表示這個(gè)值用不到了,因此可將其釋放午笛。
但是如果一個(gè)值不再用到了惭蟋,引用次數(shù)卻不為 0 ,垃圾回收機(jī)制卻無法釋放這塊內(nèi)存药磺,從而導(dǎo)致內(nèi)存泄漏告组。
const arr = [1, 2, 3, 4];
console.log(arr);
打印完 arr 之后, arr 便用不到了,引用次數(shù)為 1, 但是它還會(huì)繼續(xù)占用內(nèi)存癌佩。
const arr = [1, 2, 3, 4];
console.log(arr);
arr = null;
arr 重置為 null木缝,就解除了對(duì) [1, 2, 3, 4] 的引用,引用次數(shù)變成了 0 围辙,內(nèi)存就可以釋放了我碟。
JavaScript 內(nèi)存管理
JavaScript 是一種垃圾回收語(yǔ)言。垃圾回收語(yǔ)言通過周期性地檢查先前分配的內(nèi)存是否可達(dá)姚建,幫助開發(fā)者管理內(nèi)存矫俺。換言之,垃圾回收語(yǔ)言減輕了“內(nèi)存仍可用”及“內(nèi)存仍可達(dá)”的問題掸冤。兩者的區(qū)別是微妙而重要的:僅有開發(fā)者了解哪些內(nèi)存在將來仍會(huì)使用厘托,而不可達(dá)內(nèi)存通過算法確定和標(biāo)記,適時(shí)被操作系統(tǒng)回收稿湿。
JavaScript 內(nèi)存泄漏
垃圾回收語(yǔ)言的內(nèi)存泄漏主因是不需要的引用催烘。理解它之前,還需了解垃圾回收語(yǔ)言如何辨別內(nèi)存的可達(dá)與不可達(dá)缎罢。
Mark-and-sweep
- 大部分垃圾回收語(yǔ)言用的算法稱之為 Mark-and-sweep 伊群。算法由以下幾步組成:
垃圾回收器創(chuàng)建了一個(gè)“roots”列表考杉。Roots 通常是代碼中全局變量的引用。JavaScript 中舰始,“window” 對(duì)象是一個(gè)全局變量崇棠,被當(dāng)作 root 。window 對(duì)象總是存在丸卷,因此垃圾回收器可以檢查它和它的所有子對(duì)象是否存在(即不是垃圾)枕稀; - 所有的 roots 被檢查和標(biāo)記為激活(即不是垃圾)。所有的子對(duì)象也被遞歸地檢查谜嫉。從 root 開始的所有對(duì)象如果是可達(dá)的萎坷,它就不被當(dāng)作垃圾。
- 所有未被標(biāo)記的內(nèi)存會(huì)被當(dāng)做垃圾沐兰,收集器現(xiàn)在可以釋放內(nèi)存哆档,歸還給操作系統(tǒng)了。
現(xiàn)代的垃圾回收器改良了算法住闯,但是本質(zhì)是相同的:可達(dá)內(nèi)存被標(biāo)記瓜浸,其余的被當(dāng)作垃圾回收。
不需要的引用是指開發(fā)者明知內(nèi)存引用不再需要比原,卻由于某些原因插佛,它仍被留在激活的 root 樹中。在 JavaScript 中量窘,不需要的引用是保留在代碼中的變量雇寇,它不再需要,卻指向一塊本該被釋放的內(nèi)存蚌铜。有些人認(rèn)為這是開發(fā)者的錯(cuò)誤谢床。
為了理解 JavaScript 中最常見的內(nèi)存泄漏,我們需要了解哪種方式的引用容易被遺忘厘线。
常見 JavaScript 內(nèi)存泄漏
意外的全局變量
JavaScript 處理未定義變量的方式比較寬松:未定義的變量會(huì)在全局對(duì)象創(chuàng)建一個(gè)新變量识腿。在瀏覽器中,全局對(duì)象是 window 造壮。
function foo(arg) {
bar = "this is a hidden global variable";
}
真相是:
function foo(arg) {
window.bar = "this is an explicit global variable";
}
函數(shù) foo 內(nèi)部忘記使用 var 渡讼,意外創(chuàng)建了一個(gè)全局變量。此例泄漏了一個(gè)簡(jiǎn)單的字符串耳璧,無傷大雅成箫,但是有更糟的情況。
另一種意外的全局變量可能由 this 創(chuàng)建:
function foo() {
this.variable = "potential accidental global";
}
// Foo 調(diào)用自己旨枯,this 指向了全局對(duì)象(window)
// 而不是 undefined
foo();
在 JavaScript 文件頭部加上 'use strict'蹬昌,可以避免此類錯(cuò)誤發(fā)生。啟用嚴(yán)格模式解析 JavaScript 攀隔,避免意外的全局變量皂贩。
全局變量注意事項(xiàng):
盡管我們討論了一些意外的全局變量栖榨,但是仍有一些明確的全局變量產(chǎn)生的垃圾。它們被定義為不可回收(除非定義為空或重新分配)明刷。尤其當(dāng)全局變量用于臨時(shí)存儲(chǔ)和處理大量信息時(shí)婴栽,需要多加小心。如果必須使用全局變量存儲(chǔ)大量數(shù)據(jù)時(shí)辈末,確保用完以后把它設(shè)置為 null 或者重新定義愚争。與全局變量相關(guān)的增加內(nèi)存消耗的一個(gè)主因是緩存。緩存數(shù)據(jù)是為了重用挤聘,緩存必須有一個(gè)大小上限才有用轰枝。高內(nèi)存消耗導(dǎo)致緩存突破上限,因?yàn)榫彺鎯?nèi)容無法被回收组去。
被遺忘的計(jì)時(shí)器或回調(diào)函數(shù)
在 JavaScript 中使用 setInterval 非常平常鞍陨。一段常見的代碼:
var someResource = getData();
setInterval(function() {
var node = document.getElementById('Node');
if(node) {
// 處理 node 和 someResource
node.innerHTML = JSON.stringify(someResource));
}
}, 1000);
此例說明了什么:與節(jié)點(diǎn)或數(shù)據(jù)關(guān)聯(lián)的計(jì)時(shí)器不再需要,node 對(duì)象可以刪除添怔,整個(gè)回調(diào)函數(shù)也不需要了湾戳∠涂酰可是广料,計(jì)時(shí)器回調(diào)函數(shù)仍然沒被回收(計(jì)時(shí)器停止才會(huì)被回收)。同時(shí)幼驶,someResource 如果存儲(chǔ)了大量的數(shù)據(jù)艾杏,也是無法被回收的。
對(duì)于觀察者的例子盅藻,一旦它們不再需要(或者關(guān)聯(lián)的對(duì)象變成不可達(dá))购桑,明確地移除它們非常重要。老的 IE 6 是無法處理循環(huán)引用的氏淑。如今勃蜘,即使沒有明確移除它們,一旦觀察者對(duì)象變成不可達(dá)假残,大部分瀏覽器是可以回收觀察者處理函數(shù)的缭贡。
觀察者代碼示例:
var element = document.getElementById('button');
function onClick(event) {
element.innerHTML = 'text';
}
element.addEventListener('click', onClick); // => 循環(huán)調(diào)用
對(duì)象觀察者和循環(huán)引用注意事項(xiàng)
老版本的 IE 是無法檢測(cè) DOM 節(jié)點(diǎn)與 JavaScript 代碼之間的循環(huán)引用,會(huì)導(dǎo)致內(nèi)存泄漏辉懒。如今阳惹,現(xiàn)代的瀏覽器(包括 IE 和 Microsoft Edge)使用了更先進(jìn)的垃圾回收算法,已經(jīng)可以正確檢測(cè)和處理循環(huán)引用了眶俩。換言之莹汤,回收節(jié)點(diǎn)內(nèi)存時(shí),不必非要調(diào)用 removeEventListener 了颠印。
脫離 DOM 的引用
有時(shí)纲岭,保存 DOM 節(jié)點(diǎn)內(nèi)部數(shù)據(jù)結(jié)構(gòu)很有用抹竹。假如你想快速更新表格的幾行內(nèi)容,把每一行 DOM 存成字典(JSON 鍵值對(duì))或者數(shù)組很有意義荒勇。此時(shí)柒莉,同樣的 DOM 元素存在兩個(gè)引用:一個(gè)在 DOM 樹中,另一個(gè)在字典中沽翔。將來你決定刪除這些行時(shí)兢孝,需要把兩個(gè)引用都清除.
var elements = {
button: document.getElementById('button'),
image: document.getElementById('image'),
text: document.getElementById('text')
};
function doStuff() {
image.src = 'http://some.url/image';
button.click();
console.log(text.innerHTML);
// 更多邏輯
}
function removeButton() {
// 按鈕是 body 的后代元素
document.body.removeChild(document.getElementById('button'));
// 此時(shí),仍舊存在一個(gè)全局的 #button 的引用
// elements 字典仅偎。button 元素仍舊在內(nèi)存中跨蟹,不能被 GC 回收。
}
此外還要考慮 DOM 樹內(nèi)部或子節(jié)點(diǎn)的引用問題橘沥。假如你的 JavaScript 代碼中保存了表格某一個(gè) <td> 的引用窗轩。將來決定刪除整個(gè)表格的時(shí)候,直覺認(rèn)為 GC 會(huì)回收除了已保存的 <td> 以外的其它節(jié)點(diǎn)座咆。實(shí)際情況并非如此:此 <td> 是表格的子節(jié)點(diǎn)痢艺,子元素與父元素是引用關(guān)系。由于代碼保留了 <td> 的引用介陶,導(dǎo)致整個(gè)表格仍待在內(nèi)存中堤舒。保存 DOM 元素引用的時(shí)候,要小心謹(jǐn)慎哺呜。
閉包
如果閉包的作用域中保存著一個(gè) HTML 元素舌缤,則該元素?zé)o法被銷毀。(下面代碼來自高程)
閉包是 JavaScript 開發(fā)的一個(gè)關(guān)鍵方面:匿名函數(shù)可以訪問父級(jí)作用域的變量某残。
function assgin() {
var ele = document.getElementById('someEle');
ele.onclick = function(){
alert(ele.id);
}
}
以上代碼創(chuàng)建了一個(gè)作為 ele 元素事件處理程序的閉包国撵,而這個(gè)閉包有創(chuàng)建了一個(gè)循環(huán)的引用,由于匿名函數(shù)保存了一個(gè) assgin() 的活動(dòng)對(duì)象的引用 玻墅,因此無法減少對(duì) ele 的引用次數(shù) , 只要匿名函數(shù)存在介牙,ele的引用次數(shù)至少是 1。我們可以稍微改寫一下:
function assgin() {
var ele = document.getElementById('someEle');
var id = ele.id
ele.onclick = function(){
alert(id);
}
ele = null;
}
上面代碼中澳厢,通過把 ele.id 的一個(gè)副本保存在一個(gè)變量中环础,并且在比保重引用該變量消除了循環(huán)引用,但是這樣還不能解決內(nèi)存泄露赏酥,閉包會(huì)引用包含函數(shù)的整個(gè)活動(dòng)對(duì)象喳整,而其中包含著 ele ,即使閉包不直接引用 ele 裸扶,包含函數(shù)的活動(dòng)對(duì)象中也會(huì)保存 一個(gè)引用框都,因此需要把 ele 變量設(shè)置為 null ,這樣就解除了對(duì) DOM 對(duì)象的引用,減少其引用數(shù),確保能正澄罕#回收熬尺。
關(guān)于內(nèi)存的發(fā)現(xiàn) chrome 的使用~暫時(shí)沒有使用過,看不太明白谓罗,就不 copy 了粱哼。
js閉包測(cè)試 => 看不懂~
上述內(nèi)容 copy 自下面二者:
JavaScript 內(nèi)存泄漏教程-阮一峰
4類 JavaScript 內(nèi)存泄漏及如何避免
ajax 原生實(shí)現(xiàn)
var xhr = createXHR()
xhr.onreadystatechange = function() {
if(xhr.readyState == 4) {
if(xhr.status == 200) {
console.log(xhr.responeText)
//do sth...
} else {
console.log('request fail' + xhr.status)
}
}
};
xhr.open('get', 'hello.com', true)
xhr.send(null);
閉包的理解
閉包是指有權(quán)訪問另一個(gè)函數(shù)作用域中的變量的函數(shù)。
這個(gè)口述我還是不知道怎么說檩咱,或許是應(yīng)用不夠看了無數(shù)文章到頭來敵不過忘記也可能我理解的還是不到位吧~個(gè)人不解釋了揭措,放參考鏈接吧
How do JavaScript closures work?--StackOverflow
學(xué)習(xí)Javascript閉包(Closure)--阮一峰的網(wǎng)絡(luò)日志
JS 中的閉包是什么--方應(yīng)杭
JavaScript 中 閉包 的詳解
閉包--MDN
閉包的應(yīng)用
html中一段文本內(nèi)容 hdslakddnska8das ,將文本中含有數(shù)組['d', 'a', '', '8'] 中的內(nèi)容標(biāo)記為紅色文本(字符串有改動(dòng))
設(shè)定 html 結(jié)構(gòu)
<style>
.mark {
color: red;
}
</style>
<html>
<body>
<div class='textToMark'>
hdslakddnska8das
</div>
</body>
</html>
方法一:循環(huán)
const textToMark = document.querySelector('.textToMark');
const text = textToMark.innerHTML;
const arr = ['d', 'a', '*', '8'];
const newText = text.split('');
function toMark (textArr, arr) {
for(let i = 0; i < newText.length; i++) {
for(let j = 0; j < arr.length; j++) {
if(newText[i] == arr[j]) {
newText[i] = `<span class='mark'>${newText[i]}</span>`;
}
}
}
return newText;
}
toMark(newText, arr);
textToMark.innerHTML = newText.join('');
方法二: 字符串的 replace
const textToMark = document.querySelector('.textToMark');
const text = textToMark.innerHTML;
const reg = /[da\*8]+/g;
var newtext = text.replace(reg, (match) => {
return match = `<span class='mark'>${match}</span>`;
});
textToMark.innerHTML = newtext;
代碼為個(gè)人寫出刻蚯,如果有更好的辦法歡迎指教
原生JS創(chuàng)建這樣的 dom 結(jié)構(gòu) < div id='hello'> < p class='textToMark'>hdslakddnska8das< p>< /div>
function createElement() {
var body = document.body;
var fragment = document.createDocumentFragment()
var div = document.createElement('div')
div.setAttribute('id', 'hello')
fragment.appendChild(div)
var p = document.createElement('p')
p.className = 'textToMark'
p.innerHTML = 'hdslakddnska8das'
div.appendChild(p);
body.appendChild(fragment)
}
createElement();
感謝評(píng)論指出绊含,已改正,關(guān)于節(jié)點(diǎn)創(chuàng)建 createElement 的效率問題炊汹,如果當(dāng)插入的節(jié)點(diǎn)很多的時(shí)候躬充,createElement 的效率會(huì)不如 createDocumentFragment .
createElement 每次 append 一個(gè)節(jié)點(diǎn)的時(shí)候,都會(huì)導(dǎo)致頁(yè)面的重排讨便,例如:
數(shù)據(jù)為這樣:
<ul id="myList">
<li>
<a href="www.baidu.com"></a>
</li>
<li>
<a href="www.helloworld.com"></a>
</li>
</ul>
var data = [
{ name: '36O秋招', url: 'http://campus.#/2015/grad.html'},
{ name: 'TX校招', url: 'http://join.qq.com/index.php'}
]
function appendChildToElement(appendToElement, data) {
var a, li;
for (var i = 0, len = data.length; i < len; i++) {
a = document.createElement('a');
a.href = data[i].url;
a.appChild(document.createTextNode(data[i].name))
li = document.createElement('li');
li.appendChild(a);
appendChildToElement(li);
}
}
這種情況下充甚,data 內(nèi)的每一個(gè)對(duì)象插入到 DOM 結(jié)構(gòu)的時(shí)候都會(huì)觸發(fā)一次重排,因此效率會(huì)較低霸褒。
但是我們可以改變他的 display 屬性伴找,臨時(shí)從文檔移除 ul ,即可有效減少重排次數(shù)傲霸。
var ul = document.getElementById('myList');
ur.style.display = 'none';
appendChildToElement(ul, data);
ul.style.display = 'block';
當(dāng)然疆瑰,更好的辦法就是利用 createDocumentFragment 來創(chuàng)建一個(gè)文檔片段.
var fragment = document.createElementFragment();
appendChildToElement(fragment, data);
document.getElementById('myList').appendChild(fragment);
只訪問了一次 DOM 節(jié)點(diǎn)眉反,只觸發(fā)了一次重排;再次感謝 @xaclincoln 的指出昙啄。
查了一些關(guān)于 createDocumentFragment 和 createElement 比較的文章。
- createDocumentFragment or createElement--StackOverflow
- createElement vs createDocumentFragment
- createElement 與 createDocumentFragment 的點(diǎn)點(diǎn)區(qū)別
- CreateDocumentFragment 的用處
創(chuàng)建一個(gè)函數(shù)對(duì) JS 基礎(chǔ)類型 ( function, boolean, array, number, string, object) 進(jìn)行值復(fù)制
function valueToCopy (valueBeCopy) {
var copyValue;
if (typeof (+valueBeCopy) === 'number' && typeof valueBeCopy !== 'object') {
copyValue = +valueBeCopy;
} else if (typeof valueBeCopy === 'string') {
copyValue = parseInt(copyValue);
} else if (typeof valueBeCopy === 'object'){
if(Array.isArray(valueBeCopy)) {
copyValue = valueBeCopy.slice();
}
copyValue = JSON.parse(JSON.stringify(valueBeCopy))
}
copyValue = valueBeCopy;
// console.log(copyValue)
return copyValue;
}

url 輸入到頁(yè)面完成經(jīng)歷了什么
感覺這篇文章非常非常詳細(xì)了太長(zhǎng)了寸五,過段時(shí)間再整理(抄襲)
老生常談-從輸入url到頁(yè)面展示到底發(fā)生了什么
選擇題
執(zhí)行順序
var input = document.getElementById('cls')
input.onmouseup = function() {
console.log('onmouseup')
}
input.onmousedown = function() {
console.log('onmousedown')
}
input.onclick = function() {
console.log('onclick')
}
input.onfocus = function() {
console.log('onfocus')
}
onmousedown => onfocus => onmouseup => onclick
a 鏈接默認(rèn)事件的阻止
A. a.onmouseup = function(e) {
e.preventDefault()
}
B. a.onmousedown = function(e) {
e.preventDefault()
}
C. a.onclick = function(e) {
e.preventDefault()
}
D. A B C 都可以~
- => 經(jīng)測(cè)試只有 onclick 可以
IE瀏覽器中 attachEvent 方式的事件綁定
attachEvent的this總是Window梳凛。
el.attachEvent('onclick', function(){
alert(this);
});
HTTP狀態(tài)碼
- 400 Bad Request
由于明顯的客戶端錯(cuò)誤(例如,格式錯(cuò)誤的請(qǐng)求語(yǔ)法梳杏,太大的大小韧拒,無效的請(qǐng)求消息或欺騙性路由請(qǐng)求),服務(wù)器不能或不會(huì)處理該請(qǐng)求十性。[31] - 401 Unauthorized(RFC 7235)
參見:HTTP基本認(rèn)證叛溢、HTTP摘要認(rèn)證
類似于403 Forbidden,401語(yǔ)義即“未認(rèn)證”劲适,即用戶沒有必要的憑據(jù)楷掉。[32]該狀態(tài)碼表示當(dāng)前請(qǐng)求需要用戶驗(yàn)證。
注意:當(dāng)網(wǎng)站(通常是網(wǎng)站域名)禁止IP地址時(shí)霞势,有些網(wǎng)站狀態(tài)碼顯示的401烹植,表示該特定地址被拒絕訪問網(wǎng)站斑鸦。
- 402 Payment Required
該狀態(tài)碼是為了將來可能的需求而預(yù)留的。該狀態(tài)碼最初的意圖可能被用作某種形式的數(shù)字現(xiàn)金或在線支付方案的一部分草雕,但幾乎沒有哪家服務(wù)商使用巷屿,而且這個(gè)狀態(tài)碼通常不被使用。如果特定開發(fā)人員已超過請(qǐng)求的每日限制墩虹,Google Developers API會(huì)使用此狀態(tài)碼嘱巾。[34] - 403 Forbidden
服務(wù)器已經(jīng)理解請(qǐng)求,但是拒絕執(zhí)行它诫钓。與401響應(yīng)不同的是浓冒,身份驗(yàn)證并不能提供任何幫助,而且這個(gè)請(qǐng)求也不應(yīng)該被重復(fù)提交尖坤。如果這不是一個(gè)HEAD請(qǐng)求稳懒,而且服務(wù)器希望能夠講清楚為何請(qǐng)求不能被執(zhí)行,那么就應(yīng)該在實(shí)體內(nèi)描述拒絕的原因慢味。當(dāng)然服務(wù)器也可以返回一個(gè)404響應(yīng)场梆,假如它不希望讓客戶端獲得任何信息。
選擇正確答案(構(gòu)造函數(shù)的引用地址)
var str = 'asd;
var str2 = new String(str) var str1 = new String(str)
console.log(str1 == str2 , str1 === str2)
A. true true
B. true false
C. false true
D. false false
// => 輸出 => false false
因?yàn)?new 出來的倆個(gè)字符串引用地址不同
下面的輸出結(jié)果 (this 指向問題)
function one () {
this.name = 1;
return function two () {
name = 2;
return function three() {
var name = 3;
console.log(this.name);
}
}
}
one()()() // => 2;
還有一部分題忘掉嘍 ~ 還有一些題具體的記不太清了纯路,稍作修改或油,考點(diǎn)計(jì)本差不多,上面答案有的是我自己寫的驰唬,有的是我 google 整理出來的顶岸,筆試期間攝像頭壞了,而且不小心彈出去了三四次~就當(dāng)練習(xí)了吧叫编,反正簡(jiǎn)歷也沒準(zhǔn)備好呢辖佣,哦,對(duì)了搓逾,考點(diǎn)大多都在高程中有詳細(xì)講解卷谈,需要好好看一下高程,面試應(yīng)該會(huì)問一些 Node 和 ES6吧霞篡,如果有錯(cuò)誤或者更好的方法請(qǐng)告訴我