整合營銷服務商

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

          免費咨詢熱線:

          從小白到專家:JavaScript 延展操作符的幾個基本用法

          文共5530字,預計學習時長11分鐘



          延展操作符首次于ES6中引入,并很快成為最受歡迎的功能之一。盡管事實上延展操作符只適用于數組,但仍有建議提出可以將其功能擴展到對象。最終ES9中引入了此功能。

          本教程將說明為什么應該使用擴展運算符,以及它如何運作。



          目錄


          1.為什么要使用延展操作符

          2.克隆數組/對象

          3.將類數組結構轉換為數組

          4.延展操作符作為參數

          5.將元素添加到數組/對象

          6.合并數組/對象


          為什么要使用延展操作符


          閱讀了以上列表之后,你可能會想:“JavaScript就已經能夠滿足需求了,為什么還要使用延展操作符?”我們先來介紹下不變性。

          牛津詞典:不變性 - 隨著時間的推移不變或無法改變。

          作為軟件開發的術語,不可變指狀態不能隨時間變化的值。實際上,通常使用的大多數值(原始值,如字符串,整數等)都是不可變的。

          然而,JavaScript中非常特殊的一點是,其中的數組和對象實際上是可變的。這可能成為一個大問題。以下實例闡明了其中原因:

          const mySquirtle={
          name: 'Squirtle',
           type: 'Water',
           hp: 100
          };
          const anotherSquirtle = mySquirtle;
          anotherSquirtle.hp = 0;
          console.log(mySquirtle); //Result: { name: 'Squirtle', type: 'Water', hp: 0 }
          


          從上述代碼中可以看到,我們有一個變量Squirtle(杰尼龜)。因為剛剛訪問了神奇寶貝中心,這只杰尼龜的HP值為100。

          由于還想要另一只杰尼龜,因此聲明變量為anotherSquirtle,將初始Squirtle指定為它的值。一場苦戰后,另一只杰尼龜被擊敗了。因此,訪問另一只杰尼龜的HP值并將其更改為0。下一步,檢查初始Squirtle,輸入console.log和...

          等等,什么?初始Squirtle的HP降至0。這怎么可能?可憐的杰尼龜遭遇了什么?原來是發生了JavaScript變異。接下來將為你解釋其中緣由。

          當創建anotherSquirtle變量并將初始Squirtle指定為其值時,實際是給初始Squirtle對象的內存位置分配了一個引用。這是因為JavaScript數組和對象是引用數據類型。與基本數據類型不同,引用數據類型指向存儲實際對象/數組的內存地址。

          為了便于理解,可以將引用數據類型想象為全局變量的指針。更改引用數據類型的值實際上是在更改全局變量的值。

          這意味著當將anotherSquirtle的HP值更改為0時,實際是將存儲在內存中的Squirtle對象的HP值更改為0。這就是為什么mySquirtle的HP值為0 - 因為mySquirtle是對存儲在內存中的對象的引用,可以通過anotherSquirtle變量被改變。謝謝JavaScript。

          如何解決這個問題?

          為了避免變量的變異,需要在要復制數組/對象時,創建數組/對象實例。如何實現這一操作?

          使用延展操作符。


          延展操作符如何運作


          從MDN文檔中可以查到:展開語法(spread syntax),可以在函數調用或數組構造時,將數組表達式或string等iterable在語法層面展開,還可以在構造字面量對象時,將對象表達式按鍵-值方式展開。

          簡而言之,延展操作符......延展iterable中的項(iterable指receiver中任何可循環的項,如字符串,數組,集等)。(receiver用于接收展開值。)為便于理解,以下是數組的簡單示例:

          const numbers = [1, 2, 3];
          console.log(...numbers); //Result: 1 2 3
          const pokemon = ['Squirtle', 'Bulbasur', 'Charmander'];
          console.log(...pokemon); //Squirtle Bulbasur Charmander
          const pokedex = [
           { name: 'Squirtle', type: 'Water' },
           { name: 'Bulbasur', type: 'Plant' },
           { name: 'Charmander', type: 'Fire' }
          ];
          console.log(...pokedex); //{ name: 'Squirtle', type: 'Water' } { name: 'Bulbasur', type: 'Plant' } { name: 'Charmander', type: 'Fire' }
          import pandas as pd
          


          數組中使用延展操作符的三個示例


          如上所示,當在數組上使用延展操作符時,可以獲取數組中所含的每個單獨的項。在上述所有示例中,receiver都是一個函數,即console.log函數。夠簡單吧?


          克隆數組/對象


          現在已經知道了延展操作符的工作原理,可以利用它復制數組和對象而不改變其值。怎么做呢?延展內容然后使用數組[]或對象文字{}來生成數組/對象實例。

          仍然以上文的杰尼龜為例,通過克隆mySquirtle變量解決上文中的問題:

          const mySquirtle = {
           name: 'Squirtle',
           type: 'Water',
           hp: 100
          };
          const anotherSquirtle = { ...mySquirtle };
          anotherSquirtle.hp = 0;
          console.log(anotherSquirtle); //Result: { name: 'Squirtle', type: 'Water', hp: 0 }
          console.log(mySquirtle); //Result: { name: 'Squirtle', type: 'Water', hp: 100 }
          

          使用延展操作符復制對象


          通過使用解延展操作符解構mySquirtle變量內容并使用對象字面量,創建了Squirtle對象的新實例。這樣,就防止變量突然變異。

          使用相同的語法復制數組:

          const pokemon = ['Squirtle', 'Bulbasur', 'Charmander'];
          const pokedex = [...pokemon];
          pokedex.push('Cyndaquil');
          console.log(pokemon); //[ 'Squirtle', 'Bulbasur', 'Charmander' ]
          console.log(pokedex); //[ 'Squirtle', 'Bulbasur', 'Charmander', 'Cyndaquil' ]
          


          使用延展操作符復制數組

          注意:延展操作符只執行淺拷貝。這意味著若在數組/對象中存儲了引用數據類型,則在使用延展操作符進行復制時,嵌套數組/對象將包含對原始的引用,因此其數值將是可變的。


          將類數組對象轉換為數組


          類數組對象與數組非常相似。它們通常都有編號元素和長度屬性。但是,兩者有一個至關重要的區別:類數組對象沒有任何數組函數。

          類數組對象包含主要由DOM方法返回的HTML節點列表,和每個JS函數和少部分其他函數自動生成的參數變量。

          使用與克隆數組相同的語法,可以使用延展操作符將類數組結構轉換為數組,這可以代替使用Array.from的方法。以下是將nodeList轉換為數組的示例:

          const nodeList = document.getElementsByClassName("pokemon");
          const array = [...nodeList];
           
          console.log(nodeList); //Result: HTMLCollection [ div.pokemon, div.pokemon ]
          console.log(array); //Result: Array [ div.pokemon, div.pokemon ]
          


          將nodelist轉換為數組

          使用這種技術,可以將任何類數組結構轉換為數組,從而訪問所有數組函數。


          延展操作符用作參數


          某些函數接受可變數量的參數。其中一個典型列子就是Math集合中的函數。以Math.max()函數為例。它接受n個數字參數,并返回最大的參數。假設需要將一個數字數組傳遞給Math.max()函數。該怎么做呢?

          可以這樣做:

          const numbers = [1, 4, 5];
          const max = Math.max(numbers[0], numbers[1], numbers[2]);
          console.log(max); //Result: 5
          


          但是,這樣做無疑是自尋死路。若是有20個值怎么辦?1000個值呢?真的要通過索引訪問每個值嗎?當然不是。我們可以通過使用延展操作符提取數組中每個單獨的值,如下所示:

          const numbers = [1, 4, 5, 6, 9, 2, 3, 4, 5, 6];
          const max = Math.max(...numbers);
          console.log(max); //Result: 9
          


          大救星:延展操作符。


          添加新元素


          將項添加到數組

          向數組添加新元素,首先需要延展數組的內容并使用數字字面量[]創建數組實例,需要包含原始數組的內容以及要添加的值:

          const pokemon = ['Squirtle', 'Bulbasur'];
          const charmander = 'Charmander';
          const cyndaquil = 'Cyndaquil';
          const pokedex = [...pokemon, charmander, cyndaquil];
          console.log(pokedex); //Result: [ 'Squirtle', 'Bulbasur', 'Charmander', 'Cyndaquil' ]
          


          使用延展操作符將項添加到數組中


          如你所見,可以任意添加新項。

          向對象添加屬性

          通過使用與數組相同的語法,可以在克隆對象時輕松添加新屬性。稍微轉變一下,就有一個不同的語法來向對象添加屬性(也可以用于數組):

          const basicSquirtle = { name: 'Squirtle', type: 'Water' };
          const fullSquirtle = {
           ...basicSquirtle,
           species: 'Tiny Turtle Pokemon',
           evolution: 'Wartortle'
          };
          console.log(fullSquirtle); //Result: { name: 'Squirtle', type: 'Water', species: 'Tiny Turtle Pokemon', evolution: 'Wartortle' }
          


          如你所見,可以在對象字面量中而不是在外部直接聲明和初始化新變量。


          合并數組/對象


          數組

          如上述例子所示,可以通過延展數組并使用數組字面量來合并兩個數組。但是,這一部分要講的不是簡單地添加新元素,而是添加另一個(延展)數組:

          const pokemon = ['Squirtle', 'Bulbasur', 'Charmander'];
          const morePokemon = ['Totodile', 'Chikorita', 'Cyndaquil'];
          const pokedex = [...pokemon, ...morePokemon];
          console.log(pokedex); //Result: [ 'Squirtle', 'Bulbasur', 'Charmander', 'Totodile', 'Chikorita', 'Cyndaquil' ]
          

          使用延展操作符合并數組

          這也適用于數組對象:

          const pokemon = [ { name: 'Squirtle', type: 'Water' }, { name: 'Bulbasur', type: 'Plant' }];const morePokemon = [{ name: 'Charmander', type: 'Fire' }]; const pokedex = [...pokemon, ...morePokemon]; console.log(pokedex); //Result: [ { name: 'Squirtle', type: 'Water' }, { name: 'Bulbasur', type: 'Plant' }, { name: 'Charmander', type: 'Fire' } ]Merging two arrays of objects with the spread operator
          


          對象

          可以使用與之前相同的語法將兩個(或更多)對象合并到一個對象中(你可能已經留意到,擴展運算符在數組和對象中的使用方式非常相似):

          const baseSquirtle = {
           name: 'Squirtle',
           type: 'Water'
          };
          const squirtleDetails = {
           species: 'Tiny Turtle Pokemon',
           evolution: 'Wartortle'
          };
          const squirtle = { ...baseSquirtle, ...squirtleDetails };
          console.log(squirtle); //Result: { name: 'Squirtle', type: 'Water', species: 'Tiny Turtle Pokemon', evolution: 'Wartortle' }
          


          使用延展操作符合并對象

          本教程說明了為什么應該使用擴展運算符(重點強調不變性!),它是如何工作的以及幾個基本用法。


          留言 點贊 關注

          我們一起分享AI學習與發展的干貨

          如需轉載,請后臺留言,遵守轉載規范

          篇文章JavaScript基礎——你真的清楚JavaScript是什么嗎?,我們明白了JavaScript是一個單線程、非阻塞、異步、解釋性語言,清楚了什么是單線程、進程、阻塞、調用堆棧、異步回調、任務循環等感念,沒看的或者不清楚的建議點擊《JavaScript基礎——你真的清楚JavaScript是什么嗎?再看一遍,只有理解了,才能輕松閱讀理解本篇文章內容。

          什么是callback?

          JavaScript 是單線程工作,這意味著兩段腳本不能同時運行,而是必須一個接一個地運行。我們人類是多線程工作。您可以使用多個手指打字,可以一邊開車一邊與人交談。唯一一個會妨礙我們的是打噴嚏,因為當我們打噴嚏的時候,所有當前進行的活動都必須暫停。這真是非常討厭,尤其是當您在開車并想與人交談時。您可不想編寫像打噴嚏似的代碼。JavaScript由于單線程限制,防止阻塞,只能通過異步函數的調用方式,把需要延遲處理的事件放入事件循環隊列。到目前為止,回調是編寫和處理JavaScript程序異步邏輯的最常用方式。說了這么多,既然回調這么重要,到底什么是回調(callback)呢?

          簡單的定義:回調就是一個在另外一個函數執行完后要執行的函數

          復雜的定義:在JavaScript中,函數是對象。因此函數可以將函數作為參數,并且可以由其他函數進行返回。執行此操作的函數稱為高階函數。任何作為參數傳遞的函數都稱為回調函數。

          為什么需要回調?

          開篇已經介紹了JavaScript是單線程的,需要通回調函數處理異步相關的邏輯,理論還是過于生硬,我們還是來看段代碼吧:

          function first(){
          console.log(1);
          }
          function second(){
          console.log(2);
          }
          first();
          second();
          

          正如你所料,先執行first函數,再執行second函數,控制臺將輸出以下內容:

          1
          2
          

          目前看來沒什么問題,如果first()函數中含有某種無法立即執行的函數呢?例如,我們必須發送請求然后等待結果響應的API請求?為了模擬API請求,我們可以使用setTimeout函數模擬。我們將函數延遲500毫秒來模擬請求,我們更改后代碼如下:

          function first(){
          // Simulate a code delay
          setTimeout( function(){
          console.log(1);
          }, 500 );
          }
          function second(){
          console.log(2);
          }
          first();
          second();
          

          我們將 console.log(1) 延遲500毫秒輸出,這段代碼會怎么輸出呢?

          2
          1
          

          我們希望的順序先執行first,再執行second,但是由于JavaScript是異步的,所有的延遲處理都要放入循環隊列里,因此事與愿違,不能按照我們的希望順序輸出。如果希望這段代碼按照我們的意愿輸出,我們可以使用回調函數,確保某些代碼執行完了,在循序執行另外一段代碼。

          創建回調

          說了這么多,讓我們創建一個簡單的回調!

          我們打開編輯器,先輸入如下代碼:

          function doHomework(subject) {
          alert(`Starting my ${subject} homework.`);
          }
          

          上面我們創建了doHomeWork的函數,我們接受一個變量,通過控制臺調用,將得到下面的提示:

          doHomework('math');
          // Alerts: Starting my math homework.
          

          接著,我們開始添加回調,在doHomework函數中添加一個參數callback,然后在第二個參數中回調我們定義的函數。代碼如下:

          function doHomework(subject, callback) {
          alert(`Starting my ${subject} homework.`);
          callback();
          }
          doHomework('math', function() {
          alert('Finished my homework');
          });
          

          正如你希望的,我們在控制臺里運行上述代碼,將會受到兩個連續的alert,Starting my math homework,然后彈出 Finished my homework。

          但是回調函數并不是非得在調用函數中定義,我們可以單獨定義,修改后的代碼如下:

          function doHomework(subject, callback) {
          alert(`Starting my ${subject} homework.`);
          callback();
          }
          function alertFinished(){
          alert('Finished my homework');
          }
          doHomework('math', alertFinished);
          

          此示例的輸出結果和上段代碼的結果一致,我們實現了在doHomework函數中調用alertFinished,實現了函數作為參數進行傳遞,實現了回調函數的創建。

          用回調寫一段真實業務場景的代碼!

          例如我們有一個需求,用NodeJs實現從論壇帖子列表中顯示其中的一個帖子的信息及留言列表信息,代碼如下:

          DB/posts.json(帖子列表數據)

          [
          {
          "id": "001",
          "title": "Greeting",
          "text": "Hello World",
          "author": "Jane Doe"
          },
          {
          "id": "002",
          "title": "JavaScript 101",
          "text": "The fundamentals of programming.",
          "author": "Alberta Williams"
          },
          {
          "id": "003",
          "title": "Async Programming",
          "text": "Callbacks, Promises and Async/Await.",
          "author": "Alberta Williams"
          }
          ]
          

          DB/comments.json(評論列表)

          [
          {
          "id": "phx732",
          "postId": "003",
          "text": "I don't get this callback stuff."
          },
          {
          "id": "avj9438",
          "postId": "003",
          "text": "This is really useful info."
          },
          {
          "id": "gnk368",
          "postId": "001",
          "text": "This is a test comment."
          }
          ]
          

          Index.js

          const fs = require('fs');
          const path = require('path');
          const postsUrl = path.join(__dirname, 'db/posts.json');
          const commentsUrl = path.join(__dirname, 'db/comments.json');
          //return the data from our file
          function loadCollection(url, callback) {
          fs.readFile(url, 'utf8', function(error, data) {
          if (error) {
          console.log(error);
          } else {
          return callback(JSON.parse(data));
          }
          });
          }
          //return an object by id
          function getRecord(collection, id, callback) {
          var collectobj=collection.find(function(element){
          return element.id == id;
          });
          callback(collectobj);
          return collectobj;
          }
          //return an array of comments for a post
          function getCommentsByPost(comments, postId) {
          return comments.filter(function(comment){
          return comment.postId == postId;
          });
          }
          loadCollection(postsUrl, function(posts){
          loadCollection(commentsUrl, function(comments){
          getRecord(posts, "001", function(post){
          const postComments = getCommentsByPost(comments, post.id);
          console.log(post);
          console.log(postComments);
          });
          });
          });
          

          大家請注意,我們在loadCollection函數中我們沒有使用try/catch,使用的是if/else,因為catch無法從readFile方法中獲取錯誤。上述代碼還需要完善,我沒有包含任何錯誤處理。如果在任何步驟中發生錯誤,程序將無法繼續。

          錯誤處理是很重要的事情,我們寫代碼時要嚴格對待,比如我們要編寫一個用戶登錄的功能。涉及從網頁表單里獲取用戶名和密碼,查詢我們的數據庫,確認用戶信息是否正確,驗證通過后,將用戶引導到用戶中心頁面。如果用戶名密碼格式不正確,用戶名密碼不正確,我們應該將錯誤信息返回給用戶,并引導用戶重新登錄。

          總結

          很好!我們一起把回調的內容學完了,理解了什么是回調,異步編程是我們的代碼中使用的一種方法,用于推遲事件以便以后執行。當您處理異步任務時,回調是一種解決方案,以便它們按順序執行。

          如果我們有多個任務依賴于前幾個任務的結果,那我們就要使用多個嵌套回調,但是就會引發“回調地域”(過多的回調嵌套會使得代碼變得難以理解與維護),還好Promise解決了“回調地獄”的問題,讓我們以同步的方式編寫代碼,小編將會再下篇文章里進行詳細介紹,敬請期待!

          更多精彩內容,請微信關注”前端達人”公眾號

          JavaScript、CSS 相比,HTML 經過三十多年的發展,似乎逐漸走進無人問津的角落,如何才能讓 HTML 再次回到人們視野的中心。

          作者 | Yaser Adel Mehraban

          譯者 | 譚開朗,責編 | 屠敏

          出品 | CSDN(ID:CSDNnews)

          以下為譯文:

          有多少次,身為開發者的你編寫了一個HTML塊而沒有意識到可能編碼得并不理想?

          為什么

          HTML一直處于無人問津的角落,因為JavaScript和CSS總是吸引人們的注意力。

          請在腦海里先保留這種印象,因為我要用一些簡單的技巧來發揮作用,讓HTML再次回到人們視野的中心。

          以下是創建一目了然、可維護和可擴展的代碼的一些方法,其很好的應用了HTML5的語義標記元素,并將在支持的瀏覽器中正確呈現。

          其緣由就不贅述了,讓我們來看看具體是什么吧。

          文檔類型

          在index.html的頂部位置,請確保聲明了DOCTYPE。這將在所有瀏覽器中激活標準模式,并告知瀏覽器該如何編譯文檔。請記住DOCTYPE不是HTML元素。

          HTML5是這樣的:

          <!DOCTYPE html>

          注意:如果應用了框架,這已預先寫好。如果沒有,我強烈建議使用像Emmet這樣的代碼片段,它在VS代碼中可用。

          了解更多關于其他文檔類型的信息嗎?點擊這里查看參考文件:https://html.com/tags/doctype/。

          可選標簽

          有些標簽在HTML5中是可選的,主要是因為元素是隱式呈現的。信不信由你,你可以省略<html>標簽,而頁面呈現得也很好。

          <!DOCTYPE HTML>

          <head>
          <title>Hello</title>
          </head>
          <body>
          <p>Welcome to this example.</p>
          </body>
          </html>

          上面是一個有效的HTML,但在某些情況下就不能這樣做了。例如標簽后面跟著注釋:

          <!DOCTYPE HTML>
          <!-- where is this comment in the DOM? -->

          <head>
          <title>Hello</title>
          </head>
          <body>
          <p>Welcome to this example.</p>
          </body>
          </html>

          上面是無效的,因為注釋位于<thml>標簽之外,解析樹發生了更改。

          結束標簽

          應始終記得結束標簽,否則某些瀏覽器在呈現頁面時會出現問題。出于可讀性和其他原因,建議保留這些內容,稍后我會詳細介紹。

          <div id="example">
          <img src="example.jpg" alt="example" />
          <a href="#" title="test">example</a>
          <p>example</p>
          </div>

          以上都是有效的標簽,但也有一些特例,如下。

          自閉合標簽是有效的,但不是必需的。這些元素包括:

          <br>, <hr>, <img>, <input>, <link>, <meta>,
          <area>, <base>, <col>, <command>, <embed>, <keygen>, <param>, <source>, <track>, <wbr>

          注意:普通元素永遠不能有自閉合標簽。

          <title />

          上面顯然是無效的。

          字符集

          預先定義字符集。最好是將它放在頂部元素中。

          <head>
          <title>This is a super duper cool title, right ?</title>
          <meta charset="utf-8">
          </head>

          上面是無效的,標題無法正確呈現。正確寫法是將字符集移到頂部位置。

          <head>
          <meta charset="utf-8">
          <title>This is a super duper cool title, right ?</title>
          </head>

          語言

          不忽略可選標簽的另一個原因是在使用屬性時。在這種情況下,我們應該定義web頁面的語言,這對于可訪問性和搜索非常重要。

          <html lang="fr-CA">
          ...
          </html>

          標題

          永遠不要忽略標題標簽,否則可訪問性太差了。我個人就永遠不會使用這樣的網站,因為我剛打開它即刻在20多個頁面后就找不到了(瀏覽器選項卡不會有任何顯示)。

          base標簽

          這是一個非常有用的標簽,應該謹慎使用。它將設置應用程序的基本URL。一旦設置好,所有鏈接都將相對于這個基本URL,這可能會導致一些不必要的行為:

          <base href="http://www.example.com/" />

          通過以上設置,href="#internal"將被編譯為href=http://www.example.com/#internal。或者href="example.org"將被編譯為href="http://www.example.com/example.org"。

          描述

          這個meta標簽非常有用,盡管嚴格來說它不是最佳寫法。但在搜索引擎時,這是超級有用的。

          <meta name="description" content="HTML best practices">

          這有一個帖子“搜索引擎優化正盛行”:https://yashints.dev/blog/2019/06/11/seo-tips。

          語義標簽

          雖然可以使用div創建UX工程師的線框,但這并不意味著必須這樣做。語義HTML為頁面提供了意義,而不單純是內容顯示。像p、section、h{1-6}、main、nav等標簽都是語義標簽。如果使用p標簽,用戶將知道這表示一段文本,瀏覽器也知道如何展示它們。

          語義HTML超出了本文的范圍。但是我們應該進行檢查,就好比寫作所用的筆,而我們有鼠標。

          hr不應該用于格式化

          <hr>不是格式化元素,所以不要用它來格式化內容。在HTML5中,這個標簽代表了內容的主題分離。正確的用法是這樣的:

          <p>Paragraph about puppies</p>
          <p>Paragraph about puppies' favourite foods</p>
          <p>Paragraph about puppies' breeds</p>
          <hr>
          <p>Paragraph about why I am shaving my head </p>

          使用title屬性時要小心

          title屬性是一個功能強大的工具,它可以幫助闡明頁面上元素的操作或目的,比如工具提示。但是,它不能與圖像上的alt等其他屬性互換。

          HTML 5 規范道:

          目前不鼓勵依賴title屬性,因為很多用戶代理不按照規范的訪問方式來暴露該屬性(例如,使用鼠標等設備來喚出提示框,而不包括只用鍵盤或觸控鍵盤的用戶,或者現代手機或平板電腦)。

          請閱讀有關如何正確使用此屬性的更多信息:https://html.spec.whatwg.org/multipage/dom.html#the-title-attribute。

          單引號或雙引號

          我見過的許多代碼庫,他們的標記中混合了這兩種形式。這并不好,特別是當你使用一個依賴于單引號的框架時,比如php,當你在一個句子中使用單引號時,就像我現在做的一樣。另一個原因是保持一致,這總是好的。不要這樣寫:

          <img alt="super funny meme" src='/img/meme.jpg'>

          而寫為:

          <img alt="super funny meme" src="/img/meme.jpg">

          省略布爾值

          當涉及到屬性的布爾值時,建議省略,因為它們不添加任何值,還會增加標記的權重。

          public class MyActivity extends AppCompatActivity {
          <audio autoplay="autoplay" src="podcast.mp3">

          <!-- instead -->

          <audio autoplay src="podcast.mp3">

          省略類型屬性

          不需要向scriptand樣式標簽添加type屬性。某些服務(如W3C的標記驗證工具)還會出現驗證錯誤。

          驗證標記

          可以使用W3C的標記驗證等服務以確保有效的標記。

          拒絕內聯樣式

          HTML中寫的是內容,其如何展示取決于樣式。將展示形式留給CSS吧,不要使用內聯樣式,這將有利于開發人員和瀏覽器理解你的標記。

          總結

          這些只是編寫標簽時要記住的冰山一角。還有很多很好的資源可以讓你深入了解,強烈建議你重復閱讀。

          • 《GitHub HTML最佳實踐》:https://github.com/hail2u/html-best-practices

          • 《W3C School HTML樣式指南》:https://www.w3schools.com/html/html5_syntax.asp

          希望你喜歡本文,并能寫出優雅的標簽。

          原文:https://dev.to/yashints/let-s-write-html-like-a-pro-28h5

          本文為 CSDN 翻譯,轉載請注明來源出處。

          【END】


          主站蜘蛛池模板: 国产精品一区二区无线| 国产区精品一区二区不卡中文 | 亚洲AV美女一区二区三区| 亚洲免费一区二区| 成人精品一区二区不卡视频| 亚州AV综合色区无码一区| 人妻在线无码一区二区三区| 男人的天堂av亚洲一区2区| 日本精品一区二区三区视频| 区三区激情福利综合中文字幕在线一区 | 久久久91精品国产一区二区三区 | 国产主播福利一区二区| 韩国女主播一区二区| 无码人妻精品一区二区三区99不卡| 久久se精品一区二区影院| 久久无码人妻一区二区三区午夜| 成人免费视频一区| 亚洲日韩激情无码一区| 波多野结衣一区视频在线| 国产一区二区视频在线观看| 日韩精品无码一区二区三区四区| 人妖在线精品一区二区三区| 亚洲熟女乱综合一区二区| 91video国产一区| 日本一区精品久久久久影院| 亚洲精品伦理熟女国产一区二区| 中文字幕一区二区免费| 国产伦精品一区二区三区无广告| 乱子伦一区二区三区| 国产高清精品一区| 亚洲欧美日韩中文字幕在线一区| 国产熟女一区二区三区四区五区| 春暖花开亚洲性无区一区二区| 亚洲国产精品无码久久一区二区| 日韩视频在线观看一区二区| 亚洲欧洲无码一区二区三区| 亚洲国产高清在线精品一区| 国产一区二区高清在线播放| 无码日韩精品一区二区人妻| 国产成人一区二区动漫精品| 影院成人区精品一区二区婷婷丽春院影视|