整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          前端基礎入門(HTML)

          習目標

          • 了解常用瀏覽器
          • 掌握WEB標準
          • 理解標簽語義化
          • 掌握常用的排版標簽
          • 掌握常用的文本格式化圖像鏈接等標簽
          • 掌握三種列表標簽
          • 掌握表格標簽
          • 掌握表格標簽
          • 掌握表單標簽

          HTML第一天目標

          能夠寫出基本的頁面(里面包含圖片、各種標簽和鏈接)

          開發工具

          我們主要用的開發工具有chrome、hbuilder、Photoshop

          瀏覽器顯示

          瀏覽器是網頁顯示、運行的平臺,常用的瀏覽器有IE、火狐(Firefox)、谷歌(Chrome)、Safari和Opera等。我們平時稱為五大瀏覽器。

          瀏覽器內核(理解)

          瀏覽器內核又可以分成兩部分:渲染引擎(layout engineer 或者 Rendering Engine)和 JS 引擎。
          渲染引擎 :它負責取得網頁的內容(HTML、XML、圖像等等)、整理訊息(例如加入 CSS 等),以及計算網頁的顯示方式,然后會輸出至顯示器或打印機。瀏覽器的內核的不同對于網頁的語法解釋會有不同,所以渲染的效果也不相同。
          JS 引擎 則是解析 Javascript 語言,執行 javascript語言來實現網頁的動態效果。


          最開始渲染引擎和 JS 引擎并沒有區分得很明確,后來 JS 引擎越來越獨立,內核就傾向于只指渲染引擎。有一個網頁標準計劃小組制作了一個 ACID 來測試引擎的兼容性和性能。內核的種類很多,如果加上沒什么人使用的非商業的免費內核,可能會有10多種,但是常見的瀏覽器內核可以分這四種:Trident、Gecko、Blink、Webkit。

          了解一點:移動端的瀏覽器內核主要說的是系統內置瀏覽器的內核。
          Android手機而言,使用率最高的就是Webkit內核,大部分國產瀏覽器宣稱的自己的內核,基本上也是屬于webkit二次開發。

          iOS以及WP7平臺上,由于系統原因,系統大部分自帶瀏覽器內核,一般是Safari或者IE內核Trident的


          Web標準

          • 了解常用瀏覽器
            • 1、讓Web的發展前景更廣闊
            • 2、內容能被更廣泛的設備訪問
            • 3、更容易被搜尋引擎搜索
            • 4、降低網站流量費用
              • 5、使網站更易于維護
              • 6、提高頁面瀏覽速度

          web標準的結構

          結構標準:結構用于對網頁元素進行整理和分類,咱們主要學的是HTML。 最重要
          表現標準:表現用于設置網頁元素的版式、顏色、大小等外觀樣式,主要指的是CSS。
          行為標準:行為是指網頁模型的定義及交互的編寫,咱們主要學的是 Javascript


          HTML初識

          HTML(英文Hyper Text Markup Language的縮寫)中文譯為“超文本標簽語言”。是用來描述網頁的一種語言。

          所謂超文本,因為它可以加入圖片、聲音、動畫、多媒體等內容,不僅如此,它還可以從一個文件跳轉到另一個文件,與世界各地主機的文件連接。

          <h1> 我是一個大標題 </h1>

          注意: 體會 文本 標簽 語言 幾個詞語

          • HTML 指的是超文本標記語言 (Hyper Text Markup Language)
          • HTML 不是一種編程語言,而是一種標記語言 (markup language)
          • 標記語言是一套標記標簽 (markup tag)

          總結: HTML 作用就是用標記標簽來描述網頁,把網頁內容在瀏覽器中展示出來。


          HTML骨架格式

          <!DOCTYPE html>
          <html lang="en">
          <head>
              <meta charset="UTF-8">
              <meta http-equiv="X-UA-Compatible" content="IE=edge">
              <meta name="viewport" content="width=device-width, initial-scale=1.0">
              <title>Document</title>
              </style>
          </head>
          <body>
              <div class="box"></div>
          </body>
          </html>

          骨架結構解析

          1.HTML標簽:
          作用所有HTML中標簽的一個根節點。 最大的標簽 根標簽
          2 head標簽: 文檔的頭部
          文檔的頭部描述了文檔的各種屬性和信息,包括文檔的標題、在 Web 中的位置以及和其他文檔的關系等。絕大多數文檔頭部包含的數據都不會真正作為內容顯示給讀者。

          注意在head標簽中我們必須要設置的標簽是title

          3.title標簽: 文檔的標題
          作用:讓頁面擁有一個屬于自己的標題。
          4.body標簽:文檔的主體 以后我們的頁面內容 基本都是放到body里面的
          body 元素包含文檔的所有內容(比如文本、超鏈接、圖像、表格和列表等等。)


          HTML標簽分類

          在HTML頁面中,帶有“< >”符號的元素被稱為HTML標簽,如上面提到的 HTML、head、body都是HTML骨架結構標簽。所謂標簽就是放在“< >” 標簽符中表示某個功能的編碼命令,也稱為HTML標簽或 HTML元素

          1.雙標簽

          <標簽名> 內容 </標簽名>

          該語法中“<標簽名>”表示該標簽的作用開始,一般稱為“開始標簽(start tag)”,“</標簽名>” 表示該標簽的作用結束,一般稱為“結束標簽(end tag)”。和開始標簽相比,結束標簽只是在前面加了一個關閉符“/”。

          比如 <body>我是文字 </body>

          2.單標簽

          <標簽名 />

          單標簽也稱空標簽,是指用一個標簽符號即可完整地描述某個功能的標簽。

          比如 <br />


          HTML標簽關系

          標簽的相互關系就分為兩種:

          1.嵌套關系

          <head> <title> </title> </head>

          2.并列關系

          <head></head> <body></body>


          HTML常用標簽

          首先 HTML和CSS是兩種完全不同的語言,我們學的是結構,就只寫HTML標簽,認識標簽就可以了。 不會再給結構標簽指定樣式了。

          HTML標簽有很多,這里我們學習最為常用的,后面有些較少用的,我們可以查下手冊就可以了。

          排版標簽

          標題標簽(熟記)

          單詞縮寫: head 頭部. 標題 title 文檔標題

          為了使網頁更具有語義化,我們經常會在頁面中用到標題標簽,HTML提供了6個等級的標題,即
          <h1>、<h2>、<h3>、<h4>、<h5>和<h6>
          其基本語法格式如下:

          <hn> 標題文本 </hn>


          段落標簽(熟記)

          <p> 文本內容 </p>


          水平線標簽(認識)

          <hr />是單標簽


          換行標簽(熟記)

          <br />


          div span標簽(重點)

          div span 是沒有語義的 是我們網頁布局主要的2個盒子 css+div

          div 就是 division 的縮寫 分割, 分區的意思 其實有很多div 來組合網頁。

          span, 跨度,跨距;范圍

          語法格式:

          <div> 這是頭部 </div> <span>今日價格</span>


          文本格式化標簽(熟記)

          在網頁中,有時需要為文字設置粗體、斜體或下劃線效果,這時就需要用到HTML中的文本格式化標簽,使文字以特殊的方式顯示。

          b i s u 只有使用 沒有 強調的意思 strong em del ins 語義更強烈


          標簽屬性

          使用HTML制作網頁時,如果想讓HTML標簽提供更多的信息,可以使用HTML標簽的屬性加以設置。其基本語法格式如下:

          <標簽名 屬性1="屬性值1" 屬性2="屬性值2" …> 內容 </標簽名>

          在上面的語法中,

          1.標簽可以擁有多個屬性,必須寫在開始標簽中,位于標簽名后面。

          2.屬性之間不分先后順序,標簽名與屬性、屬性與屬性之間均以空格分開。

          3.任何標簽的屬性都有默認值,省略該屬性則取默認值。

          采取 鍵值對 的格式 key="value" 的格式

          比如:

          <hr width="400" />

          屬性 是 寬度

          值 是 400


          圖像標簽img (重點)

          單詞縮寫: image 圖像

          HTML網頁中任何元素的實現都要依靠HTML標簽,要想在網頁中顯示圖像就需要使用圖像標簽,接下來將詳細介紹圖像標簽<img />以及和他相關的屬性。其基本語法格式如下:

          該語法中src屬性用于指定圖像文件的路徑和文件名,他是img標簽的必需屬性。

          <img src="圖像URL" />


          鏈接標簽(重點)

          單詞縮寫: anchor 的縮寫 [???k?(r)] 。基本解釋 錨, 鐵錨 的

          在HTML中創建超鏈接非常簡單,只需用標簽環繞需要被鏈接的對象即可,其基本語法格式如下:

          <a href="跳轉目標" target="目標窗口的彈出方式">文本或圖像</a>

          href:用于指定鏈接目標的url地址,當為標簽應用href屬性時,它就具有了超鏈接的功能。 Hypertext Reference的縮寫。意思是超文本引用

          target:用于指定鏈接頁面的打開方式,其取值有self和blank兩種,其中self為默認值,blank為在新窗口中打開方式。

          注意:

          1.外部鏈接 需要添加 http:// www.baidu.com

          2.內部鏈接 直接鏈接內部頁面名稱即可 比如 < a href="index.html"> 首頁

          3.如果當時沒有確定鏈接目標時,通常將鏈接標簽的href屬性值定義為“#”(即href="#"),表示該鏈接暫時為一個空鏈接。

          4.不僅可以創建文本超鏈接,在網頁中各種網頁元素,如圖像、表格、音頻、視頻等都可以添加超鏈接。


          錨點定位 (難點)

          通過創建錨點鏈接,用戶能夠快速定位到目標內容。

          創建錨點鏈接分為兩步:

          1.使用“a href=”#id名>“鏈接文本"</a>創建鏈接文本(被點擊的) <a href="#two"> 2.使用相應的id名標注跳轉目標的位置。 <h3 id="two">第2集</h3>


          base 標簽 基本的

          base 可以設置整體鏈接的打開狀態

          base 寫到 <head> </head> 之間

          把所有的連接 都默認添加 target="_blank"


          特殊字符標簽 (理解)


          注釋標簽

          在HTML中還有一種特殊的標簽——注釋標簽。如果需要在HTML文檔中添加一些便于閱讀和理解但又不需要顯示在頁面中的注釋文字,就需要使用注釋標簽。其基本語法格式如下:

          <!-- 注釋語句 --> ctrl + / 或者 ctrl +shift + /

          注釋內容不會顯示在瀏覽器窗口中,但是作為HTML文檔內容的一部分,也會被下載到用戶的計算機上,查看源代碼時就可以看到。


          路徑(重點、難點)

          實際工作中,通常新建一個文件夾專門用于存放圖像文件,這時再插入圖像,就需要采用“路徑”的方式來指定圖像文件的位置。

          根目錄 當前目錄

          路徑可以分為: 相對路徑和絕對路徑


          相對路徑

          以引用文件之網頁所在位置為參考基礎,而建立出的目錄路徑。因此,當保存于不同目錄的網頁引用同一個文件時,所使用的路徑將不相同,故稱之為相對路徑。

          1. 圖像文件和HTML文件位于同一文件夾:只需輸入圖像文件的名稱即可,如img src="logo.gif" /。
          2. 圖像文件位于HTML文件的下一級文件夾:輸入文件夾名和文件名,之間用“/”隔開,如img src="img/img01/logo.gif" /。
          1. 圖像文件位于HTML文件的上一級文件夾:在文件名之前加入“../” ,如果是上兩級,則需要使用 “../ ../”,以此類推,如img src="../logo.gif" /。

          絕對路徑

          絕對路徑以Web站點根目錄為參考基礎的目錄路徑。之所以稱為絕對,意指當所有網頁引用同一個文件時,所使用的路徑都是一樣的

          “D:webimglogo.gif”,或完整的網絡地址,例如“http://www.itcast.cn/images/l...”。


          總結今天的思路貫穿線


          列表標簽

          無序列表 ul (重點)

          無序列表的各個列表項之間沒有順序級別之分,是并列的。其基本語法格式如下:

          <ul> <li>列表項1</li> <li>列表項2</li> <li>列表項3</li> ...... </ul>

          注意:

          1. <ul></ul>中只能嵌套<li></li>,直接在<ul></ul>標簽中輸入其他標簽或者文字的做法是不被允許的。
          2. <li>與</li>之間相當于一個容器,可以容納所有元素。
          1. 無序列表會帶有自己樣式屬性,放下那個樣式,一會讓CSS來!

          有序列表 ol (了解)

          有序列表即為有排列順序的列表,其各個列表項按照一定的順序排列定義,有序列表的基本語法格式如下:

          <ol> <li>列表項1</li> <li>列表項2</li> <li>列表項3</li> ...... </ol>

          所有特性基本與ul 一致。

          但是實際工作中, 較少用 ol img src="media/1.jpg" />


          自定義列表(理解)

          定義列表常用于對術語或名詞進行解釋和描述,定義列表的列表項前沒有任何項目符號。其基本語法如下:

          <dl> <dt>名詞1</dt> <dd>名詞1解釋1</dd> <dd>名詞1解釋2</dd> ... <dt>名詞2</dt> <dd>名詞2解釋1</dd> <dd>名詞2解釋2</dd> ... </dl>


          表格 table(會使用)

          創建表格

          在HTML網頁中,要想創建表格,就需要使用表格相關的標簽。創建表格的基本語法格式如下:

          <table> <tr> <td>單元格內的文字</td> ... </tr> ... </table>

          在上面的語法中包含三對HTML標簽,分別為 table</table、tr</tr、td</td,他們是創建表格的基本標簽,缺一不可,下面對他們進行具體的解釋
          1.table用于定義一個表格。

          2.tr 用于定義表格中的一行,必須嵌套在 table標簽中,在 table中包含幾對 tr,就有幾行表格。

          3.td /td:用于定義表格中的單元格,必須嵌套在<tr></tr>標簽中,一對 <tr> </tr>中包含幾對<td></td>,就表示該行中有多少列(或多少個單元格)。


          注意:

          1. <tr></tr>中只能嵌套<td></td> 2. <td></td>標簽,他就像一個容器,可以容納所有的元素


          表格屬性


          表頭標簽

          表頭一般位于表格的第一行或第一列,其文本加粗居中,如下圖所示,即為設置了表頭的表格。設置表頭非常簡單,只需用表頭標簽th</th替代相應的單元格標簽td</td即可。


          表格結構(了解)

          在使用表格進行布局時,可以將表格劃分為頭部、主體和頁腳(頁腳因為有兼容性問題,我們不在贅述),具體 如下所示:

          <thead></thead>:用于定義表格的頭部。

          必須位于<table></table> 標簽中,一般包含網頁的logo和導航等頭部信息。

          <tbody></tbody>:用于定義表格的主體。

          位于<table></table>標簽中,一般包含網頁中除頭部和底部之外的其他內容。


          表格標題

          表格的標題: caption
          定義和用法

          caption 元素定義表格標題。

          <table>    <caption>我是表格標題</caption> </table>

          caption 標簽必須緊隨 table 標簽之后。您只能對每個表格定義一個標題。通常這個標題會被居中于表格之上。


          合并單元格(難點)

          跨行合并:rowspan 跨列合并:colspan

          合并單元格的思想:

          將多個內容合并的時候,就會有多余的東西,把它刪除。 例如 把 3個 td 合并成一個, 那就多余了2個,需要刪除。 公式: 刪除的個數 = 合并的個數 - 1

          合并的順序 先上 先左


          總結表格

          1. 表格提供了HTML 中定義表格式數據的方法。
          2. 表格中由行中的單元格組成。
          1. 表格中沒有列元素,列的個數取決于行的單元格個數。
          2. 表格不要糾結于外觀,那是CSS 的作用。

          表格的學習要求: 能手寫表格結構,并且能合并單元格。


          表單標簽(掌握)

          表單控件:

          包含了具體的表單功能項,如單行文本輸入框、密碼輸入框、復選框、提交按鈕、重置按鈕等。

          提示信息:

          一個表單中通常還需要包含一些說明性的文字,提示用戶進行填寫和操作。

          表單域:

          他相當于一個容器,用來容納所有的表單控件和提示信息,可以通過他定義處理表單數據所用程序的url地址,以及數據提交到服務器的方法。如果不定義表單域,表單中的數據就無法傳送到后臺服務器。


          input 控件(重點)

          在上面的語法中,input /標簽為單標簽,type屬性為其最基本的屬性,其取值有多種,用于指定不同的控件類型。除了type屬性之外,input /標簽還可以定義很多其他的屬性,其常用屬性如下表所示。


          label標簽(理解)

          label 標簽為 input 元素定義標注(標簽)。

          作用: 用于綁定一個表單元素, 當點擊label標簽的時候, 被綁定的表單元素就會獲得輸入焦點

          如何綁定元素呢?

          for 屬性規定 label 與哪個表單元素綁定。

          <label for="male">Male</label> <input type="radio" name="sex" id="male" value="male">

          textarea控件(文本域)

          如果需要輸入大量的信息,就需要用到textarea/textarea標簽。通過textarea控件可以輕松地創建多行文本輸入框,其基本語法格式如下:

          <textarea cols="每行中的字符數" rows="顯示的行數">   文本內容 </textarea>


          下拉菜單

          使用select控件定義下拉菜單的基本語法格式如下

          <select>   <option>選項1</option>   <option>選項2</option>   <option>選項3</option>   ... </select>

          注意:

          1. select</select中至少應包含一對option></option。
          2. 在option 中定義selected =" selected "時,當前項即為默認選中項。

          表單域

          在HTML中,form標簽被用于定義表單域,即創建一個表單,以實現用戶信息的收集和傳遞,form中的所有內容都會被提交給服務器。創建表單的基本語法格式如下:

          <form action="url地址" method="提交方式" name="表單名稱">   各種表單控件 </form>

          常用屬性:

          1. Action
            在表單收集到信息后,需要將信息傳遞給服務器進行處理,action屬性用于指定接收并處理表單數據的服務器程序的url地址。
          2. method
            用于設置表單數據的提交方式,其取值為get或post。
          1. name
            用于指定表單的名稱,以區分同一個頁面中的多個表單。

          注意: 每個表單都應該有自己表單域。

          如需轉載,請注明出處,否則將追究法律責任。

          個視頻我們來寫兩個圓環。這個圓環雖然看起來只是普普通通的兩個圓,但是認真一看好像又沒那么簡單,因為它是交錯重疊起來的,并且還有一點陰影的效果,看起來比較真實。這個案例其實是UTube上面一個比較知名博主的教學案例,我們不妨來學習一下。

          可能很多人也看過,我們今天主要來實現這兩個圓環重疊的部分,陰影的部分比較簡單,大家可以自己去思考一下。html里面這兩個div就是這兩個圓環,樣式現在寫了一些基本的樣式,其它樣式重新來寫。

          ·先來把這兩個圓環的基礎樣式寫出來,兩個圓有了,然后把其中一個變成紅色,再讓它們先簡單的重疊一下,控制一下第二個圓環,調整一下它的邊框顏色就可以了,把它變成紅色。

          ·再往左邊移動60像素,先簡單重疊起來。現在兩個圓只是簡單的重疊,我們要怎么樣實現這種交錯重疊?就好像兩個圓環是穿起來的這種感覺。這里分別給這兩個圓環加個偽元素,我們是可以通過定位把一個盒子撐起來的。

          ·這里給它設置一下inset,關鍵就是inset設置為多少合適。如果是設置為0,也就是四個方向都是設為0,按道理應該是和父元素完全重疊的(沒border的話)。

          ·加個邊框看一下,很明顯它并沒有和白色圓環完全重疊,而是在它里面。這是因為我們看到的這兩個圓環,看到的只是border邊框的區域。inset的設置為0,它只不過是貼在content內容區域里面,所以偽元素我們要把它擴大才可以。

          ·這里要調整一下inset的值,0是剛好貼滿content的區域,設置為正值它是收縮的,所以這里設置為-25px。現在和白色的圓環就一樣大了,只不過一個正方形一個圓形,等一下把偽元素調整成圓的就可以了。

          ·然后單獨來設置一下上邊框,同樣也是白色的邊框,還有右邊框也單獨設置一下。ok,再把另外兩條邊框設置為透明。現在左邊和下邊就看不到了,再把它設置成一個圓,這樣它就可以和第一個圓環完全重疊起來了。

          ·現在偽元素這半個圓環就和本來的圓環完全重疊起來,那有什么用?還是和原來的一樣,但是現在就可以單獨給偽元素這半個圓環設置層級了,把層級調高一點,這樣這一段圓環它就可以蓋在上面,然后再給它旋轉一下位置,讓它旋轉負的四十五度,這樣兩個圓環貫穿重疊起來的效果就完成了。

          其實就是借助了一個偽元素做了一個障眼法,如果想實現圓環交匯的地方有點陰影的效果,也可以多寫兩個偽元素來實現,這個大家可以自己來思考一下。

          這個視頻就到這里,感謝大家的收看。

          理清執行上下文作用域閉包這三個關系之前,我們需要先理解一些概念。

          我們知道所學的高級語言分為兩類:1、編譯型 2、解釋型

          編譯型(compilation):將整個代碼立刻轉化為機器代碼,然后寫下機器代碼轉換為可在任何計算機上執行的可移植文件,然后在進行執行。

          解釋:解釋器貫穿整個源代碼進行一行一行的讀取執行,但是還是會轉為機器代碼,但是發生在執行前,而不是提前到和編譯一樣,整體進行轉換為機器代碼。

          對于Javascript,我們了解到的是它是一個解釋型語言,但是隨著后續的發展,常用于web或者服務端的開發,性能難以跟上。因此現代JavaScript是實時編譯(JIT),將匯編和解釋混合在一起,對整個源文件代碼進行轉化為機器代碼,然后立刻執行,這樣速度就更快些,省去了可移植文件,節省了時間。

          現代JavaScript在V8引擎的工作原理:

          因此JavaScript代碼的整個執行過程,分為兩個階段:

          • 編譯階段:由編譯器完成,將代碼翻譯成可執行代碼,這個階段作用域規則會確定。
          • 執行階段:執行階段由引擎完成,主要任務是執行可執行代碼,執行上下文在這個階段創建。


          明白這些之后,我們繼續說執行上下文和作用域。

          執行上下文

          1、執行上下文一句話解釋

          執行上下文是一段JavaScript代碼執行的環境,包含了所有必要的信息以供其執行。

          2、執行上下文的出現時機

          上面畫過一張V8引擎運行圖,當時所講的詞法環境是在 編譯階段產生,現在講的執行上下文是在引擎執行階段進行。

          當一段js代碼出現的時候,js引擎對整體代碼進行編譯完成轉為機器代碼后便可進行執行,此時會為頂級代碼立刻創建一個全局上下文(頂級代碼一定不在任何函數內,只有函數外的代碼會被首先執行,函數內的只會在調用的時候執行),創建完成后將其推入js引擎的堆棧當中。接著進入執行階段,執行可執行代碼,該賦值賦值,遇到函數,就創建一個函數執行上下文,并往調用棧中壓入該函數的執行上下文;反復循環,到最后調用棧中只剩一個全局執行上下文,除非你關閉瀏覽器,不然全局執行上下文不會彈出。

          3、執行上下文的生命周期

          根據第二點,執行上下文被分為兩個階段:

          • 創建階段:
            • this 值的確定,即我們所熟知的 this 綁定
            • 創建詞法環境組件(LexicalEnvironment component )
            • 創建變量環境組件(VariableEnvironment component )
          • 執行階段:就是將執行上下文不斷的壓棧出棧進行執行

          如果看視頻或者上下文的文章,我們了解到執行上下文在創建階段所含的內容不同,如下圖所示,目前的ES6執行上下文也又發生了變化。但本質還是一樣的


          那詞法環境組件和變量環境組件是什么呢?

          • 詞法環境組件:包括環境記錄器和 outer,詞法環境的環境記錄器收集 let、const、class 等變量
          • 變量環境組件:包括環境記錄器和 outer,變量環境的環境記錄器收集 var、function 等變量

          詞法環境組件、變量環境組件和詞法環境的區別是什么呢?

          我的理解:本質上這兩個是一個東西,只是由于執行上下文它是一個JavaScript代碼的環境,記錄一些執行所需要的信息,因此創建一個變量來存儲前面已經有的詞法環境(作用域),這樣來保持運行。相當于在執行上下文創建的時候,除了 this,像變量環境、詞法環境在編譯階段就已經確定了,其中變量環境的變量 var、function 會進行變量、函數提升,并初始化,而詞法環境中的變量雖然提升了,但不會被初始化;而兩者的 outer 則相同,它們都指向父作用域。這個時候就會確定我們的作用域鏈,變量提升也在編譯的時候完成了。

          作用域與作用域鏈

          1、作用域到底是什么

          作用域是表示在哪里可以訪問到變量,其本質是一套規則,而這個規則的底層遵循的就是詞法作用域模型,即在詞法分析時生成的作用域,詞法分析階段,也可以理解為代碼書寫階段,當你把函數(塊級作用域同理)書寫到某個位置,不用執行,它的作用域就已經確定了。簡單來說,“詞法作用域”就是作用域的成因。

          從語言的層面來說,作用域模型分兩種:

          • 詞法作用域:也稱靜態作用域,是最為普遍的一種作用域模型
          • 動態作用域:相對“冷門”,bash腳本、Perl等語言采納的是動態作用域

          總結一下。詞法作用域和動態作用域最根本區別在于生成作用域的時機

          • 詞法作用域:在代碼書寫時完成劃分,作用域沿著它定義的位置往外延伸
          • 動態作用域:在代碼運行時完成劃分,作用域鏈沿著他的調用棧往外延伸

          JavaScript擁有詞法作用域,因此可以訪問到變量的規則是基于代碼中函數和塊被寫在哪里,也就是它是在編譯階段就確定了。

          2、作用域分類

          在JS中分為作用域分三種:

          • 全局作用域
          • 函數作用域
          • 塊作用域

          3、作用域鏈

          作用域鏈是把作用域層層嵌套,當查找一個變量在內部作用域中未找到,向上父作用域去查找,找不到接著找,一直找到全局作用域這樣的一個關系叫做作用域鏈。

          變量提升的出現

          變量提升的表象:使某些類型的變量在實際聲明之前就可以在代碼中訪問。“變量被提升到其作用域的頂部”。

          其深層的原因:在執行之前,掃描代碼以查找變量聲明,并在變量環境對象中為每個變量創建一個新屬性。這都是發生在執行上下文的創建階段。


          是否變量提升

          初始值

          作用域

          函數聲明

          ?是

          實際函數

          嚴格模式下:塊級作用域;非嚴格模式:函數作用域

          var聲明的變量

          ?是

          undefined

          函數作用域

          let、const聲明的變量

          ?否

          <uninitialized>(未初始化)、TDZ(暫時性死區)

          塊級作用域

          函數表達式、箭頭函數

          取決于使用var、const、let哪一個關鍵字



          理論上let和const關鍵字也會變量提升,但是它的初始值為未初始化,因此沒有任何用處,可以說是這些聲明的變量被置于暫時性死區(TDZ),這樣使得我們在作用域范圍最初到聲明變量的位置之間是無法訪問變量的,因此在聲明之前訪問會進行報錯,但在之后就可以正常訪問了。

          為什么會有暫時性死區?

          • 更加容易去避免bug和捕捉bug
          • 讓const關鍵字能夠正常使用:由于常量不能夠改變,因此不能進行初始化之后再來重新賦值,因此只在執行時分配值

          為什么會存在變量提升?

          • 在實際聲明之前可以調用函數,好處有:相互函數遞歸等
          • var關鍵字的變量提升是個副產品

          閉包內部

          1、閉包是什么

          在說閉包背后原理之前,我們先看看閉包是什么。

          閉包是內層函數能夠訪問外層函數聲明的變量,并且內層函數在全局環境下可訪問。

          這個解釋其實僅僅對閉包的現象進行解釋了一遍。

          真正的實際閉包,它背后是可以訪問附加到函數身上的變量環境,這樣的一個關系被稱之為閉包。

          任何函數都可以訪問到創建它的執行上下文當中的變量環境(詞法環境組件和變量環境組件),所有函數都有個[[Environment]] 的隱藏屬性,該屬性保存了對創建該函數的詞法環境的引用,[[Environment]] 引用在函數創建時被設置并永久保存。

          許多大神對閉包的定義都是去描述上方這句話。

          接下來我們看一下閉包的例子:

          2、舉例說明

          function foo() {
              var a = 1;
              var b = 2;
              return function bar() {
                  console.log(a++);
              };
          }
          var baz = foo();
          baz();
          • 在任何代碼執行之前,先創建全局執行上下文,并往調用棧中壓棧
          • 接著創建詞法環境,登記函數聲明 foo 和變量聲明 baz
          • 由于全局詞法環境沒有外部引用,所以箭頭指向了 null


          • 代碼開始執行,執行 foo(),創建 foo() 的函數執行上下文,并往調用棧中壓棧
          • 在開始執行 foo 函數內代碼前,創建 foo 的詞法環境,登記函數聲明 bar 和變量聲明 a、b。它的 outer 指向父作用域——全局作用域



          代碼執行至 function bar 時,創建 bar 的詞法環境,它沒有變量,outer 指向父作用域 foo

          • 所有函數在“誕生”時都會記住創建它們的詞法環境
          • 所有函數都有個[[Environment]] 的隱藏屬性,該屬性保存了對創建該函數的詞法環境的引用
          • 我們說過作用域與它創建于哪里相關,與在哪兒調用無


        1. 調用完函數 foo(),彈出調用棧,foo 中的函數 bar、變量 b 隨著 foo 出棧而被釋放
        2. 由于函數 bar 的結果賦值給了全局變量 baz,baz 相當于多個了隱藏屬性 [[Environment]],它指向父作用域 foo,而 bar 又引用了 foo 作用域下的變量 a,所以變量 a 無法被釋放
          • 因此,baz.[[Environment]] 有對 {a: 0} 詞法環境的引用
          • [[Environment]] 引用在函數創建時被設置并永久保存


          調用函數 baz(),創建 baz() 執行上下文,并將其壓入調用棧中

        3. 并在執行代碼前,創建一個新的詞法環境,并且它的 outer 指向 baz.[[Environment]] ,即父作用域 foo
        4. 當它查找變量 a 時,先在自己的詞法環境中找,找不到,沿著 outer 往它的父作用域找,在 foo 詞法環境中找到了變量 a,并在變量所在的詞法環境中更新變量

        5. 如此,調用完 baz,因為 baz 一直存在全局詞法環境中,它的隱藏屬性[[Environment]] 一直引用著 foo 函數中的 a 變量(即使 foo 函數已經被銷毀了)

          當再次調用 baz 時,就會再往調用棧中壓入baz(),并生成一個新的 bar 的詞法環境,它的 outer 還是引用 baz.[[Environment]],即上圖中的 foo 詞法環境。

          這里我們可以通過運行這段閉包代碼,打印baz函數,可以看見它含有的內部屬性[[scope]]里含有閉包(closures),保存引用。查看閉包的一個優先級大于作用域鏈

          總結

          到此,執行上下文作用域閉包三者的聯系串聯起來給大家講清楚,也分別介紹了三者是什么。

          最后用簡短的一句話分別描述一下這三個是什么:

          • 執行上下文:執行一段JavaScript代碼的環境
          • 作用域:在哪里可以訪問到變量
          • 閉包:內層函數能訪問外層函數變量環境

          這是我根據自行閱讀文章和視頻總結出來的個人理解,如有不正確的地方歡迎大家進行指正。


          主站蜘蛛池模板: 国产一区二区三区乱码网站| 亚洲av鲁丝一区二区三区| 国产一区二区三区在线影院 | 精品视频一区二区| 久久婷婷久久一区二区三区| 国产精品美女一区二区三区 | 中文字幕一区二区三区视频在线| 亚洲国产精品综合一区在线| 日韩一区二区在线免费观看| 亚洲综合色自拍一区| 日韩美一区二区三区| 97久久精品无码一区二区| 精品国产一区二区三区2021| 久久精品国产AV一区二区三区| 亚洲熟妇无码一区二区三区导航| 欧美日韩综合一区二区三区| 国模私拍一区二区三区| 久久精品免费一区二区喷潮| 末成年女A∨片一区二区| 99精品国产一区二区三区不卡| 日韩精品一区二区午夜成人版| 日韩av片无码一区二区三区不卡| 亚洲AV无码一区二区三区国产| 成人无码AV一区二区| 最新中文字幕一区| 在线精品亚洲一区二区小说| 性色AV一区二区三区| 无码喷水一区二区浪潮AV| 精品亚洲一区二区| 动漫精品第一区二区三区| 丰满少妇内射一区| 福利一区二区三区视频午夜观看| 少妇激情AV一区二区三区| 国产一区二区精品久久91| 国产视频一区二区在线播放| 韩国福利视频一区二区 | 国产伦精品一区二区三区无广告| 国产不卡视频一区二区三区| 国产精品视频一区国模私拍| 99精品国产高清一区二区麻豆| 色偷偷一区二区无码视频|