成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

前端中的那些 This vs That,你知道嗎?

開發(fā) 前端
前端中還有很多相近的概念和 API,在業(yè)務(wù)開發(fā)時可能沒時間去了解,但是有空的時候還是可以花點時間去掌握其中的異同,扎實自己的前端基礎(chǔ)。

前端知識中有很多相近的概念或 API,相信不少人在開發(fā)中有注意到這些相近的概念或 API,但是有時不會深入去了解異同,只要某個 API 能滿足開發(fā)需求即可。

本文將介紹一些相近的概念和 API,讓你能更清晰地了解它們的異同,在使用時更游刃有余。

1. cookie vs localStorage vs sessionStorage

前端開發(fā)中,這三個本地存儲方案可以說是很常見的,用一張圖說明下它們的區(qū)別:

comparison-tablecomparison-table

圖片來源:local-storage-vs-session-storage-vs-cookies[1]

圖中從存儲大小、是否自動過期、服務(wù)端是否可以獲取、是否支持 HTTP 請求傳輸和數(shù)據(jù)持久性方面進行對比。除了圖中幾個部分,在作用域方面,cookie 由域名和路徑?jīng)Q定,localStorage 和 sessionStorge 都是遵守同源策略。

最后再提幾個關(guān)于在使用 sessionStorage 的時偶爾會陌生的知識點:

  1. sessionStorage 數(shù)據(jù)在各個直接打開的瀏覽器頁簽中是不會同步的,這意味著你打開了兩個同域名的網(wǎng)站,在其中一個設(shè)置了 sessionStorage 數(shù)據(jù),另一個頁面是不會同步這個數(shù)據(jù)的(而 localStorage 會),也就是說 sessionStorage 除了關(guān)閉瀏覽器時不會保留數(shù)據(jù),各個頁簽數(shù)據(jù)的同步也和 localStorage 不一樣。
  2. 如果你在當(dāng)前頁設(shè)置了一些 sessionStorage 數(shù)據(jù),然后通過 window.open 或 <a> 標(biāo)簽打開,新頁簽會同步一份當(dāng)前頁副本,隨后兩個頁簽的 sessionStorage 又會是獨立的,不過要注意打開新頁簽的 rel 屬性(用于指定當(dāng)前文檔與被鏈接文檔的關(guān)系)要設(shè)置為 opener。

圖片圖片

2. querySelectorAll vs getElementsByTagName

querySelectorAll 可以根據(jù)傳入的 CSS 選擇器查找 HTML 元素,使用上比 getElementsByTagName 更靈活。

它們之間的不同點在于:querySelectorAll 返回的是一個靜態(tài)的 NodeList,而 getElementsByTagName 返回的是動態(tài)的。

來看下面這個示例:

<ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
</ul>

接下來使用兩個方法獲取 li 元素類數(shù)組,然后再動態(tài)插入一個 li,最后查看兩個類數(shù)組的長度。

const listItems = document.querySelectorAll('li');
const listItems2 = document.getElementsByTagName('li');
console.log(listItems.length, listItems2.length);  // 3,3

const list = document.querySelector('ul');
const li = document.createElement('li');
li.innerHTML = '4';
list.appendChild(li);

console.log(listItems.length, listItems2.length);  // 3, 4

可以看到 querySelectorAll 方法獲取的類數(shù)組長度在動態(tài)添加 li 后還是 3,而 getElementsByTagName 的為 4。

常用的獲取元素方法中g(shù)etElementsByClassName 方法、element.childNodes 和 element.children 返回的也是動態(tài) NodeList。

3. children vs childNodes

children 和 childNodes 都可以用來獲取元素的子節(jié)點,不同的是 children 只會獲取 HTML 元素節(jié)點,而 childNodes 會獲取到非 HTML 元素節(jié)點,包括文本、注釋節(jié)點等。

<ul>
    <!-- 這里有有些內(nèi)容 -->
    <li>A</li>
    <li>B</li>
    <li>C</li>
</ul>
const parent = document.querySelector('ul');
// 輸出 HTMLCollection(3) [li, li, li]
console.log(parent.children)
// 輸出 NodeList(10) [text, comment, text, text, li, text, li, text, li, text]
console.log(parernt.childNodes)

4. microtasks vs macrotasks

宏任務(wù)和微任務(wù)概念也經(jīng)常在前端中出現(xiàn),與之相關(guān)的就是事件循環(huán)機制。事件循環(huán)機制是必須掌握的,宏任務(wù)和微任務(wù)也可以了解下,實際開發(fā)中碰到相關(guān)問題能反應(yīng)過來是宏任務(wù)和微任務(wù)的不同即可。

宏任務(wù)包括:

  • setTimeout and  setInterval 的回調(diào)
  • DOM 操作
  • I/O 操作 (Node 中讀寫文件)
  • requestAnimationFrame

微任務(wù)包括:

  • Promises 的 resolve 和 reject
  • MutationObserver 回調(diào)
  • Node 中的 process.nextTick

事件循環(huán)機制如下圖:

圖片圖片

宏任務(wù)微任務(wù)執(zhí)行順序如下圖:

圖片圖片

最后配合一個例子看下效果:

console.log('Script start')

setTimeout(function () {
  console.log('setTimeout')
}, 0)

new Promise((resolve) => {
  console.log('Promise')
}).then(function () {
  console.log('Promise then')
})

console.log('Script end')

// 輸出順序為: Script start、Promise、Script end、Promise then、setTimeout

一個更清晰的圖(源[2]):

圖片圖片

5. setTimeout(0) vs requestAnimationFrame

setTimeout(0) 和 requestAnimationFrame 都能把代碼延遲到下一個動畫幀運行,它們的不同在于:

  • setTimeout(0) 將代碼推到事件循環(huán)的任務(wù)隊列中,如果任務(wù)隊列中有大量任務(wù),setTimeout(0) 就不會立即執(zhí)行。
  • requestAnimationFrame 會在下一次渲染前執(zhí)行,而不是在事件循環(huán)中執(zhí)行,它能自動與顯示器刷新率同步。不過,它只有在瀏覽器準(zhǔn)備好渲染新幀時才會執(zhí)行,如果標(biāo)簽頁處于非激活狀態(tài),它就不會運行。

處理動畫時,requestAnimationFrame 更合適, 如果你要延遲執(zhí)行代碼的話,可以直接使用 setTimeout(0)。

補充一個小點:setTimeout 的語法是  setTimeout(functionRef, delay, param1, param2, /* … ,*/ paramN),除了回調(diào)函數(shù)和延遲時間,后續(xù)參數(shù)都會作為回調(diào)函數(shù)的參數(shù)。

// 1 秒后輸出 delay 1s
setTimeout(console.log, 1000, 'delay 1s')

6. naturalWidth vs width

naturalWidth 是元素的自然寬度,它永遠(yuǎn)不會改變。例如,一張 100px 寬的圖片的 naturalWidth 始終是 100px,即使通過 CSS 或 JavaScript 調(diào)整圖片大小后也不變。

而 width 是可以改變的,可以通過 CSS 或 JavaScript 設(shè)置。

圖片圖片

7. stopImmediatePropagation vs stopPropagation

stopImmediatePropagation() 方法與 stopPropagation() 方法一樣,可阻止事件冒泡。但是,stopImmediatePropagation() 方法會阻止元素同一事件的其他監(jiān)聽器。

button.addEventListener('click', function () {
  console.log('foo')
})

button.addEventListener('click', function (e) {
  console.log('bar')
  e.stopImmediatePropagation()
})

button.addEventListener('click', function () {
  console.log('baz')
})

上面代碼中按鈕點擊后只會輸出 foo and bar,baz 的事件監(jiān)聽函數(shù)不會觸發(fā)。

8. HTML 字符實體 vs Unicode 字符

HTML 實體是特殊字符序列,用來表示可能被誤認(rèn)為是 HTML 代碼的字符,如小于號 (<) 或雙引號 (&)。

下面是一些常見的 HTML 實體:

  • &lt; 代表小于號 <
  • &gt; 代表大于號 >
  • &amp; 代表于符號 &
  • &quot; 代表雙引號 "
  • &apos; 或 &#39; 代表單引號 '
  • &nbsp; 代表空格

HTML 字符實體相比 Unicode 字符會更好記些,同時瀏覽器對 HTML 字符實體支持更好。

Unicode 是表示字符或符號的特定代碼,它們用于顯示標(biāo)準(zhǔn)字符集中可能沒有的字符,如非拉丁字母或特殊符號。

一些 Unicode 字符示例:

  • \u00A9 表示版權(quán)符號 (?)
  • \u2192 表示右箭頭 (→)
  • \u2615 代表咖啡杯 (?)
  • \u1F60E 代表戴著墨鏡的笑臉 (??)
  • \u2764 表示一顆紅心 (?)

Unicode 可以表示任何語言的任何字符或符號,不過舊版本瀏覽器的支持性可能沒那么好。

9. script async vs script defer

當(dāng)瀏覽器碰到 script 標(biāo)簽時,會執(zhí)行以下步驟:

  • 暫停文檔解析
  • 創(chuàng)建一個新請求來下載腳本
  • 下載完成后執(zhí)行腳本
  • 繼續(xù)解析文檔

script 標(biāo)簽會阻塞整個文檔的解析,為了提供更好的體驗,HTML5 為 script 標(biāo)簽提供了兩個屬性,它們是 async 和 defer。

<script src="/path/to/script.js" async></script>
<script src="/path/to/script.js" defer></script>

這兩個屬性讓瀏覽器知道,該腳本與文檔解析可以同時進行。

async 和 defer 的效果如上圖。

async 會在下載完成后立即執(zhí)行(下載不阻塞 HTML 解析,執(zhí)行會),所以多個 script 標(biāo)簽都使用 async 屬性的話,是不能保證多個 script 的執(zhí)行順序,而使用 defer 的話,下載完后會等待 HTML 解析完成再執(zhí)行,可以保證多個 script 的執(zhí)行順序。

所以 async 一般在獨立的腳本上使用,如埋點腳本。

還有一點,動態(tài)加載的腳本 async 默認(rèn)為 true,如果你不需要,可以設(shè)置為 false:

const script = document.createElement('script');
script.src = '/path/to/script.js';
script.async = false;
document.head.appendChild(script);

10. __proto__ vs prototype

__proto__ 和 prototype 的區(qū)別很簡單:

  • __proto__ 是對象實例的屬性
  • prototype 是構(gòu)造函數(shù)的屬性

當(dāng)你使用 __proto__ 時,你是正在查找對象原型鏈上的屬性和方法,而 prototype 對象定義了所有實例都將擁有的共享屬性和方法。

圖片圖片

如上圖,Letter 函數(shù)的 prototype 屬性和其三個實例的 __proto__ 屬性都是指向 Letter 的原型鏈對象 Letter.prototype。

11.Dependencies vs devDependencies vs peerDependencies

dependencies 代表依賴項是項目中的一部分,最終會被一起打包到生產(chǎn)代碼中,當(dāng)你執(zhí)行 npm install 時,你依賴的那個包的依賴也會自動安裝,比如你項目使用到了 antd, npm install 時 antd 的依賴項 classnames 也會被安裝,這就是你有時候沒安裝一些庫,但是也可以使用的原因。

"dependencies": {
    "lodash": "^4.17.21"
}

devDenpendencies 代表依賴項是僅在開發(fā)過程中才需要的,代碼的最終生產(chǎn)版本并不需要這些依賴項。

"devDependencies": {
    "jest": "^29.6.4"
}

peerDependencies 代表使用這個庫時需要的依賴項,和 dependencies 不同的是,它不會在 npm install 時被安裝,需要你顯式的在自己項目下安裝。各個包管理器的各個版本對 peerDependencies 的處理可能都不同,有興趣的可以繼續(xù)深入了解。

"peerDependencies": {
    "react": ">=16.9.0",
    "react-dom": ">=16.9.0"
  },

12. isNaN vs Number.isNaN

isNaN 是一個全局函數(shù),用于判斷參數(shù)是否為 NaN,不過,在判斷參數(shù)是否為 NaN 之前,它會嘗試先將參數(shù)轉(zhuǎn)換為數(shù)字。

isNaN('hello');     // true
isNaN(undefined);   // true
isNaN({});          // true
isNaN([]);          // false  +[] === 0
isNaN(42);          // false

在 ES6 中引入了 Number.isNaN 函數(shù),與 isNaN 不同的是,在判斷前 Number.isNaN 不會轉(zhuǎn)換參數(shù)。

Number.isNaN('hello');      // false
Number.isNaN(undefined);    // false
Number.isNaN({});           // false
Number.isNaN([]);           // false
Number.isNaN(42);           // false
Number.isNaN(NaN);          // true

一般來說,使用 Number.isNaN 比 isNaN 更準(zhǔn)確。

13. 默認(rèn)參數(shù) vs 或操作符

JavaScript 提供了兩種為函數(shù)參數(shù)設(shè)置默認(rèn)值的方法:使用默認(rèn)參數(shù)或 OR (||) 操作符,兩者在最終效果上會有一些不同。

先來看默認(rèn)參數(shù):

const sayHello = (name = 'World') => {
  console.log(`Hello, ${name}!`);
};

sayHello();                 // `Hello, World!`
sayHello(undefined);        // `Hello, World!`
sayHello(null);    // `Hello, null!`
sayHello('');    // `Hello, !`
sayHello("Phuoc Nguyen");   // `Hello, Phuoc Nguyen!`

可以看到默認(rèn)參數(shù)只有為 undefined 的時候,默認(rèn)參數(shù)才會生效。不傳和傳 undefined 效果一致。

再來看或操作符:

const sayHello2 = (name) => {
    const withDefaultName = name || 'World';
    console.log(`Hello, ${withDefaultName}!`);
};

sayHello2();                 // `Hello, World!`
sayHello2(undefined);        // `Hello, World!`
sayHello2(null);    // `Hello, World!`
sayHello2('');     // `Hello, World!`
sayHello2("Phuoc Nguyen");   // `Hello, Phuoc Nguyen!`

可以看到參數(shù)只要是 falsy 值(undefined、null、NaN、0、""和 false),都會使用代碼中默認(rèn)參數(shù),這個就是和 ES6 默認(rèn)參數(shù)不同的地方。

14. null vs undefined

null 和 undefined 的不同點如下:

  1. undefined 表示變量已經(jīng)被聲明,但未被賦值;null 用來表示變量沒有值。
let foo;
console.log(foo); // undefined

let foo = null;
console.log(foo); // null
  1. undefined 和 null 代表的類型不同。
console.log(typeof undefined); // 'undefined'
console.log(typeof null); // 'object'

除了以上兩點不同之外,還有兩點值得關(guān)注的:

  1. undefined 和 null 進行比較的結(jié)果。
null == undefined; // true
null === undefined; // false
  1. JSON.stringify 會忽略 undefined, 但是會保留 null。
JSON.stringify({
    name: 'John',
    address: null,
    age: undefined,
});

// {"name":"John","address":null}

小結(jié)

前端中還有很多相近的概念和 API,在業(yè)務(wù)開發(fā)時可能沒時間去了解,但是有空的時候還是可以花點時間去掌握其中的異同,扎實自己的前端基礎(chǔ)。

參考資料

[1]local-storage-vs-session-storage-vs-cookies: https://www.loginradius.com/blog/engineering/guest-post/local-storage-vs-session-storage-vs-cookies/

[2]圖片源: https://medium.com/@francesco_rizzi/javascript-main-thread-dissected-43c85fce7e23

責(zé)任編輯:武曉燕 來源: 栗子前端
相關(guān)推薦

2022-05-27 08:55:15

工具自動化軟件

2014-05-30 10:23:15

樂跑手環(huán)智能手環(huán)運動手環(huán)

2024-10-12 08:01:53

2019-01-07 13:01:08

Linux驚嘆用法命令

2024-11-20 08:31:49

前端全棧技術(shù)

2020-11-04 10:19:09

前端開發(fā)插件

2023-12-12 08:41:01

2024-06-14 08:36:57

2019-12-12 09:23:29

Hello World操作系統(tǒng)函數(shù)庫

2022-03-10 08:25:27

JavaScrip變量作用域

2024-09-18 07:00:00

消息隊列中間件消息隊列

2021-10-14 06:52:47

算法校驗碼結(jié)構(gòu)

2022-09-29 15:32:58

云計算計算模式

2023-12-20 08:23:53

NIO組件非阻塞

2023-04-26 10:21:04

2024-04-30 09:02:48

2019-02-12 11:15:15

Spring設(shè)計模式Java

2024-09-12 08:20:39

2024-04-09 11:40:58

DartJSWasmGC

2024-05-28 09:12:10

點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 中文在线观看视频 | 国产成人精品免高潮在线观看 | 在线国产视频观看 | 在线激情视频 | 亚洲激情网站 | 一区二区精品 | 欧美日韩国产免费 | 黑人精品欧美一区二区蜜桃 | 久久国产精99精产国高潮 | 精品日韩一区 | 国产日韩91| 国产免费视频在线 | 精品中文在线 | 成人网av | av日韩一区 | 青青草av网站 | 黑人巨大精品欧美一区二区免费 | 国产美女精品视频 | 精品在线一区 | 天天综合久久网 | 欧美性高潮 | 日日干夜夜干 | av网站免费在线观看 | 欧美国产91 | 欧美午夜精品理论片a级按摩 | 国产三级日本三级 | 99日韩| av一区二区三区 | 国产成人免费网站 | 国产精品人人做人人爽 | 久久精品一级 | 国产免费一区二区三区 | 本道综合精品 | 久久成人精品视频 | 精品欧美一区二区三区久久久 | 欧美日韩久久 | 亚洲第一在线 | 国产区在线观看 | 美女毛片 | 国产精品久久久久久久久久久免费看 | 涩涩片影院 |