欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

js的一些潛在規(guī)則示例分析

 更新時(shí)間:2023年02月21日 14:38:46   作者:Spirited_Away  
這篇文章主要為大家介紹了js的一些潛在規(guī)則示例分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

宏任務(wù)和微任務(wù)

采納 JSC 引擎的術(shù)語,我們把宿主發(fā)起的任務(wù)稱為宏觀任務(wù),把 JavaScript 引擎發(fā)起的任務(wù)稱為微觀任務(wù)。

JavaScript 引擎等待宿主環(huán)境分配宏觀任務(wù),在操作系統(tǒng)中,通常等待的行為都是一個(gè)事件循環(huán),所以在 Node 術(shù)語中,也會(huì)把這個(gè)部分稱為事件循環(huán)。在底層的 C/C++ 代碼中,這個(gè)事件循環(huán)是一個(gè)跑在獨(dú)立線程中的循環(huán)。

宏觀任務(wù)的隊(duì)列就相當(dāng)于事件循環(huán)。

在宏觀任務(wù)中,JavaScript 的 Promise 還會(huì)產(chǎn)生異步代碼,JavaScript 必須保證這些異步代碼在一個(gè)宏觀任務(wù)中完成,因此,每個(gè)宏觀任務(wù)中又包含了一個(gè)微觀任務(wù)隊(duì)列。

語句的執(zhí)行過程 (Completion Record )

我們知道有的語句按順序執(zhí)行,有的語句會(huì)阻斷執(zhí)行。那么這是何種原因?qū)е碌哪兀?/p>

我們來看一下js語句執(zhí)行的完成狀態(tài)。JavaScript 語句執(zhí)行的完成狀態(tài),我們用一個(gè)標(biāo)準(zhǔn)類型來表示:Completion Record。

Completion Record 表示一個(gè)語句執(zhí)行完之后的結(jié)果,它有三個(gè)字段:

  • [[type]] 表示完成的類型,有 break continue return throw 和 normal 幾種類型;如果返回的type是normal,那么語句將會(huì)順序執(zhí)行。
  • [[value]] 表示語句的返回值,如果語句沒有,則是 empty;只有表達(dá)式語句會(huì)產(chǎn)生 [[value]]。
  • [[target]] 表示語句的目標(biāo),通常是一個(gè) JavaScript 標(biāo)簽。當(dāng)在循環(huán)語句中,結(jié)合break/continue可以跳出多層循環(huán)。
outer: while(true) {
    inner: while(true) {
        break outer;
    }
}
console.log("finished")

在任何一個(gè)js語句之前都可以加一個(gè)標(biāo)簽。

    firstStatement: var i = 1;

控制語句跟 break 、continue 、return 、throw四種類型與控制語句兩兩組合產(chǎn)生的效果。

  • 消費(fèi)就是在當(dāng)前語句中結(jié)束了。

穿透就是繼續(xù)執(zhí)行下一條語句。

文法

文法 = 詞法 + 語法。

詞法

JavaScript 源代碼中的輸入可以這樣分類:

WhiteSpace 空白字符

LineTerminator 換行符

Comment 注釋

Token 詞

  • IdentifierName 標(biāo)識(shí)符名稱,典型案例是我們使用的變量名,注意這里關(guān)鍵字也包含在內(nèi)了。
  • Punctuator 符號(hào),我們使用的運(yùn)算符和大括號(hào)等符號(hào)。
  • NumericLiteral 數(shù)字直接量,就是我們寫的數(shù)字。 為什么12.toString會(huì)報(bào)錯(cuò)?

十進(jìn)制的 Number 可以帶小數(shù),小數(shù)點(diǎn)前后部分都可以省略,但是不能同時(shí)省略。12.被當(dāng)成一個(gè)詞。如果想讓表達(dá)式正常運(yùn)行,我們可以讓.成為一個(gè)詞。

    12. toString()
  • StringLiteral 字符串直接量,就是我們用單引號(hào)或者雙引號(hào)引起來的直接量。

字符串中其他必須轉(zhuǎn)義的字符是\和所有換行符。

  • Template 字符串模板,用反引號(hào)`括起來的直接量。
  • RegularExpressionLiteral

正則表達(dá)式有自己的語法規(guī)則,在詞法階段,僅會(huì)對(duì)它做簡單解析。

語句是否需要加分號(hào)

自動(dòng)插入分號(hào)規(guī)則其實(shí)獨(dú)立于所有的語法產(chǎn)生式定義,它的規(guī)則說起來非常簡單,只有三條。

  • 要有換行符,且下一個(gè)符號(hào)是不符合語法的,那么就嘗試插入分號(hào)。
  • 有換行符,且語法中規(guī)定此處不能有換行符,那么就自動(dòng)插入分號(hào)。
  • 源代碼結(jié)束處,不能形成完整的腳本或者模塊結(jié)構(gòu),那么就自動(dòng)插入分號(hào)。

no LineTerminator here規(guī)則

這個(gè)規(guī)則與自動(dòng)插入分號(hào)的第二條規(guī)則緊密相關(guān)。

腳本和模塊

腳本是可以由瀏覽器或者 node 環(huán)境引入執(zhí)行的,而模塊只能由 JavaScript 代碼用 import引入執(zhí)行。

從概念上,我們可以認(rèn)為腳本具有主動(dòng)性的 JavaScript 代碼段,是控制宿主完成一定任務(wù)的代碼;而模塊是被動(dòng)性的 JavaScript 代碼段,是等待被調(diào)用的庫。

直接 import 一個(gè)模塊,只是保證了這個(gè)模塊代碼被執(zhí)行,引用它的模塊是無法獲得它的任何信息的。帶 from 的 import 意思是引入模塊中的一部分信息,可以把它們變成本地的變量。

通過export default導(dǎo)出的值,和導(dǎo)入文件的變量不是實(shí)時(shí)綁定的。導(dǎo)出文件的變量改變不會(huì)影響導(dǎo)入變量的變化。

聲明提升

預(yù)處理階段,var 和函數(shù)聲明的作用能夠穿透一切語句結(jié)構(gòu),它只認(rèn)腳本、模塊和函數(shù)體三種語法結(jié)構(gòu)。

函數(shù)聲明提升和var變量聲明提升的區(qū)別

函數(shù)聲明能穿過if等語句,但是只是在全局創(chuàng)建一個(gè)同名的變量賦值為undefined,并沒有把函數(shù)體提升。

    console.log(foo); // undefined
    if(true) {
        function foo(){}
    }
    // 因?yàn)橐话愫瘮?shù)都是整體提升的。
    var a = 1;
    function foo() {
        console.log(a); // undefined
        if(false) {
            var a = 2;
        }
    }
    foo();

解析HTML

編譯階段。會(huì)將html標(biāo)簽拆分成一個(gè)個(gè)token(表示最小的有意義的單元), 種類大約只有標(biāo)簽開始、屬性、標(biāo)簽結(jié)束、注釋、CDATA 節(jié)點(diǎn)幾種。

實(shí)現(xiàn)分詞,又用到了狀態(tài)機(jī)。用狀態(tài)機(jī)做詞法分析,其實(shí)正是把每個(gè)詞的“特征字符”逐個(gè)拆開成獨(dú)立狀態(tài),然后再把所有詞的特征字符鏈合起來,形成一個(gè)聯(lián)通圖結(jié)構(gòu)。 其中每一個(gè)狀態(tài)函數(shù)都返回一個(gè)狀態(tài)函數(shù),做狀態(tài)遷移。

把html元素分成若干詞后,我們就可以構(gòu)建dom樹了。這個(gè)過程是使用棧來實(shí)現(xiàn)的。我們把每個(gè)解析的詞加入到棧中,當(dāng)接收完所有輸入,棧頂就是最后的根節(jié)點(diǎn)。

對(duì)于 Text 節(jié)點(diǎn),我們則需要把相鄰的 Text 節(jié)點(diǎn)合并起來,我們的做法是當(dāng)詞(token)入棧時(shí),檢查棧頂是否是 Text 節(jié)點(diǎn),如果是的話就合并 Text 節(jié)點(diǎn)。

可以點(diǎn)擊這里查看解析規(guī)則

github上別人寫了一個(gè)簡易的解析器

排版。

  • 瀏覽器對(duì)行的排版,一般是先行內(nèi)布局,再確定行的位置,根據(jù)行的位置計(jì)算出行內(nèi)盒和文字的排版位置。
  • 塊級(jí)盒比較簡單,它總是單獨(dú)占據(jù)一整行,計(jì)算出交叉軸方向的高度即可。
  • 浮動(dòng)元素排版,float 元素非常特別,瀏覽器對(duì) float 的處理是先排入正常流,再移動(dòng)到排版寬度的最左 /最右(這里實(shí)際上是主軸的最前和最后)。
  • 絕對(duì)定位元素。完全跟正常流無關(guān)的一種獨(dú)立排版模式,逐層找到其父級(jí)的 position 非 static 元素即可。

渲染。

瀏覽器中渲染這個(gè)過程,就是把每一個(gè)元素對(duì)應(yīng)的盒變成位圖。 這里的元素包括 HTML 元素和偽元素,一個(gè)元素可能對(duì)應(yīng)多個(gè)盒(比如 inline 元素,可能會(huì)分成多行)。每一個(gè)盒對(duì)應(yīng)著一張位圖。

渲染過程,是不會(huì)把子元素繪制到渲染的位圖上的,這樣,當(dāng)父子元素的相對(duì)位置發(fā)生變化時(shí),可以保證渲染的結(jié)果能夠最大程度被緩存,減少重新渲染。

合成。

合成的過程,就是為一些元素創(chuàng)建一個(gè)“合成后的位圖”(我們把它稱為合成層),把一部分子元素渲染到合成的位圖上面。

繪制。

繪制過程,實(shí)際上就是按照 z-index 把合成位圖依次繪制到屏幕上。

DOM API

DOM API 大致會(huì)包含 4 個(gè)部分。

  • 節(jié)點(diǎn):DOM 樹形結(jié)構(gòu)中的節(jié)點(diǎn)相關(guān) API。
  • 事件:觸發(fā)和監(jiān)聽事件相關(guān) API。
  • Range:操作文字范圍相關(guān) API。
  • 遍歷:遍歷 DOM 需要的 API。

節(jié)點(diǎn)

元素在DOM樹中關(guān)系api

  • parentNode
  • childNodes
  • firstChild
  • lastChild
  • nextSibling
  • previousSibling

操作 DOM 樹的API

  • appendChild
  • insertBefore
  • removeChild
  • replaceChild

一些高級(jí) API

  • compareDocumentPosition 是一個(gè)用于比較兩個(gè)節(jié)點(diǎn)中關(guān)系的函數(shù)。
  • contains 檢查一個(gè)節(jié)點(diǎn)是否包含另一個(gè)節(jié)點(diǎn)的函數(shù)。這個(gè)方法一般用于做一些點(diǎn)擊判斷,然后關(guān)閉一些dom的功能。
  • isEqualNode 檢查兩個(gè)節(jié)點(diǎn)是否完全相同。
  • isSameNode 檢查兩個(gè)節(jié)點(diǎn)是否是同一個(gè)節(jié)點(diǎn),實(shí)際上在 JavaScript 中可以用“===”。
  • cloneNode 復(fù)制一個(gè)節(jié)點(diǎn),如果傳入?yún)?shù) true,則會(huì)連同子元素做深拷貝。

創(chuàng)建DOM的api

  • createElement
  • createTextNode
  • createCDATASection
  • createComment
  • createProcessingInstruction
  • createDocumentFragment
  • createDocumentType

操作屬性的api

  • getAttribute
  • setAttribute
  • removeAttribute
  • hasAttribute 如果你喜歡 property 一樣的訪問 attribute,還可以使用 attributes 對(duì)象,比如document.body.attributes.class =“a”等效于document.body.setAttribute(“class”,“a”)。

查找元素api

  • querySelector
  • querySelectorAll
  • getElementById
  • getElementsByName
  • getElementsByTagName
  • getElementsByClassName

我們需要注意,getElementById、getElementsByName、getElementsByTagName、getElementsByClassName,這幾個(gè) API 的性能高于 querySelector。

新增加的節(jié)點(diǎn)會(huì)被添加到非querySelector, querySelectorAll查詢出來的對(duì)象上的。

遍歷

  • createNodeIterator
  • createTreeWalker

Range

Range API 表示一個(gè) HTML 上的范圍,這個(gè)范圍是以文字為最小單位的,所以 Range 不一定包含完整的節(jié)點(diǎn)。

具體請(qǐng)看這里

DOM中的位置

全局尺寸信息

我們獲取寬高的對(duì)象應(yīng)該是“盒”,于是 CSSOM View 為 Element 類添加了兩個(gè)方法:

  • getClientRects()。返回一個(gè)列表,里面包含元素對(duì)應(yīng)的每一個(gè)盒所占據(jù)的客戶端矩形區(qū)域,這里每一個(gè)矩形區(qū)域可以用 x, y, width, height 來獲取它的位置和尺寸。
  • getBoundingClientRect()。它返回元素對(duì)應(yīng)的所有盒的包裹的矩形區(qū)域,需要注意,這個(gè) API 獲取的區(qū)域會(huì)包括當(dāng) overflow 為visible 時(shí)的子元素區(qū)域。

這兩個(gè) API 獲取的矩形區(qū)域都是相對(duì)于視口的坐標(biāo),這意味著,這些區(qū)域都是受滾動(dòng)影響的。

事件

事件捕獲的由來?

我們操作元素時(shí),都是通過輸入設(shè)備來做到的,點(diǎn)擊事件來自觸摸屏或者鼠標(biāo),鼠標(biāo)點(diǎn)擊并沒有位置信息,但是一般操作系統(tǒng)會(huì)根據(jù)位移的累積計(jì)算出來,跟觸摸屏一樣,提供一個(gè)坐標(biāo)給瀏覽器。把這個(gè)坐標(biāo)轉(zhuǎn)換為具體的元素上事件的過程,就是捕獲過程了。

建議這樣使用冒泡和捕獲機(jī)制:默認(rèn)使用冒泡模式,當(dāng)開發(fā)組件時(shí),遇到需要父元素控制子元素的行為,可以使用捕獲機(jī)制。

事件處理函數(shù)不一定是函數(shù),也可以是個(gè) JavaScript 具有 handleEvent 方法的對(duì)象。

var o = {
    handleEvent: event => console.log(event)
}
document.body.addEventListener("keydown", o, false);

自定義事件。DOM API 中的事件并不能用于普通對(duì)象,所以很遺憾,我們只能在 DOM 元素上使用自定義事件。

    var evt = new Event("look", {
        "bubbles":true, 
        "cancelable":false
    });
    document.dispatchEvent(evt); // 調(diào)用自定義事件

性能優(yōu)化

以上就是js的一些潛在規(guī)則示例分析的詳細(xì)內(nèi)容,更多關(guān)于js潛在規(guī)則的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 前端JavaScript多數(shù)元素的算法詳解

    前端JavaScript多數(shù)元素的算法詳解

    這篇文章主要介紹了前端JavaScript多數(shù)元素的算法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • 一文了解什么是TypeScript?

    一文了解什么是TypeScript?

    這篇文章主要介紹了什么是TypeScript,TypeScript是JavaScript的超集,它可以編譯成純JavaScript代碼,TypeScript可以運(yùn)行在瀏覽器環(huán)境、Node.js環(huán)境或者ECMAScript3或者更高的JavaScript的引擎中,下面我們就進(jìn)入文章一起學(xué)習(xí)TypeScript的詳細(xì)內(nèi)容吧
    2021-12-12
  • 微信小程序 教程之模塊化

    微信小程序 教程之模塊化

    這篇文章主要介紹了微信小程序 模塊化的相關(guān)資料,需要的朋友可以參考下
    2016-10-10
  • JS前端宏任務(wù)微任務(wù)及Event Loop使用詳解

    JS前端宏任務(wù)微任務(wù)及Event Loop使用詳解

    這篇文章主要為大家介紹了JS前端宏任務(wù)微任務(wù)及Event Loop使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • 微信小程序 條件渲染詳解

    微信小程序 條件渲染詳解

    這篇文章主要介紹了微信小程序 條件渲染詳解的相關(guān)資料,需要的朋友可以參考下
    2016-10-10
  • JS前端二維數(shù)組生成樹形結(jié)構(gòu)示例詳解

    JS前端二維數(shù)組生成樹形結(jié)構(gòu)示例詳解

    這篇文章主要為大家介紹了JS前端二維數(shù)組生成樹形結(jié)構(gòu)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09
  • 制作特殊字的腳本

    制作特殊字的腳本

    制作特殊字的腳本...
    2006-06-06
  • requestAnimationFrame使用示例詳解

    requestAnimationFrame使用示例詳解

    這篇文章主要為大家介紹了requestAnimationFrame使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-02-02
  • Umi4集成阿里低代碼框架lowcode-engine實(shí)現(xiàn)

    Umi4集成阿里低代碼框架lowcode-engine實(shí)現(xiàn)

    這篇文章主要為大家介紹了Umi4集成阿里低代碼框架lowcode-engine實(shí)現(xiàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • 詳解微信小程序如何實(shí)現(xiàn)類似ChatGPT的流式傳輸

    詳解微信小程序如何實(shí)現(xiàn)類似ChatGPT的流式傳輸

    這篇文章主要為大家介紹了微信小程序如何實(shí)現(xiàn)類似ChatGPT的流式傳輸示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03

最新評(píng)論