代碼輸出結果
var a = 1;
setTimeout(function(){
a = 2;
console.log(a);
}, 0);
var a ;
console.log(a);
a = 3;
console.log(a);
// 輸出結果
1 3 2
// 原因:setTimeout異步執(zhí)行,從上到下執(zhí)行完之后再執(zhí)行setTimeout內(nèi)的語句
- var a = 1:聲明并將1賦值給a
- setTimeout方法加入任務隊列不執(zhí)行
- var a:聲明a a的值不變
- console.log(a) 輸出為 1
- a = 3:將3賦值給a
- console.log(a) 輸出為3
- 執(zhí)行setTimeout,a被賦值為2并即時輸出
代碼輸出結果
var flag = true;
setTimeout(function(){
flag = false;
},0)
while(flag){}
console.log(flag);
// 不輸出任何東西,且控制臺/瀏覽器卡死
- var flag = true,給flag賦值
- 遇到setTimeout,加入任務隊列,跳過
- while語句,這里的flag是true,執(zhí)行{}內(nèi)循環(huán)體,循環(huán)體無內(nèi)容無break,陷入死循環(huán)
實現(xiàn)一個節(jié)流函數(shù)
用途
函數(shù)節(jié)流實際上是一個日常處理函數(shù)/方法短時間多次調(diào)用導致的性能/表現(xiàn)問題的優(yōu)化方案
通過添加定時器及對應的清除方法,讓可能會多次調(diào)用重復函數(shù)/方法時,如果但時間內(nèi)重復調(diào)用,則刪除上一次調(diào)用
舉例
// 常規(guī)寫法
var timer
function test(){
if(timer){
clearTimeout(timer)
}
timer = setTimeout(function(){
console.log('上一次調(diào)用once函數(shù)間隔時間大于設置時間,成功執(zhí)行一次')
},500)
}
// 測試輸出
test()
// 測試結果
達到了節(jié)流作用
簡單解釋單線程、任務隊列的概念

單線程模型
單線程
JavaScript是瀏覽器用來與用戶進行交互、進行DOM操作的,這也使得了它必須是單線程這一特性。
所謂單線程也就是只有一條線,一步一步走
任務隊列
在JavaScript中任務有兩種,一種是同步任務,一種是異步任務。
- 同步任務:各個任務按照文檔定義的順序一一推入"執(zhí)行棧"中,當前一個任務執(zhí)行完畢,才會開始執(zhí)行下一個任務。
- 異步任務:各個任務推入"任務隊列"中,只有在當前的所有同步任務執(zhí)行完畢,才會將隊列中的任務"出隊"執(zhí)行。
- 當線程中沒有執(zhí)行任何同步代碼的前提下才會執(zhí)行異步代碼
列出DOM 元素選取的 API
-
getElementById()
getElementById方法返回匹配指定ID屬性的元素節(jié)點。如果沒有發(fā)現(xiàn)匹配的節(jié)點,則返回null。這也是獲取一個元素最快的方法 -
getElementsByClassName()
getElementsByClassName方法返回一個類似數(shù)組的對象(HTMLCollection類型的對象),包括了所有class名字符合指定條件的元素(搜索范圍包括本身),元素的變化實時反映在返回結果中。這個方法不僅可以在document對象上調(diào)用,也可以在任何元素節(jié)點上調(diào)用。 -
getElementsByTagName()
getElementsByTagName方法返回所有指定標簽的元素(搜索范圍包括本身)。返回值是一個HTMLCollection對象,也就是說,搜索結果是一個動態(tài)集合,任何元素的變化都會實時反映在返回的集合中。這個方法不僅可以在document對象上調(diào)用,也可以在任何元素節(jié)點上調(diào)用。 -
getElementsByName()
getElementsByName方法用于選擇擁有name屬性的HTML元素,比如form、img、frame、embed和object,返回一個NodeList格式的對象,不會實時反映元素的變化。 -
querySelector()
querySelector方法返回匹配指定的CSS選擇器的元素節(jié)點。如果有多個節(jié)點滿足匹配條件,則返回第一個匹配的節(jié)點。如果沒有發(fā)現(xiàn)匹配的節(jié)點,則返回null。 -
querySelectorAll()
querySelectorAll方法返回匹配指定的CSS選擇器的所有節(jié)點,返回的是NodeList類型的對象。NodeList對象不是動態(tài)集合,所以元素節(jié)點的變化無法實時反映在返回結果中。
如何創(chuàng)建元素、如何添加元素
創(chuàng)建元素
-
createElement():createElement方法用來生成HTML元素節(jié)點。
var newDiv = document.createElement("div");
//createElement方法的參數(shù)為元素的標簽名,即元素節(jié)點的tagName屬性。如果傳入大寫的標簽名,會被轉為小寫。如果參數(shù)帶有尖括號(即<和>)或者是null,會報錯。
-
createTextNode():createTextNode方法用來生成文本節(jié)點,參數(shù)為所要生成的文本節(jié)點的內(nèi)容。
var newDiv = document.createElement("div");
var newContent = document.createTextNode("Hello");
-
createDocumentFragment():createDocumentFragment方法生成一個DocumentFragment對象。
var docFragment = document.createDocumentFragment();
//DocumentFragment對象是一個存在于內(nèi)存的DOM片段
//但是不屬于當前文檔,常常用來生成較復雜的DOM結構,然后插入當前文檔。
//這樣做的好處在于,因為DocumentFragment不屬于當前文檔
//對它的任何改動,都不會引發(fā)網(wǎng)頁的重新渲染,比直接修改當前文檔的DOM有更好的性能表現(xiàn)。
添加元素
-
appendChild():在元素末尾添加元素
var newDiv = document.createElement("div");
var newContent = document.createTextNode("Hello");
newDiv.appendChild(newContent);
-
insertBefore():在某個元素之前插入元素
var newDiv = document.createElement("div");
var newContent = document.createTextNode("Hello");
newDiv.insertBefore(newContent, newDiv.firstChild);
-
replaceChild():replaceChild()接受兩個參數(shù):要插入的元素和要替換的元素
newDiv.replaceChild(newElement, oldElement);
刪除元素
removeChild()
parentNode.removeChild(childNode);
clone元素
-
cloneNode()// 深拷貝
node.cloneNode(true);