
此讀數是使用Markdown-Builder構建的。
訪談令人生畏,甚至可以使經驗最豐富的專家忘記在壓力下的事情。審查並了解社區策劃的訪談中通常會遇到哪些問題,這些問題是回答他們的,並為他們要問的任何事情做好了準備。通過匯總經驗和現實世界的例子,您可以從緊張到為下一個大機會做好準備。

30秒的訪談是社區的努力,因此請隨時以任何方式做出貢獻。每個貢獻都會有所幫助!
您有一個好主意還是知道一些不在列表中的很酷的問題?閱讀貢獻指南並提交拉動請求。
加入我們的吉特頻道,以幫助項目的開發。
batches ,該功能返回可以從食譜烹飪的整個批次的最大數量。bind該函數在功能上等效於方法函數Function.prototype.bind 。setState的參數的目的是什麼?children道具是什麼?==和===有什麼區別?0.1 + 0.2 === 0.3評估什麼?map()和forEach()有什麼區別?# ,除了最後四(4)個字符。this上下文?null和undefined有什麼區別?pipe ,該功能管通過返回接受一個參數的函數來執行從左到右功能的組合。i++和前綴++i增量運算符有什麼區別?this關鍵字是什麼,它如何工作?'use strict'是什麼,使用它有哪些關鍵好處?var , let , const和NO關鍵字語句之間有什麼區別?setState的參數的目的是什麼?children道具是什麼?className而不是html中的class ?this上下文?alt屬性的目的是什麼?<script>標籤上的defer和async屬性是什麼?<header>元素嗎? <footer>元素呢?<header> , <article> , <section> , <footer>localStorage和sessionStorage 。rel="noopener"屬性在哪里以及為什麼使用?em和rem單位有什麼區別?col-{n} / 12比率。@media屬性的四種類型嗎?無狀態組件是其行為不取決於其狀態的組件。無狀態組件可以是功能或類成分。無狀態的功能組件更易於維護和測試,因為它們可以保證在相同的道具下產生相同的輸出。當不需要使用生命週期掛鉤時,應首選無狀態的功能組件。
this關鍵字。
⬆回到頂部
==和===有什麼區別?三重等於( === )檢查嚴格的平等,這意味著類型和值必須相同。另一方面,雙等價( == )首先執行類型的脅迫,因此兩個操作數均具有相同的類型,然後應用嚴格的比較。
==可能會產生不直覺的結果。
⬆回到頂部
元素是代表DOM節點或組件的普通JavaScript對象。元素是純淨的,永遠不會變異,而且創造便宜。
組件是函數或類。組件可以具有狀態並將道具作為輸入,並將元素樹作為輸出返回(儘管它們可以代表通用容器或包裝器,並且不一定要發射DOM)。組件可以啟動生命週期方法的副作用(例如AJAX請求,DOM突變,與第三方庫的接口),並且創建可能很昂貴。
const Component = ( ) => "Hello"
const componentElement = < Component />
const domNodeElement = < div />
⬆回到頂部
狀態組件是其行為取決於其狀態的組成部分。這意味著與純函數組件不同,如果給出相同的道具,則組件的兩個單獨實例不一定會呈現相同的輸出。
// Stateful class component
class App extends Component {
constructor ( props ) {
super ( props )
this . state = { count : 0 }
}
render ( ) {
// ...
}
}
// Stateful function component
function App ( ) {
const [ count , setCount ] = useState ( 0 )
return // ...
} useState()中初始化。
⬆回到頂部
這些州之一是一個Promise :
懸而未決的承諾可以通過價值來實現,或者以理由拒絕(錯誤)。當這些選項中的任何一個都會發生時,相關的處理程序以諾言的方式排隊。
⬆回到頂部
i++和前綴++i增量運算符有什麼區別?兩者都將變量值增加1。差異是他們評估的。
Postfix增量運算符在將其增量之前對其進行評估。
let i = 0
i ++ // 0
// i === 1前綴增量運算符在增量後評估該值。
let i = 0
++ i // 1
// i === 1
⬆回到頂部
batches ,該功能返回可以從食譜烹飪的整個批次的最大數量。 /**
It accepts two objects as arguments: the first object is the recipe
for the food, while the second object is the available ingredients.
Each ingredient's value is a number representing how many units there are.
`batches(recipe, available)`
*/
// 0 batches can be made
batches (
{ milk : 100 , butter : 50 , flour : 5 } ,
{ milk : 132 , butter : 48 , flour : 51 }
)
batches (
{ milk : 100 , flour : 4 , sugar : 10 , butter : 5 } ,
{ milk : 1288 , flour : 9 , sugar : 95 }
)
// 1 batch can be made
batches (
{ milk : 100 , butter : 50 , cheese : 10 } ,
{ milk : 198 , butter : 52 , cheese : 10 }
)
// 2 batches can be made
batches (
{ milk : 2 , sugar : 40 , butter : 20 } ,
{ milk : 5 , sugar : 120 , butter : 500 }
)我們必須擁有可用的食譜的所有成分,並且數量超過或等於所需的單位數量。如果只有一種不可用或低於所需的成分,我們將無法進行一批。
使用Object.keys()將配方的成分返回作為數組,然後使用Array.prototype.map()將每個成分映射到可用單位的比率與配方所需的數量。如果根本不可用食譜所需的一種成分,則比率將與NaN進行評估,因此在這種情況下,邏輯或操作員可以將邏輯或運算符用於下降至0 。
使用差異...運算符將所有成分比的數組饋入Math.min()以確定最低比率。將整個結果傳遞到Math.floor()回合以返回整個批次的最大數量。
const batches = ( recipe , available ) =>
Math . floor (
Math . min ( ... Object . keys ( recipe ) . map ( k => available [ k ] / recipe [ k ] || 0 ) )
)
⬆回到頂部
typeof typeof 0它評估為"string" 。
typeof 0評估字符串"number" ,因此typeof "number"評估為"string" 。
⬆回到頂部
使用對像傳播操作員...可以將對象自己的枚舉屬性複製到新對像中。這創建了物體的淺克隆。
const obj = { a : 1 , b : 2 }
const shallowClone = { ... obj }使用此技術,原型被忽略。另外,嵌套對像沒有克隆,而是複制它們的引用,因此嵌套的對象仍然指與原始對象相同的對象。深度關閉更為複雜,以便有效克隆任何可能嵌套在對像中的對象(日期,regexp,function,set等)。
其他選擇包括:
JSON.parse(JSON.stringify(obj))可用於深粘結一個簡單的對象,但它是CPU密集型的,僅接受有效的JSON(因此它剝離功能並且不允許循環引用)。Object.assign({}, obj)是另一種選擇。Object.keys(obj).reduce((acc, key) => (acc[key] = obj[key], acc), {})是另一個更詳細的替代方案,它以更深入的深度顯示了概念。
⬆回到頂部
同步意味著每個操作必須等待上一個操作完成。
異步意味著在仍在處理其他操作時可能會發生操作。
在JavaScript中,由於其單線程的性質,所有代碼都是同步的。但是,異步操作不是程序的一部分(例如XMLHttpRequest或setTimeout )是在主線程之外處理的,因為它們是由本機代碼(瀏覽器API)控制的,但是程序的回調部分仍將同時執行。
alert屏蔽主線程之類的函數,以便在用戶關閉之前沒有註冊用戶輸入。
⬆回到頂部
即使兩個不同的對象可以具有相同值相同的屬性,但使用==或===進行比較時,它們也不相等。這是因為它們是通過參考(內存中的位置)進行比較的,這與原始值不同,這些值按值進行了比較。
為了測試兩個對象的結構是否相等,需要一個輔助功能。它將通過每個對象的自身屬性進行迭代,以測試它們是否具有相同的值,包括嵌套對象。可選地,也可以通過將true作為第三參數進行測試對象的原型。
注意:此技術不會嘗試測試除普通對象,數組,函數,日期和原始值以外的數據結構的等效性。
function isDeepEqual ( obj1 , obj2 , testPrototypes = false ) {
if ( obj1 === obj2 ) {
return true
}
if ( typeof obj1 === "function" && typeof obj2 === "function" ) {
return obj1 . toString ( ) === obj2 . toString ( )
}
if ( obj1 instanceof Date && obj2 instanceof Date ) {
return obj1 . getTime ( ) === obj2 . getTime ( )
}
if (
Object . prototype . toString . call ( obj1 ) !==
Object . prototype . toString . call ( obj2 ) ||
typeof obj1 !== "object"
) {
return false
}
const prototypesAreEqual = testPrototypes
? isDeepEqual (
Object . getPrototypeOf ( obj1 ) ,
Object . getPrototypeOf ( obj2 ) ,
true
)
: true
const obj1Props = Object . getOwnPropertyNames ( obj1 )
const obj2Props = Object . getOwnPropertyNames ( obj2 )
return (
obj1Props . length === obj2Props . length &&
prototypesAreEqual &&
obj1Props . every ( prop => isDeepEqual ( obj1 [ prop ] , obj2 [ prop ] ) )
)
}
⬆回到頂部
XSS是指攻擊者將惡意腳本注入合法網站或Web應用程序的客戶端代碼注入。當應用程序未驗證用戶輸入並自由注入動態HTML內容時,通常可以實現這一點。
例如,如果評論系統不驗證或逃脫用戶輸入,則將處於危險之中。如果該評論包含未設計的HTML,則該註釋可以將<script>標籤注入其他用戶會根據其知識執行的網站。
textContent而不是innerHTML可防止瀏覽器通過HTML解析器運行字符串,該解析器將在其中執行腳本。
⬆回到頂部
交叉原始資源共享或CORS是一種使用其他HTTP標頭的機制,授予瀏覽器的權限,以從與網站Origin不同的原點的服務器訪問資源。
交叉原始請求的一個示例是從http://mydomain.com提供的Web應用程序,該應用程序使用Ajax向http://yourdomain.com提出請求。
出於安全原因,瀏覽器限制了JavaScript發起的交叉原始HTTP請求。 XMLHttpRequest和fetch遵循相同的Origin策略,這意味著使用這些API的Web應用程序只能從同一來源請求HTTP Resources訪問該應用程序的訪問,除非來自其他原點的響應包括正確的CORS標頭。
⬆回到頂部
DOM(文檔對像模型)是一種跨平台API,將HTML和XML文檔視為由節點組成的樹結構。這些節點(例如元素和文本節點)是可以通過編程方式操縱的對象,並且對其進行的任何可見更改都會反映在文檔中。在瀏覽器中,該API可用於JavaScript,可以操縱DOM節點以更改其樣式,內容,文檔中的位置或通過事件聽眾進行交互。
<head>帶有defer屬性,或者在DOMContentLoaded Event ockiter中。在構造DOM之後,應運行操縱DOM節點的腳本以避免錯誤。document.getElementById()和document.querySelector()是選擇DOM節點的常見函數。innerHTML屬性設置為新值可以通過HTML解析器運行字符串,從而提供了一種簡單的方法,可以將動態HTML內容附加到節點。
⬆回到頂部
bind該函數在功能上等效於方法函數Function.prototype.bind 。 function example ( ) {
console . log ( this )
}
const boundExample = bind ( example , { a : true } )
boundExample . call ( { b : true } ) // logs { a: true }返回一個函數,該函數通過將其收集到其餘的...運營商來接受任意數量的參數。從該函數中,返回使用Function.prototype.apply返回fn的結果,以將上下文和參數數組應用於函數。
const bind = ( fn , context ) => ( ... args ) => fn . apply ( context , args )
⬆回到頂部
var , let , const和NO關鍵字語句之間有什麼區別?當變量分配之前不存在關鍵字時,如果不存在,它要么分配全局變量,要么重新分配已經聲明的變量。在非圖片模式下,如果尚未聲明該變量,它將將變量分配為全局對象的屬性(瀏覽器中的window )。在嚴格的模式下,它將引發錯誤,以防止不必要的全局變量被創建。
var是在ES2015之前聲明變量的默認語句。它創建了一個可以重新分配和重新播放的功能範圍的變量。但是,由於缺乏塊範圍,如果變量在包含異步回調的循環中重複使用,則可能會導致問題,因為該變量將繼續存在於塊範圍之外。
下面,到setTimeout回調執行時,循環已經完成, i變量為10 ,因此所有十個回調引用了功能範圍中可用的相同變量。
for ( var i = 0 ; i < 10 ; i ++ ) {
setTimeout ( ( ) => {
// logs `10` ten times
console . log ( i )
} )
}
/* Solutions with `var` */
for ( var i = 0 ; i < 10 ; i ++ ) {
// Passed as an argument will use the value as-is in
// that point in time
setTimeout ( console . log , 0 , i )
}
for ( var i = 0 ; i < 10 ; i ++ ) {
// Create a new function scope that will use the value
// as-is in that point in time
; ( i => {
setTimeout ( ( ) => {
console . log ( i )
} )
} ) ( i )
} let在ES2015中引入,這是聲明變量的新首選方法,這些變量將在以後重新分配。試圖重新匯集變量將引發錯誤。它是塊拆分的,因此在循環中使用它可以使其範圍範圍內的迭代範圍。
for ( let i = 0 ; i < 10 ; i ++ ) {
setTimeout ( ( ) => {
// logs 0, 1, 2, 3, ...
console . log ( i )
} )
} const是在ES2015中介紹的,是如果以後不會重新分配所有變量,即使對於將要突變的對象(只要對象的引用不更改),也是聲明所有變量的新首選默認方法。它是塊分割的,不能重新分配。
const myObject = { }
myObject . prop = "hello!" // No error
myObject = "hello" // Error let和const有一個稱為時間死區(TDZ)的概念。雖然聲明仍在提起,但在進入範圍和聲明無法訪問的地方之間存在一段時間。var以及let解決它的常見問題,以及保留var的解決方案。var ,並更喜歡const作為所有變量的默認聲明語句,除非以後將其重新分配,否則請使用let 。 let vs const
⬆回到頂部
事件代表團是將事件委派給單個共同祖先的技術。由於事件冒泡,事件通過在每個祖先元素上逐漸執行任何處理程序,直到可能正在聆聽它的根來“冒泡” DOM樹。
DOM事件提供了有關通過Event.target啟動事件的元素的有用信息。這使父元素可以處理行為,就好像目標元素在聽事件,而不是父母或父母本身的所有孩子。
這提供了兩個主要好處:
而不是:
document . querySelectorAll ( "button" ) . forEach ( button => {
button . addEventListener ( "click" , handleButtonClick )
} )事件委託涉及使用條件來確保孩子目標與我們所需的元素匹配:
document . addEventListener ( "click" , e => {
if ( e . target . closest ( "button" ) ) {
handleButtonClick ( )
}
} )
⬆回到頂部
setState的參數的目的是什麼?setState完成並渲染組件後,調用回調功能。由於setState是異步的,因此回調函數用於任何後操作。
setState ( { name : "sudheer" } , ( ) => {
console . log ( "The name has updated and component re-rendered" )
} ) setState完成後調用回調功能,並用於任何後操作。setState上的react文檔
⬆回到頂部
JavaScript中有兩個主要的句法類別:表達式和語句。第三個都是在一起,稱為表達式語句。它們大致總結為:
一般的經驗法則:
如果您可以打印或將其分配給變量,則是一個表達式。如果不能,這是一個陳述。
let x = 0
function declaration ( ) { }
if ( true ) {
}語句以執行操作但不產生價值的指示出現。
// Assign `x` to the absolute value of `y`.
var x
if ( y >= 0 ) {
x = y
} else {
x = - y
}上面代碼中唯一的表達式是y >= 0它產生一個值,無論是true還是false 。代碼的其他部分不會產生一個值。
表達產生一個值。它們可以傳遞到函數,因為解釋器將其解析的價值取代。
5 + 5 // => 10
lastCharacter ( "input" ) // => "t"
true === true // => true 使用條件運算符以前用作表達式的一組語句的等效版本:
// Assign `x` as the absolute value of `y`.
var x = y >= 0 ? y : - y這既是表達式又是語句,因為我們將變量x (語句)稱為評估(表達式)。
⬆回到頂部
根據在布爾語境中對其進行評估,價值要么是真實的,要么是虛假的。虛假意味著假和真實的意思是真實的。從本質上講,它們是執行某些操作時被強制為true或false值。
JavaScript中有6個虛假值。他們是:
falseundefinednull"" (空字符串)NaN0 ( +0和-0 )其他每個價值都被認為是真實的。
可以通過將價值傳遞到Boolean功能來檢查價值的真實性。
Boolean ( "" ) // false
Boolean ( [ ] ) // true使用邏輯上沒有的是一個快捷方式!操作員。使用!一旦將一個值轉換為其反向布爾值等效物(即不是false是true),並且!再一次將轉換,從而有效地將值轉換為布爾值。
! ! "" // false
! ! [ ] // true
⬆回到頂部
初始化長度為n的空數組。使用Array.prototype.reduce()使用最後兩個值的總和將值添加到數組中,但前兩個值除外。
const fibonacci = n =>
[ ... Array ( n ) ] . reduce (
( acc , val , i ) => acc . concat ( i > 1 ? acc [ i - 1 ] + acc [ i - 2 ] : i ) ,
[ ]
)
⬆回到頂部
0.1 + 0.2 === 0.3評估什麼?它評估為false ,因為JavaScript使用IEEE 754標準數學標準,並使用64位浮數。簡而言之,這會導致精度錯誤,因為計算機在基本2中工作,而十進制為基礎10。
0.1 + 0.2 // 0.30000000000000004解決此問題的一種解決方案是使用一個函數,該函數通過定義誤差邊距(Epsilon)值是否大致相等,即兩個值之間的差異應小於。
const approxEqual = ( n1 , n2 , epsilon = 0.0001 ) => Math . abs ( n1 - n2 ) < epsilon
approxEqual ( 0.1 + 0.2 , 0.3 ) // true
⬆回到頂部
map()和forEach()有什麼區別?兩種方法都通過數組的元素迭代。 map()通過在每個元素上調用回調函數並返回新數組,將每個元素映射到新元素。另一方面, forEach()調用每個元素的回調函數,但不會返回新數組。通常在對每次迭代產生副作用時通常使用forEach() ,而map()是一種常見的功能編程技術。
forEach()而無需返回值即可生成新數組。map()是將數據不可變的正確選擇,而原始數組的每個值都映射到新數組。
⬆回到頂部
短路評估涉及從左到右評估和儘早停止評估的邏輯操作。
true || false在上面的示例中,使用邏輯或JavaScript不會查看第二個操作數false ,因為無論如何,表達式評估為true 。這被稱為短路評估。
這也適用於邏輯和。
false && true這意味著您可以擁有一個表達式,該表達式在評估時會引發錯誤,並且不會引起問題。
true || nonexistentFunction ( )
false && nonexistentFunction ( )由於從左到右評估,多次操作仍然如此。
true || nonexistentFunction ( ) || window . nothing . wouldThrowError
true || window . nothing . wouldThrowError
true此行為的常見用例是設置默認值。如果第一操作數是虛假的,則將評估第二操作數。
const options = { }
const setting = options . setting || "default"
setting // "default"另一個常見的用例是僅在第一個操作數是真實情況下評估表達式。
// Instead of:
addEventListener ( "click" , e => {
if ( e . target . closest ( "button" ) ) {
handleButtonClick ( e )
}
} )
// You can take advantage of short-circuit evaluation:
addEventListener (
"click" ,
e => e . target . closest ( "button" ) && handleButtonClick ( e )
)在上述情況下,如果e.target不或不包含匹配"button"選擇器的元素,則該函數將不會被調用。這是因為第一台操作數將是虛假的,導致第二個操作數未進行評估。
⬆回到頂部
有時。由於JavaScript的自動分號插入,解釋器將半洛龍置於大多數陳述之後。這意味著在大多數情況下可以省略半殖民物。
但是,在某些情況下需要它們。它們在塊開始時不需要它們,但是如果他們遵循一條線,則是:
[ const previousLine = 3
; [ 1 , 2 , previousLine ] . map ( n => n * 2 )( const previousLine = 3
; ( function ( ) {
// ...
} ) ( )在上述情況下,解釋器不會在3之後插入半隆,因此將3視為嘗試對象屬性訪問或被調用為函數,這會丟棄錯誤。
⬆回到頂部
var foo = 1
var foobar = function ( ) {
console . log ( foo )
var foo = 2
}
foobar ( )由於提升,在調用console.log方法之前聲明局部變量foo 。這意味著將局部變量foo作為參數傳遞給console.log()而不是在函數之外聲明的全局變量。但是,由於該值沒有帶有變量聲明,因此輸出將undefined ,而不是2 。
strict模式
⬆回到頂部
提升是一種JavaScript機制,在編譯階段,將可變和函數聲明放入內存中。這意味著無論函數和變量在何處聲明,無論其範圍是全球還是本地的,它們都將移至其範圍頂部。
但是,該聲明並沒有提高價值。
以下片段:
console . log ( hoist )
var hoist = "value"等同於:
var hoist
console . log ( hoist )
hoist = "value"因此,記錄hoist輸出undefined到控制台,而不是"value" 。
提升還允許您調用函數聲明,然後才能在程序中聲明。
myFunction ( ) // No error; logs "hello"
function myFunction ( ) {
console . log ( "hello" )
}但是要警惕分配給變量的功能表達式:
myFunction ( ) // Error: `myFunction` is not a function
var myFunction = function ( ) {
console . log ( "hello" )
}
⬆回到頂部
在HTML中,屬性名稱均在所有小寫字母中,並給出一個字符串,調用在某處定義的函數:
< button onclick =" handleClick() " > </ button >在React中,屬性名稱是駱駝箱,並通過捲曲括號內的功能參考傳遞:
< button onClick = { handleClick } />在html中,可以返回false以防止默認行為,而在React preventDefault中必須明確調用。
< a href =" # " onclick =" console.log('The link was clicked.'); return false " /> function handleClick ( e ) {
e . preventDefault ( )
console . log ( "The link was clicked." )
}
⬆回到頂部
該技術在JavaScript庫中非常普遍。它圍繞文件的整個內容創建一個封閉,從而創建一個私有名稱空間,從而有助於避免不同的JavaScript模塊和庫之間的潛在名稱衝突。立即調用該函數,以便將命名空間(庫名)分配給函數的返回值。
const myLibrary = ( function ( ) {
var privateVariable = 2
return {
publicMethod : ( ) => privateVariable
}
} ) ( )
privateVariable // ReferenceError
myLibrary . publicMethod ( ) // 2
⬆回到頂部
function greet ( ) {
return
{
message : "hello"
}
}由於JavaScript的自動插入(ASI),編譯器在return關鍵字後放置了一個半龍,因此它返回undefined而不會丟棄錯誤。
⬆回到頂部
由於JSX元素樹是一個大表情,因此您無法將語句嵌入其中。條件表達式是替代樹內使用的語句。
例如,這行不通:
function App ( { messages , isVisible } ) {
return (
< div >
if (messages.length > 0 ) {
< h2 > You have { messages . length } unread messages. </ h2 >
} else {
< h2 > You have no unread messages. </ h2 >
}
if (isVisible) {
< p > I am visible. </ p >
}
</ div >
)
}邏輯和&&和三元? :操作員替換if / else語句。
function App ( { messages , isVisible } ) {
return (
< div >
{ messages . length > 0 ? (
< h2 > You have { messages . length } unread messages. </ h2 >
) : (
< h2 > You have no unread messages. </ h2 >
) }
{ isVisible && < p > I am visible. </ p > }
</ div >
)
}
⬆回到頂部
密鑰是一個特殊的字符串屬性,可幫助識別哪些項目已更改,添加或刪除。當渲染數組元素賦予它們穩定的身份時,它們會被使用。每個元素的密鑰必須是唯一的(例如,來自數據或索引作為最後的手段)。
const todoItems = todos . map ( todo => < li key = { todo . id } > { todo . text } </ li > )<li>標籤上應用。 <li>元素。
⬆回到頂部
詞彙範圍是指函數定義的位置確定您可以訪問哪些變量的位置。另一方面,動態範圍使用函數調用的位置來確定可用的變量。
⬆回到頂部
# ,除了最後四(4)個字符。 mask ( "123456789" ) // "#####6789"解決這個問題的方法有很多,這只是其中之一。
使用String.prototype.slice()我們可以通過傳遞-4作為參數來獲取字符串的最後4個字符。然後,使用String.prototype.padStart() ,我們可以使用重複的掩碼字符將字符串粘貼到原始長度上。
const mask = ( str , maskChar = "#" ) =>
str . slice ( - 4 ) . padStart ( str . length , maskChar )
⬆回到頂部
const a = [ 1 , 2 , 3 ]
const b = [ 1 , 2 , 3 ]
const c = "1,2,3"
console . log ( a == c )
console . log ( a == b )第一個console.log輸出為true ,因為JavaScript的編譯器執行類型轉換,因此與字符串的值相比。另一方面,第二個console.log輸出false ,因為數組是對象,並且可以通過參考比較對象。
⬆回到頂部
在經典的繼承範式中,對象實例從類中繼承其屬性和函數,該類別充當對象的藍圖。對象實例通常是使用構造函數和new關鍵字創建的。
在原型繼承範式中,對象實例直接從其他對象繼承,通常是使用Factory Functions或Object.create()創建的。
⬆回到頂部
MIME是Multi-purpose Internet Mail Extensions首字母縮寫。它被用作通過Internet對文件類型進行分類的標準方法。
MIME type實際上有兩個部分:一種類型和一個由斜線(/)隔開的亞型。例如,Microsoft Word文件的MIME type是application/msword (即,類型為應用程序,子類型是Msword)。
⬆回到頂部
Promise對象表示異步操作的最終完成(或失敗)及其結果值。一個示例可以是以下片段,在100毫秒後將結果字符串打印到標準輸出。另外,請注意可用於錯誤處理的捕獲物。 Promise是可以連鎖的。
new Promise ( ( resolve , reject ) => {
setTimeout ( ( ) => {
resolve ( "result" )
} , 100 )
} )
. then ( console . log )
. catch ( console . error ) Promise的其他問題!
⬆回到頂部
最新的ecmascript標准定義了七種數據類型,其中六種是原始的: Boolean , Null , Undefined , Number , String , Symbol和一種非重要數據類型: Object 。
Symbol數據類型Array , Date和function都是類型object
⬆回到頂部
fs . readFile ( filePath , function ( err , data ) {
if ( err ) {
// handle the error, the return is important here
// so execution stops here
return console . log ( err )
}
// use the data object
console . log ( data )
} )優點包括:
從下面的示例中可以看到,如果沒有錯誤,則將回調稱為其第一個參數。但是,如果存在錯誤,則創建一個錯誤對象,然後將成為回調的唯一參數。回調功能允許用戶輕鬆了解是否發生錯誤。
此練習也稱為node.js錯誤約定,這種回調實現稱為錯誤 - 先回調。
var isTrue = function ( value , callback ) {
if ( value === true ) {
callback ( null , "Value was true." )
} else {
callback ( new Error ( "Value is not true!" ) )
}
}
var callback = function ( error , retval ) {
if ( error ) {
console . log ( error )
return
}
console . log ( retval )
}
isTrue ( false , callback )
isTrue ( true , callback )
/*
{ stack: [Getter/Setter],
arguments: undefined,
type: undefined,
message: 'Value is not true!' }
Value was true.
*/
⬆回到頂部
回調是作為參數傳遞給另一個函數的函數,一旦事件發生或完成某個任務完成,通常在異步代碼中使用。稍後通過一段代碼調用回調功能,但可以在初始化時聲明而無需調用。
例如,事件偵聽器是異步回調,僅在發生特定事件時才執行。
function onClick ( ) {
console . log ( "The user clicked on the page." )
}
document . addEventListener ( "click" , onClick )但是,回調也可以同步。以下map函數採用回調函數,該函數對環路的每次迭代(數組元素)同步調用。
const map = ( arr , callback ) => {
const result = [ ]
for ( let i = 0 ; i < arr . length ; i ++ ) {
result . push ( callback ( arr [ i ] , i ) )
}
return result
}
map ( [ 1 , 2 , 3 , 4 , 5 ] , n => n * 2 ) // [2, 4, 6, 8, 10]
⬆回到頂部
null和undefined有什麼區別?在JavaScript中,兩個值分散地表示沒有 - undefined和null 。它們之間的具體差異是null是顯式的,而undefined是隱式的。當屬性不存在或尚未給出變量時,該值是undefined 。 null設置為明確指示“無值”的值。從本質上講,當不知道什麼都不知道時,使用undefined ,而當不知道的情況下,則使用null 。
typeof undefined評估為"undefined" 。typeof null評估"object" 。但是,它仍然是原始價值,這被認為是JavaScript中的實現錯誤。undefined == null評估為true 。
⬆回到頂部
通常用來存儲一種數據出現。
const person = {
name : "John" ,
age : 50 ,
birthday ( ) {
this . age ++
}
}
person . birthday ( ) // person.age === 51 當您需要創建對象的多個實例時,通常都使用它們自己的數據,每個都有自己的數據,這些數據也不會影響該類的其他實例。在調用構造函數或全局對象將被突變之前,必須使用new操作員。
function Person ( name , age ) {
this . name = name
this . age = age
}
Person . prototype . birthday = function ( ) {
this . age ++
}
const person1 = new Person ( "John" , 50 )
const person2 = new Person ( "Sally" , 20 )
person1 . birthday ( ) // person1.age === 51
person2 . birthday ( ) // person2.age === 21 創建一個類似於構造函數的新對象,但可以使用封閉來存儲私有數據。在調用功能或this關鍵字之前,也無需使用new 。工廠功能通常會丟棄原型的想法,並將所有屬性和方法保留為對象的自身屬性。
const createPerson = ( name , age ) => {
const birthday = ( ) => person . age ++
const person = { name , age , birthday }
return person
}
const person = createPerson ( "John" , 50 )
person . birthday ( ) // person.age === 51 Object.create()設置新創建的對象的原型。
const personProto = {
birthday ( ) {
this . age ++
}
}
const person = Object . create ( personProto )
person . age = 50
person . birthday ( ) // person.age === 51也可以將第二個參數提供給Object.create() ,它充當要定義的新屬性的描述符。
Object . create ( personProto , {
age : {
value : 50 ,
writable : true ,
enumerable : true
}
} )
⬆回到頂部
參數是函數定義的變量名稱,而參數是調用函數時給出的值。
function myFunction ( parameter1 , parameter2 ) {
console . log ( arguments [ 0 ] ) // "argument1"
}
myFunction ( "argument1" , "argument2" ) arguments是一個類似數組的對象,其中包含有關提供給調用函數的參數的信息。myFunction.length描述了函數的差異(無論其提供了多少參數,它具有多少參數)。
⬆回到頂部
JavaScript總是按價值通過。但是,使用對象,該值是對對象的引用。
⬆回到頂部
您可以使用箭頭函數來包裹事件處理程序並通過參數,這等同於調用bind :
< button onClick = { ( ) => this . handleClick ( id ) } />
< button onClick = { this . handleClick . bind ( this , id ) } / >
⬆回到頂部
片段允許通過對孩子進行分組而無需向DOM添加額外的元素,允許React組件返回多個沒有包裝器的元素。片段提供更好的性能,較低的內存使用情況,更清潔的DOM,並可以幫助處理某些CSS機制(例如表,Flexbox和Grid)。
render ( ) {
return (
< React . Fragment >
< ChildA />
< ChildB />
< ChildC />
</ React . Fragment >
) ;
}
// Short syntax supported by Babel 7
render ( ) {
return (
< >
< ChildA />
< ChildB />
< ChildC />
</ >
) ;
}
⬆回到頂部
pipe ,該功能管通過返回接受一個參數的函數來執行從左到右功能的組合。 const square = v => v * v
const double = v => v * 2
const addOne = v => v + 1
const res = pipe ( square , double , addOne )
res ( 3 ) // 19; addOne(double(square(3)))使用REST運算符收集所有提供的參數...並返回使用Array.prototype.reduce()在返回最終值之前通過一系列函數運行值。
const pipe = ( ... fns ) => x => fns . reduce ( ( v , fn ) => fn ( v ) , x )
⬆回到頂部
事件循環處理所有異步回調。回調是在循環中排隊的,而其他代碼則運行,並且在收到每個響應的響應時將一一運行。
⬆回到頂部
與任何比較操作員進行比較時, NaN (非數字)是唯一與自身相等的值。 NaN通常是毫無意義的數學計算的結果,因此兩個NaN值毫無意義地被認為是平等的。
isNaN()和Number.isNaN()之間的區別const isNaN = x => x !== xNaN的MDN文檔
⬆回到頂部
這兩個術語可以對比為:
在JavaScript中,物體是可變的,而原始值是不變的。這意味著在對像上執行的操作可以以某種方式更改原始參考,而以原始值進行的操作不能改變原始值。
所有String.prototype方法對原始字符串沒有影響並返回新字符串。另一方面,雖然某些Array.prototype的方法不會突變原始數組參考並產生新的陣列,但有些導致突變。
const myString = "hello!"
myString . replace ( "!" , "" ) // returns a new string, cannot mutate the original value
const originalArray = [ 1 , 2 , 3 ]
originalArray . push ( 4 ) // mutates originalArray, now [1, 2, 3, 4]
originalArray . concat ( 4 ) // returns a new array, does not mutate the original
⬆回到頂部
大o符號在計算機科學中用於描述算法的時間複雜性。最佳算法將執行最快的算法,並具有最簡單的複雜性。
算法並不總是相同的,並且可能會根據提供的數據而有所不同。在某些情況下,他們會迅速執行,但在其他情況下,即使要處理相同數量的要素,它們也會緩慢執行。
在這些示例中,基本時間為1個元素= 1ms 。
arr [ arr . length - 1 ]1ms恆定的時間複雜性。無論該數組具有多少個元素,理論上都將花費相同的執行時間(不包括現實世界的變化)。
arr . filter ( fn )1000ms線性時間複雜性。執行時間將隨數組的元素數量線性增加。如果數組具有1000個元素,並且該功能需要1毫秒來執行,則7000個元素將需要7ms才能執行。這是因為在返回結果之前,函數必須迭代數組的所有元素。
arr . some ( fn )1ms <= x <= 1000ms執行時間取決於提供給功能的數據,它可能會很早或很晚才返回。這裡最好的情況是o(1),最壞的情況是o(n)。
arr . sort ( fn )10000ms瀏覽器通常為sort()方法實現QuickSort算法,而QuickSort的平均時間複雜性為O(NLGN)。這對於大型收藏非常有效。
for ( let i = 0 ; i < arr . length ; i ++ ) {
for ( let j = 0 ; j < arr . length ; j ++ ) {
// ...
}
}1000000ms執行時間隨著元素數的數量而倍增。通常是嵌套環的結果。
const permutations = arr => {
if ( arr . length <= 2 ) return arr . length === 2 ? [ arr , [ arr [ 1 ] , arr [ 0 ] ] ] : arr
return arr . reduce (
( acc , item , i ) =>
acc . concat (
permutations ( [ ... arr . slice ( 0 , i ) , ... arr . slice ( i + 1 ) ] ) . map ( val => [
item ,
... val
] )
) ,
[ ]
)
}Infinity (實際上)MS執行時間的上升非常快,即使在數組中僅1個添加1個。
⬆回到頂部
純函數是滿足這兩個條件的函數:
只要滿足上述兩個條件,純函數就可以在函數中突變局部數據。
const a = ( x , y ) => x + y
const b = ( arr , value ) => arr . concat ( value )
const c = arr => [ ... arr ] . sort ( ( a , b ) => a - b ) const a = ( x , y ) => x + y + Math . random ( )
const b = ( arr , value ) => ( arr . push ( value ) , arr )
const c = arr => arr . sort ( ( a , b ) => a - b ) setInnerHTML ),否則所有功能都應純淨。
⬆回到頂部
遞歸是過程的重複應用。在JavaScript中,遞歸涉及將自己自重複自稱直至達到基本狀況的功能。基本條件會突破遞歸循環,因為否則該函數將無限期地調用自己。當使用包含嵌套的數據結構時,遞歸非常有用。
例如,您可能有一個從數據庫中返回的評論線,該數據庫存在於平面數組中,但需要嵌套以在UI中顯示。每個評論要么是頂級評論(沒有父母),要么是對父母評論的答复。評論可以是答复答复的回复...我們沒有事先知道,評論可能是深層的。這是遞歸可以提供幫助的地方。
const nest = ( items , id = null , link = "parent_id" ) =>
items
. filter ( item => item [ link ] === id )
. map ( item => ( { ... item , children : nest ( items , item . id ) } ) )
const comments = [
{ id : 1 , parent_id : null , text : "First reply to post." } ,
{ id : 2 , parent_id : 1 , text : "First reply to comment #1." } ,
{ id : 3 , parent_id : 1 , text : "Second reply to comment #1." } ,
{ id : 4 , parent_id : 3 , text : "First reply to comment #3." } ,
{ id : 5 , parent_id : 4 , text : "First reply to comment #4." } ,
{ id : 6 , parent_id : null , text : "Second reply to post." }
]
nest ( comments )
/*
[
{ id: 1, parent_id: null, text: "First reply to post.", children: [...] },
{ id: 6, parent_id: null, text: "Second reply to post.", children: [] }
]
*/在上面的示例中,如果filter()返回一個空數組,則滿足基本條件。鍊式map()不會調用包含遞歸調用的回調函數,從而破壞了循環。
⬆回到頂部
備忘錄是緩存函數調用輸出的過程,以使後續調用更快。再次使用相同輸入調用該函數將返回緩存的輸出,而無需再次進行計算。
JavaScript中的基本實現如下:
const memoize = fn => {
const cache = new Map ( )
return value => {
const cachedResult = cache . get ( value )
if ( cachedResult !== undefined ) return cachedResult
const result = fn ( value )
cache . set ( value , result )
return result
}
}
⬆回到頂部
REF提供了一種訪問渲染方法中創建的DOM節點或反應元素的方法。裁判應謹慎使用,但是有一些很好的用例,例如:
使用React.createRef()方法創建REFS,並通過ref屬性附加到React元素。為了在整個組件中使用refs,請將ref分配給構造函數中的實例屬性:
class MyComponent extends React . Component {
constructor ( props ) {
super ( props )
this . myRef = React . createRef ( )
}
render ( ) {
return < div ref = { this . myRef } />
}
}REF也可以在關閉的幫助下用於功能組件。
React.createRef()創建REF,並通過ref屬性連接到元素。
⬆回到頂部
這兩種類型的編程可以大致總結為:
聲明性編程的一個常見示例是CSS。開發人員指定了描述某物外觀而不是如何實現的CSS屬性。瀏覽器將“如何”抽像出來。
另一方面,命令式編程涉及實現目標所需的步驟。在JavaScript中,差異可以像這樣對比:
const numbers = [ 1 , 2 , 3 , 4 , 5 ]
const numbersDoubled = [ ]
for ( let i = 0 ; i < numbers . length ; i ++ ) {
numbersDoubled [ i ] = numbers [ i ] * 2
}我們在數組的數量上手動循環,並在數字加倍時分配新索引。
const numbers = [ 1 , 2 , 3 , 4 , 5 ]
const numbersDoubled = numbers . map ( n => n * 2 )我們聲明,新數組被映射到一個新陣列,其中每個值都會加倍。
⬆回到頂部
功能編程是一個範式,其中使用純粹的函數以避免共享狀態和可變數據的純函數以聲明性的方式構建程序。功能編程的支柱是始終返回相同輸入並且不產生副作用的相同值的功能。許多程序員認為這是軟件開發的最佳方法,因為它減少了錯誤和認知負荷。
.map , .reduce等)
⬆回到頂部
門戶是將兒童渲染到父組件層層次結構之外的DOM節點的推薦方法。
ReactDOM . createPortal ( child , container )第一個論點( child )是任何可渲染的反應子,例如元素,字符串或片段。第二個參數( container )是DOM元素。
⬆回到頂部
事件驅動的編程是一個範式,涉及構建發送和接收事件的應用程序。當程序發出事件時,程序會通過運行註冊到該事件和上下文的任何回調功能,將關聯數據傳遞給該功能。有了這種模式,即使沒有訂閱該功能,也可以將事件散發到野外而不會丟棄錯誤。
一個常見的例子是元素收聽DOM事件(例如click and mouseenter的模式,該事件發生時會在其中運行回調函數。
document . addEventListener ( "click" , function ( event ) {
// This callback function is run when the user
// clicks on the document.
} )沒有DOM的上下文,模式可能看起來像這樣:
const hub = createEventHub ( )
hub . on ( "message" , function ( data ) {
console . log ( ` ${ data . username } said ${ data . text } ` )
} )
hub . emit ( "message" , {
username : "John" ,
text : "Hello?"
} )通過此實現, on是訂閱事件的方法,而emit是發布事件的方式。
⬆回到頂部
上下文提供了一種將數據通過組件樹傳遞的方法,而無需在每個級別手動向下傳遞道具。例如,經過身份驗證的用戶,LOCALE首選項,需要通過許多組件在應用程序中訪問UI主題。
const { Provider , Consumer } = React . createContext ( defaultValue )
⬆回到頂部
靜態方法屬於類,並且不在實例上行動,而實例方法屬於類原型,該類型由類的所有實例繼承並在其上作用。
Array . isArray // static method of Array
Array . prototype . push // instance method of Array在這種情況下, Array.isArray方法作為數組的實例方法是沒有意義的,因為我們已經知道該值是在使用時的數組。
實例方法在技術上可以用作靜態方法,但提供Terser語法:
const arr = [ 1 , 2 , 3 ]
arr . push ( 4 )
Array . push ( arr , 4 )
⬆回到頂部
閉合是在另一個函數內定義的函數,即使在其詞彙範圍之外執行,也可以訪問其詞彙範圍。關閉可以訪問三個範圍的變量:
在JavaScript中,所有功能都是關閉的,因為它們都可以訪問外部範圍,但是大多數功能都不利用封閉的有用性:狀態的持久性。因此,關閉有時也稱為狀態功能。
此外,關閉是存儲無法從JavaScript中外部訪問的私人數據的唯一方法。它們是UMD(通用模塊定義)模式的關鍵,該模式經常在僅曝光公共API但將實現詳細信息私有的庫中使用,從而阻止了名稱與其他庫或用戶自己的代碼相撞。
⬆回到頂部
this關鍵字是什麼,它如何工作?this關鍵字是代表執行函數上下文的對象。常規功能可以通過方法call() , apply()和bind()更改其this值。箭頭功能隱含地綁定this ,以便它是指其詞彙環境的上下文,無論是否使用call()明確設置其上下文。
以下是一些this方式的常見示例:
如果對像在函數的調用之前, this指常規函數中的對象本身。
this的屬性不參考對象。
var myObject = {
property : this ,
regularFunction : function ( ) {
return this
} ,
arrowFunction : ( ) => {
return this
} ,
iife : ( function ( ) {
return this
} ) ( )
}
myObject . regularFunction ( ) // myObject
myObject [ "regularFunction" ] ( ) // my Object
myObject . property // NOT myObject; lexical `this`
myObject . arrowFunction ( ) // NOT myObject; lexical `this`
myObject . iife // NOT myObject; lexical `this`
const regularFunction = myObject . regularFunction
regularFunction ( ) // NOT myObject; lexical `this` this是指收聽事件的元素。
document . body . addEventListener ( "click" , function ( ) {
console . log ( this ) // document.body
} ) this是指新創建的對象。
class Example {
constructor ( ) {
console . log ( this ) // myExample
}
}
const myExample = new Example ( ) 使用call()和apply() , this指的是將對像作為第一個參數傳遞。
var myFunction = function ( ) {
return this
}
myFunction . call ( { customThis : true } ) // { customThis: true } this因為this可能會根據范圍而變化,因此使用常規功能時它可能具有意外的值。
var obj = {
arr : [ 1 , 2 , 3 ] ,
doubleArr ( ) {
return this . arr . map ( function ( value ) {
// this is now this.arr
return this . double ( value )
} )
} ,
double ( ) {
return value * 2
}
}
obj . doubleArr ( ) // Uncaught TypeError: this.double is not a function this是全局對象(瀏覽器中的window ),而在嚴格的模式中, this是undefined 。Function.prototype.call and Function.prototype.apply將執行函數的this上下文設置為第一個參數, call接受可變數量的參數, apply接受數組作為以變化方式將其作為第二個參數作為第二個參數。Function.prototype.bind返回一個新函數, this函數將此上下文強制執行為第一個參數,而其他函數無法更改。this ,則必須使用function關鍵字。當您希望this是周圍(詞彙)上下文時,請使用箭頭功能。 this在MDN上
⬆回到頂部
children道具是什麼?children是傳遞給組件的道具對象的一部分,這些對象可以將組件作為數據傳遞給其他組件,從而提供了構成組件的能力。 React API中有許多可與此Prop一起使用的方法,例如React.Children.map , React.Children.forEach , React.Children.count , React.Children.only和React.Children.toArray 。兒童道具的一個簡單用法如下:
function GenericBox ( { children } ) {
return < div className = "container" > { children } </ div >
}
function App ( ) {
return (
< GenericBox >
< span > Hello </ span > < span > World </ span >
</ GenericBox >
)
}
⬆回到頂部
由於findDOMNode()可防止將來的React的某些改進,因此首選回調Refs比findDOMNode() API首選。
// Legacy approach using findDOMNode()
class MyComponent extends Component {
componentDidMount ( ) {
findDOMNode ( this ) . scrollIntoView ( )
}
render ( ) {
return < div />
}
}
// Recommended approach using callback refs
class MyComponent extends Component {
componentDidMount ( ) {
this . node . scrollIntoView ( )
}
render ( ) {
return < div ref = { node => ( this . node = node ) } />
}
} findDOMNode() 。
⬆回到頂部
主要目的是避免直接操縱DOM,並使應用程序的狀態與UI輕鬆同步。此外,它們還提供了創建組件的能力,這些組件可以在具有較小差異的功能相似的功能時可以重複使用,避免重複,每當要在多個位置重複使用的組件的結構需要更新時,就需要進行多次更改。
當使用諸如jQuery之類的DOM操作庫時,應用程序的數據通常保存在DOM本身中,通常是類名稱或data屬性。操縱DOM以更新UI涉及許多額外的步驟,並且可以隨著時間的推移引入細微的錯誤。保持狀態分開,並讓框架在狀態變化時處理UI更新會減少認知負載。說您希望在狀態為某個值時以某種方式看起來某種方式是創建應用程序的聲明方式,而不是手動更新UI以反映新狀態的命令方式。
⬆回到頂部
'use strict'是什麼,使用它有哪些關鍵好處?在JavaScript源文件的開頭中包括'use strict'啟用嚴格模式,該模式可以實施更嚴格的解析和錯誤處理JavaScript代碼。這被認為是一種好習慣,並提供了很多好處,例如:
eval()和arguments 。this脅迫,當this引用一個null或undefined的值時,會引發錯誤。delete無效的使用情況下引發錯誤。
⬆回到頂部
getData ( function ( a ) {
getMoreData ( a , function ( b ) {
getMoreData ( b , function ( c ) {
getMoreData ( c , function ( d ) {
getMoreData ( d , function ( e ) {
// ...
} )
} )
} )
} )
} )重構功能以返回承諾並使用async/await功能通常是最佳選擇。他們沒有提供引起深嵌套的回調,而是返回可以await的諾言,一旦數據到達,就可以解決,從而可以以同步的方式評估下一條代碼。
以上代碼可以像這樣重組:
async function asyncAwaitVersion ( ) {
const a = await getData ( )
const b = await getMoreData ( a )
const c = await getMoreData ( b )
const d = await getMoreData ( c )
const e = await getMoreData ( d )
// ...
}有很多方法可以解決回調地獄問題:
⬆回到頂部
虛擬DOM(VDOR)是平原JavaScript對象的形式的真實DOM的表示。這些對象具有描述它們代表的真實DOM節點的屬性:節點名稱,其屬性和子節點。
< div class =" counter " >
< h1 > 0 </ h1 >
< button > - </ button >
< button > + </ button >
</ div >以上標記的虛擬DOM表示可能看起來像:
{
nodeName : "div" ,
attributes : { class : "counter" } ,
children : [
{
nodeName : "h1" ,
attributes : { } ,
children : [ 0 ]
} ,
{
nodeName : "button" ,
attributes : { } ,
children : [ "-" ]
} ,
{
nodeName : "button" ,
attributes : { } ,
children : [ "+" ]
}
]
}庫/框架使用虛擬DOM作為提高性能的手段。當應用程序的狀態更改時,需要對真實的DOM進行更新以反映它。但是,與重新計算虛擬DOM相比,更改真實的DOM節點的成本高昂。相比之下,可以非常快速地將上一個虛擬DOM與新的虛擬DOM進行比較。
一旦通過框架的擴散引擎計算了舊的vdom和新vdom之間的更改,就可以在最小的時間內有效地修補實際DOM以匹配應用程序的新狀態。
⬆回到頂部
this上下文?在JavaScript類中,這些方法默認不在限制。這意味著可以更改其this上下文(對於事件處理程序,轉換為正在收聽事件的元素),並且不會參考組件實例。要解決此問題, Function.prototype.bind()可以用來this上下文作為組件實例強制執行。
constructor ( props ) {
super ( props ) ;
this . handleClick = this . handleClick . bind ( this ) ;
}
handleClick ( ) {
// Perform some logic
}bind方法可以是冗長的,需要定義constructor ,因此通常優選新的公共類字段語法: handleClick = ( ) => {
console . log ( 'this is:' , this ) ;
}
render ( ) {
return (
< button onClick = { this . handleClick } >
Click me
</ button >
) ;
}this (指組件實例): < button onClick = { e => this . handleClick ( e ) } > Click me </ button >請注意,可以使用此技術進行額外的重新渲染,因為在渲染上創建了新功能參考,該函數參考將傳遞給子組件,而Breaks shouldComponentUpdate / purecomponent / PureComponent shallow均等檢查以防止不必要的重新呈現。在性能很重要的情況下,首選與構造函數或公共類字段語法方法bind在一起,因為函數參考保持恆定。
⬆回到頂部
無狀態組件是其行為不取決於其狀態的組件。無狀態組件可以是功能或類成分。無狀態的功能組件更易於維護和測試,因為它們可以保證在相同的道具下產生相同的輸出。當不需要使用生命週期掛鉤時,應首選無狀態的功能組件。
this關鍵字。
⬆回到頂部
狀態組件是其行為取決於其狀態的組成部分。這意味著與純函數組件不同,如果給出相同的道具,則組件的兩個單獨實例不一定會呈現相同的輸出。
// Stateful class component
class App extends Component {
constructor ( props ) {
super ( props )
this . state = { count : 0 }
}
render ( ) {
// ...
}
}
// Stateful function component
function App ( ) {
const [ count , setCount ] = useState ( 0 )
return // ...
} useState()中初始化。
⬆回到頂部
註釋必須包裹在捲曲括號內{}並使用/* */語法。
const tree = (
< div >
{ /* Comment */ }
< p > Text </ p >
</ div >
)
⬆回到頂部
元素是代表DOM節點或組件的普通JavaScript對象。元素是純淨的,永遠不會變異,而且創造便宜。
組件是函數或類。組件可以具有狀態並將道具作為輸入,並將元素樹作為輸出返回(儘管它們可以代表通用容器或包裝器,並且不一定要發射DOM)。組件可以啟動生命週期方法的副作用(例如AJAX請求,DOM突變,與第三方庫的接口),並且創建可能很昂貴。
const Component = ( ) => "Hello"
const componentElement = < Component />
const domNodeElement = < div />
⬆回到頂部
當幾個組件需要共享相同的數據時,建議將共享狀態提升到其最接近的共同祖先。例如,如果兩個子組件共享相同的數據,建議將共享狀態移至父母,而不是維護兩個子組件中的局部狀態。
⬆回到頂部
className而不是html中的class ?React一開始的哲學是與瀏覽器DOM API保持一致,而不是HTML,因為這更緊密地代表了元素的創建方式。在元素上設置class是指使用className API:
const element = document . createElement ( "div" )
element . className = "hello"此外,在ES5之前,保留的單詞不能在對像中使用:
const element = {
attributes : {
class : "hello"
}
}在IE8中,這將丟失錯誤。
在現代環境中,如果試圖分配變量,破壞性將引發錯誤:
const { class } = this . props // Error
const { className } = this . props // All good
const { class : className } = this . props // All good, but cumbersome!但是, class可以用作沒有問題的道具,如其他庫中所示。 React當前允許您使用class ,但會發出警告並將其轉換為引擎蓋下的className 。目前有一個開放線程(截至2019年1月)討論更改className以減少混亂的class 。
⬆回到頂部
您可以使用箭頭函數來包裹事件處理程序並通過參數,這等同於調用bind :
< button onClick = { ( ) => this . handleClick ( id ) } />
< button onClick = { this . handleClick . bind ( this , id ) } / >
⬆回到頂部
setState的參數的目的是什麼?setState完成並渲染組件後,調用回調功能。由於setState是異步的,因此回調函數用於任何後操作。
setState ( { name : "sudheer" } , ( ) => {
console . log ( "The name has updated and component re-rendered" )
} ) setState完成後調用回調功能,並用於任何後操作。setState上的react文檔
⬆回到頂部
There are four different phases of component's lifecycle:
Initialization : In this phase, the component prepares setting up the initial state and default props.
Mounting : The react component is ready to mount to the DOM. This phase covers the getDerivedStateFromProps and componentDidMount lifecycle methods.
Updating : In this phase, the component gets updated in two ways, sending the new props and updating the state. This phase covers the getDerivedStateFromProps , shouldComponentUpdate , getSnapshotBeforeUpdate and componentDidUpdate lifecycle methods.
Unmounting : In this last phase, the component is not needed and gets unmounted from the browser DOM. This phase includes the componentWillUnmount lifecycle method.
Error Handling : In this phase, the component is called whenever there's an error during rendering, in a lifecycle method, or in the constructor for any child component. This phase includes the componentDidCatch lifecycle method.
⬆回到頂部
在HTML中,屬性名稱均在所有小寫字母中,並給出一個字符串,調用在某處定義的函數:
< button onclick =" handleClick() " > </ button >In React, the attribute name is camelCase and are passed the function reference inside curly braces:
< button onClick = { handleClick } /> In HTML, false can be returned to prevent default behavior, whereas in React preventDefault has to be called explicitly.
< a href =" # " onclick =" console.log('The link was clicked.'); return false " /> function handleClick ( e ) {
e . preventDefault ( )
console . log ( "The link was clicked." )
}
⬆回到頂部
Since a JSX element tree is one large expression, you cannot embed statements inside. Conditional expressions act as a replacement for statements to use inside the tree.
For example, this won't work:
function App ( { messages , isVisible } ) {
return (
< div >
if (messages.length > 0 ) {
< h2 > You have { messages . length } unread messages. </ h2 >
} else {
< h2 > You have no unread messages. </ h2 >
}
if (isVisible) {
< p > I am visible. </ p >
}
</ div >
)
} Logical AND && and the ternary ? : operator replace the if / else statements.
function App ( { messages , isVisible } ) {
return (
< div >
{ messages . length > 0 ? (
< h2 > You have { messages . length } unread messages. </ h2 >
) : (
< h2 > You have no unread messages. </ h2 >
) }
{ isVisible && < p > I am visible. </ p > }
</ div >
)
}
⬆回到頂部
getDerivedStateFromProps : Executed before rendering on the initial mount and all component updates. Used to update the state based on changes in props over time. Has rare use cases, like tracking component animations during the lifecycle. There are only few cases where this makes sense to use over other lifecycle methods. It expects to return an object that will be the the new state, or null to update nothing. This method does not have access to the component instance either.
componentDidMount : Executed after first rendering and here all AJAX requests, DOM or state updates, and set up eventListeners should occur.
shouldComponentUpdate : Determines if the component will be updated or not. By default, it returns true. If you are sure that the component doesn't need to render after state or props are updated, you can return a false value. It is a great place to improve performance as it allows you to prevent a rerender if component receives new prop.
getSnapshotBeforeUpdate : Invoked right after a component render happens because of an update, before componentDidUpdate . Any value returned from this method will be passed to componentDidUpdate .
componentDidUpdate : Mostly it is used to update the DOM in response to prop or state changes.
componentWillUnmount : It will be used to cancel any outgoing network requests, or remove all event listeners associated with the component.
componentDidCatch : Used in error boundaries, which are components that implement this method. It allows the component to catch JavaScript errors anywhere in the child component tree (below this component), log errors, and display a UI with error information.
⬆回到頂部
Keys are a special string attribute that helps React identify which items have been changed, added or removed. They are used when rendering array elements to give them a stable identity. Each element's key must be unique (eg IDs from the data or indexes as a last resort).
const todoItems = todos . map ( todo => < li key = { todo . id } > { todo . text } </ li > )<li> tag. <li> element, if you extract list items as components.
⬆回到頂部
Callback refs are preferred over the findDOMNode() API, due to the fact that findDOMNode() prevents certain improvements in React in the future.
// Legacy approach using findDOMNode()
class MyComponent extends Component {
componentDidMount ( ) {
findDOMNode ( this ) . scrollIntoView ( )
}
render ( ) {
return < div />
}
}
// Recommended approach using callback refs
class MyComponent extends Component {
componentDidMount ( ) {
this . node . scrollIntoView ( )
}
render ( ) {
return < div ref = { node => ( this . node = node ) } />
}
} findDOMNode() .
⬆回到頂部
Fragments allow a React component to return multiple elements without a wrapper, by grouping the children without adding extra elements to the DOM. Fragments offer better performance, lower memory usage, a cleaner DOM and can help in dealing with certain CSS mechanisms (eg tables, Flexbox and Grid).
render ( ) {
return (
< React . Fragment >
< ChildA />
< ChildB />
< ChildC />
</ React . Fragment >
) ;
}
// Short syntax supported by Babel 7
render ( ) {
return (
< >
< ChildA />
< ChildB />
< ChildC />
</ >
) ;
}
⬆回到頂部
this上下文?In JavaScript classes, the methods are not bound by default. This means that their this context can be changed (in the case of an event handler, to the element that is listening to the event) and will not refer to the component instance. To solve this, Function.prototype.bind() can be used to enforce the this context as the component instance.
constructor ( props ) {
super ( props ) ;
this . handleClick = this . handleClick . bind ( this ) ;
}
handleClick ( ) {
// Perform some logic
}bind approach can be verbose and requires defining a constructor , so the new public class fields syntax is generally preferred: handleClick = ( ) => {
console . log ( 'this is:' , this ) ;
}
render ( ) {
return (
< button onClick = { this . handleClick } >
Click me
</ button >
) ;
}this (referring to the component instance) is preserved: < button onClick = { e => this . handleClick ( e ) } > Click me </ button > Note that extra re-rendering can occur using this technique because a new function reference is created on render, which gets passed down to child components and breaks shouldComponentUpdate / PureComponent shallow equality checks to prevent unnecessary re-renders. In cases where performance is important, it is preferred to go with bind in the constructor, or the public class fields syntax approach, because the function reference remains constant.
⬆回到頂部
Error boundaries are React components that catch JavaScript errors anywhere in their child component tree, log those errors, and display a fallback UI instead of the component tree that crashed.
Class components become error boundaries if they define either (or both) of the lifecycle methods static getDerivedStateFromError() or componentDidCatch().
class ErrorBoundary extends React . Component {
constructor ( props ) {
super ( props )
this . state = { hasError : false }
}
// Use componentDidCatch to log the error
componentDidCatch ( error , info ) {
// You can also log the error to an error reporting service
logErrorToMyService ( error , info )
}
// use getDerivedStateFromError to update state
static getDerivedStateFromError ( error ) {
// Display fallback UI
return { hasError : true } ;
}
render ( ) {
if ( this . state . hasError ) {
// You can render any custom fallback UI
return < h1 > Something went wrong. </ h1 >
}
return this . props . children
}
}
⬆回到頂部
A higher-order component (HOC) is a function that takes a component as an argument and returns a new component. It is a pattern that is derived from React's compositional nature. Higher-order components are like pure components because they accept any dynamically provided child component, but they won't modify or copy any behavior from their input components.
const EnhancedComponent = higherOrderComponent ( WrappedComponent )
⬆回到頂部
When the application is running in development mode, React will automatically check for all props that we set on components to make sure they are the correct data type. For incorrect data types, it will generate warning messages in the console for development mode. They are stripped in production mode due to their performance impact. Required props are defined with isRequired .
For example, we define propTypes for component as below:
import PropTypes from "prop-types"
class User extends React . Component {
static propTypes = {
name : PropTypes . string . isRequired ,
age : PropTypes . number . isRequired
}
render ( ) {
return (
< h1 > Welcome, { this . props . name } </ h1 >
< h2 > Age , { this . props . age }
)
}
} propTypespropTypes is not mandatory. However, it is a good practice and can reduce bugs.
⬆回到頂部
Context provides a way to pass data through the component tree without having to pass props down manually at every level. For example, authenticated user, locale preference, UI theme need to be accessed in the application by many components.
const { Provider , Consumer } = React . createContext ( defaultValue )
⬆回到頂部
Refs provide a way to access DOM nodes or React elements created in the render method. Refs should be used sparringly, but there are some good use cases for refs, such as:
Refs are created using React.createRef() method and attached to React elements via the ref attribute. In order to use refs throughout the component, assign the ref to the instance property within the constructor:
class MyComponent extends React . Component {
constructor ( props ) {
super ( props )
this . myRef = React . createRef ( )
}
render ( ) {
return < div ref = { this . myRef } />
}
}Refs can also be used in functional components with the help of closures.
React.createRef() and attach to elements via the ref attribute.
⬆回到頂部
children道具是什麼?children is part of the props object passed to components that allows components to be passed as data to other components, providing the ability to compose components cleanly. There are a number of methods available in the React API to work with this prop, such as React.Children.map , React.Children.forEach , React.Children.count , React.Children.only and React.Children.toArray . A simple usage example of the children prop is as follows:
function GenericBox ( { children } ) {
return < div className = "container" > { children } </ div >
}
function App ( ) {
return (
< GenericBox >
< span > Hello </ span > < span > World </ span >
</ GenericBox >
)
}
⬆回到頂部
Portal are the recommended way to render children into a DOM node that exists outside the DOM hierarchy of the parent component.
ReactDOM . createPortal ( child , container ) The first argument ( child ) is any renderable React child, such as an element, string, or fragment. The second argument ( container ) is a DOM element.
⬆回到頂部
alt屬性的目的是什麼?The alt attribute provides alternative information for an image if a user cannot view it. The alt attribute should be used to describe any images except those which only serve a decorative purpose, in which case it should be left empty.
alt attribute.alt tags to understand image content, so they are considered important for Search Engine Optimization (SEO).. at the end of alt tag to improve accessibility.
⬆回到頂部
Browsers have a cache to temporarily store files on websites so they don't need to be re-downloaded again when switching between pages or reloading the same page. The server is set up to send headers that tell the browser to store the file for a given amount of time. This greatly increases website speed and preserves bandwidth.
However, it can cause problems when the website has been changed by developers because the user's cache still references old files. This can either leave them with old functionality or break a website if the cached CSS and JavaScript files are referencing elements that no longer exist, have moved or have been renamed.
Cache busting is the process of forcing the browser to download the new files. This is done by naming the file something different to the old file.
A common technique to force the browser to re-download the file is to append a query string to the end of the file.
src="js/script.js" => src="js/script.js?v=2"The browser considers it a different file but prevents the need to change the file name.
⬆回到頂部
<header>元素嗎? <footer>元素呢?是的。 The W3 documents state that the tags represent the header( <header> ) and footer( <footer> ) areas of their nearest ancestor "section". So not only can the page <body> contain a header and a footer, but so can every <article> and <section> element.
⬆回到頂部
<header> , <article> , <section> , <footer><header> is used to contain introductory and navigational information about a section of the page. This can include the section heading, the author's name, time and date of publication, table of contents, or other navigational information.
<article> is meant to house a self-contained composition that can logically be independently recreated outside of the page without losing its meaning. Individual blog posts or news stories are good examples.
<section> is a flexible container for holding content that shares a common informational theme or purpose.
<footer> is used to hold information that should appear at the end of a section of content and contain additional information about the section. Author's name, copyright information, and related links are typical examples of such content.
<form> and <table>
⬆回到頂部
rel="noopener"屬性在哪里以及為什麼使用?The rel="noopener" is an attribute used in <a> elements (hyperlinks). It prevents pages from having a window.opener property, which would otherwise point to the page from where the link was opened and would allow the page opened from the hyperlink to manipulate the page where the hyperlink is.
rel="noopener" is applied to hyperlinks.rel="noopener" prevents opened links from manipulating the source page.
⬆回到頂部
<script>標籤上的defer和async屬性是什麼?If neither attribute is present, the script is downloaded and executed synchronously, and will halt parsing of the document until it has finished executing (default behavior). Scripts are downloaded and executed in the order they are encountered.
The defer attribute downloads the script while the document is still parsing but waits until the document has finished parsing before executing it, equivalent to executing inside a DOMContentLoaded event listener. defer scripts will execute in order.
The async attribute downloads the script during parsing the document but will pause the parser to execute the script before it has fully finished parsing. async scripts will not necessarily execute in order.
Note: both attributes must only be used if the script has a src attribute (ie not an inline script).
< script src =" myscript.js " > </ script >
< script src =" myscript.js " defer > </ script >
< script src =" myscript.js " async > </ script > defer script in the <head> allows the browser to download the script while the page is still parsing, and is therefore a better option than placing the script before the end of the body.defer .async .defer if the DOM must be ready and the contents are not placed within a DOMContentLoaded listener.
⬆回到頂部
在HTML中,屬性名稱均在所有小寫字母中,並給出一個字符串,調用在某處定義的函數:
< button onclick =" handleClick() " > </ button >In React, the attribute name is camelCase and are passed the function reference inside curly braces:
< button onClick = { handleClick } /> In HTML, false can be returned to prevent default behavior, whereas in React preventDefault has to be called explicitly.
< a href =" # " onclick =" console.log('The link was clicked.'); return false " /> function handleClick ( e ) {
e . preventDefault ( )
console . log ( "The link was clicked." )
}
⬆回到頂部
Some of the key differences are:
<DOCTYPE>checked="checked" instead of checked )
⬆回到頂部
DOM(文檔對像模型)是一種跨平台API,將HTML和XML文檔視為由節點組成的樹結構。這些節點(例如元素和文本節點)是可以通過編程方式操縱的對象,並且對其進行的任何可見更改都會反映在文檔中。在瀏覽器中,該API可用於JavaScript,可以操縱DOM節點以更改其樣式,內容,文檔中的位置或通過事件聽眾進行交互。
<head>帶有defer屬性,或者在DOMContentLoaded Event ockiter中。在構造DOM之後,應運行操縱DOM節點的腳本以避免錯誤。document.getElementById()和document.querySelector()是選擇DOM節點的常見函數。innerHTML屬性設置為新值可以通過HTML解析器運行字符串,從而提供了一種簡單的方法,可以將動態HTML內容附加到節點。
⬆回到頂部
HTML specifications such as HTML5 define a set of rules that a document must adhere to in order to be “valid” according to that specification. In addition, a specification provides instructions on how a browser must interpret and render such a document.
A browser is said to “support” a specification if it handles valid documents according to the rules of the specification. As of yet, no browser supports all aspects of the HTML5 specification (although all of the major browser support most of it), and as a result, it is necessary for the developer to confirm whether the aspect they are making use of will be supported by all of the browsers on which they hope to display their content. This is why cross-browser support continues to be a headache for developers, despite the improved specificiations.
HTML5 defines some rules to follow for an invalid HTML5 document (ie, one that contains syntactical errors)
⬆回到頂部
localStorage和sessionStorage 。With HTML5, web pages can store data locally within the user's browser. The data is stored in name/value pairs, and a web page can only access data stored by itself.
Differences between localStorage and sessionStorage regarding lifetime:
localStorage is permanent: it does not expire and remains stored on the user's computer until a web app deletes it or the user asks the browser to delete it.sessionStorage has the same lifetime as the top-level window or browser tab in which the data got stored. When the tab is permanently closed, any data stored through sessionStorage is deleted. Differences between localStorage and sessionStorage regarding storage scope: Both forms of storage are scoped to the document origin so that documents with different origins will never share the stored objects.
sessionStorage is also scoped on a per-window basis. Two browser tabs with documents from the same origin have separate sessionStorage data.localStorage , the same scripts from the same origin can't access each other's sessionStorage when opened in different tabs.
⬆回到頂部
The BEM methodology is a naming convention for CSS classes in order to keep CSS more maintainable by defining namespaces to solve scoping issues. BEM stands for Block Element Modifier which is an explanation for its structure. A Block is a standalone component that is reusable across projects and acts as a "namespace" for sub components (Elements). Modifiers are used as flags when a Block or Element is in a certain state or is different in structure or style.
/* block component */
. block {
}
/* element */
. block__element {
}
/* modifier */
. block__element--modifier {
}Here is an example with the class names on markup:
< nav class =" navbar " >
< a href =" / " class =" navbar__link navbar__link--active " > </ a >
< a href =" / " class =" navbar__link " > </ a >
< a href =" / " class =" navbar__link " > </ a >
</ nav > In this case, navbar is the Block, navbar__link is an Element that makes no sense outside of the navbar component, and navbar__link--active is a Modifier that indicates a different state for the navbar__link Element.
Since Modifiers are verbose, many opt to use is-* flags instead as modifiers.
< a href =" / " class =" navbar__link is-active " > </ a >These must be chained to the Element and never alone however, or there will be scope issues.
. navbar__link . is-active {
}
⬆回到頂部
CSS preprocessors add useful functionality that native CSS does not have, and generally make CSS neater and more maintainable by enabling DRY (Don't Repeat Yourself) principles. Their terse syntax for nested selectors cuts down on repeated code. They provide variables for consistent theming (however, CSS variables have largely replaced this functionality) and additional tools like color functions ( lighten , darken , transparentize , etc), mixins, and loops that make CSS more like a real programming language and gives the developer more power to generate complex CSS.
⬆回到頂部
col-{n} / 12比率。 < div class =" row " >
< div class =" col-2 " > </ div >
< div class =" col-7 " > </ div >
< div class =" col-3 " > </ div >
</ div >Set the .row parent to display: flex; and use the flex shorthand property to give the column classes a flex-grow value that corresponds to its ratio value.
. row {
display : flex;
}
. col-2 {
flex : 2 ;
}
. col-7 {
flex : 7 ;
}
. col-3 {
flex : 3 ;
}
⬆回到頂部
@media屬性的四種類型嗎?all , which applies to all media type devicesprint , which only applies to printersscreen , which only applies to screens (desktops, tablets, mobile etc.)speech , which only applies to screenreaders @media rule
⬆回到頂部
Content : The inner-most part of the box filled with content, such as text, an image, or video player. It has the dimensions content-box width and content-box height .
Padding : The transparent area surrounding the content. It has dimensions padding-box width and padding-box height .
Border : The area surrounding the padding (if any) and content. It has dimensions border-box width and border-box height .
Margin : The transparent outer-most layer that surrounds the border. It separates the element from other elements in the DOM. It has dimensions margin-box width and margin-box height .
⬆回到頂部
em和rem單位有什麼區別?Both em and rem units are based on the font-size CSS property. The only difference is where they inherit their values from.
em units inherit their value from the font-size of the parent elementrem units inherit their value from the font-size of the root element ( html ) In most browsers, the font-size of the root element is set to 16px by default.
em and rem units
⬆回到頂部
CSS sprites combine multiple images into one image, limiting the number of HTTP requests a browser has to make, thus improving load times. Even under the new HTTP/2 protocol, this remains true.
Under HTTP/1.1, at most one request is allowed per TCP connection. With HTTP/1.1, modern browsers open multiple parallel connections (between 2 to 8) but it is limited. With HTTP/2, all requests between the browser and the server are multiplexed on a single TCP connection. This means the cost of opening and closing multiple connections is mitigated, resulting in a better usage of the TCP connection and limits the impact of latency between the client and server. It could then become possible to load tens of images in parallel on the same TCP connection.
However, according to benchmark results, although HTTP/2 offers 50% improvement over HTTP/1.1, in most cases the sprite set is still faster to load than individual images.
To utilize a spritesheet in CSS, one would use certain properties, such as background-image , background-position and background-size to ultimately alter the background of an element.
background-image , background-position and background-size can be used to utilize a spritesheet.
⬆回到頂部
The General Sibling Selector ~ selects all elements that are siblings of a specified element.
The following example selects all <p> elements that are siblings of <div> elements:
div ~ p {
background-color : blue;
} The Adjacent Sibling Selector + selects all elements that are the adjacent siblings of a specified element.
The following example will select all <p> elements that are placed immediately after <div> elements:
div + p {
background-color : red;
}
⬆回到頂部
Assuming the browser has already determined the set of rules for an element, each rule is assigned a matrix of values, which correspond to the following from highest to lowest specificity:
When two selectors are compared, the comparison is made on a per-column basis (eg an id selector will always be higher than any amount of class selectors, as ids have higher specificity than classes). In cases of equal specificity between multiple rules, the rules that comes last in the page's style sheet is deemed more specific and therefore applied to the element.
⬆回到頂部
A focus ring is a visible outline given to focusable elements such as buttons and anchor tags. It varies depending on the vendor, but generally it appears as a blue outline around the element to indicate it is currently focused.
In the past, many people specified outline: 0; on the element to remove the focus ring. However, this causes accessibility issues for keyboard users because the focus state may not be clear. When not specified though, it causes an unappealing blue ring to appear around an element.
In recent times, frameworks like Bootstrap have opted to use a more appealing box-shadow outline to replace the default focus ring. However, this is still not ideal for mouse users.
The best solution is an upcoming pseudo-selector :focus-visible which can be polyfilled today with JavaScript. It will only show a focus ring if the user is using a keyboard and leave it hidden for mouse users. This keeps both aesthetics for mouse use and accessibility for keyboard use.
⬆回到頂部
WCAG stands for "Web Content Accessibility Guidelines". It is a standard describing how to make web content more accessible to people with disabilities They have 12-13 guidelines and for each one, there are testable success criteria, which are at three levels: A, AA, and AAA. The higher the level, the higher the impact on the design of the web content. The higher the level, the web content is essentially more accessible by more users. Depending on where you live/work, there may be regulations requiring websites to meet certain levels of compliance. For instance, in Ontario, Canada, beginning January 1, 2021 all public websites and web content posted after January 1, 2012 must meet AA compliance.
⬆回到頂部
ARIA stands for "Accessible Rich Internet Applications", and is a technical specification created by the World Wide Web Consortium (W3C). Better known as WAI-ARIA, it provides additional HTML attributes in the development of web applications to offer people who use assistive technologies (AT) a more robust and interoperable experience with dynamic components. By providing the component's role, name, and state, AT users can better understand how to interact with the component. WAI-ARIA should only be used when an HTML element equivalent is not available or lacks full browser or AT support. WAI-ARIA's semantic markup coupled with JavaScript works to provide an understandable and interactive experience for people who use AT.
An example using ARIA:
<div
role="combobox"
aria-expanded="false"
aria-owns="ex1-grid"
aria-haspopup="grid"
id="ex1-combobox">
...
</div>
Credit: W3C's ARIA 1.1 Combobox with Grid Popup Example
⬆回到頂部
The Accessibility Tree is a structure produced by the browser's Accessibility APIs which provides accessibility information to assistive technologies such as screen readers. It runs parallel to the DOM and is similar to the DOM API, but with much fewer nodes, because a lot of that information is only useful for visual presentation. By writing semantic HTML we can take advantage of this process in creating an accessible experience for our users.
⬆回到頂部
Landmark roles is a way to identify different sections of a page like the main content or a navigation region. The Landmarks helps assistive technology users to navigate a page, allowing them skip over areas of it.
例如,
< div id =" header " role =" banner " > Header of the Page </ div >
< div id =" content " role =" main " > Main Content Goes Here </ div >
⬆回到頂部
fs . readFile ( filePath , function ( err , data ) {
if ( err ) {
// handle the error, the return is important here
// so execution stops here
return console . log ( err )
}
// use the data object
console . log ( data )
} )優點包括:
As you can see from below example, the callback is called with null as its first argument if there is no error. However, if there is an error, you create an Error object, which then becomes the callback's only parameter. The callback function allows a user to easily know whether or not an error occurred.
This practice is also called the Node.js error convention , and this kind of callback implementations are called error-first callbacks .
var isTrue = function ( value , callback ) {
if ( value === true ) {
callback ( null , "Value was true." )
} else {
callback ( new Error ( "Value is not true!" ) )
}
}
var callback = function ( error , retval ) {
if ( error ) {
console . log ( error )
return
}
console . log ( retval )
}
isTrue ( false , callback )
isTrue ( true , callback )
/*
{ stack: [Getter/Setter],
arguments: undefined,
type: undefined,
message: 'Value is not true!' }
Value was true.
*/
⬆回到頂部
REST (REpresentational State Transfer) is a software design pattern for network architecture. A RESTful web application exposes data in the form of information about its resources.
Generally, this concept is used in web applications to manage state. With most applications, there is a common theme of reading, creating, updating, and destroying data. Data is modularized into separate tables like posts , users , comments , and a RESTful API exposes access to this data with:
Here is an example of the URL and HTTP method with a posts resource:
/posts/ => GET/posts/new => POST/posts/:id => PUT/posts/:id => DELETE
⬆回到頂部
getData ( function ( a ) {
getMoreData ( a , function ( b ) {
getMoreData ( b , function ( c ) {
getMoreData ( c , function ( d ) {
getMoreData ( d , function ( e ) {
// ...
} )
} )
} )
} )
} )Refactoring the functions to return promises and using async/await is usually the best option. Instead of supplying the functions with callbacks that cause deep nesting, they return a promise that can be await ed and will be resolved once the data has arrived, allowing the next line of code to be evaluated in a sync-like fashion.
The above code can be restructured like so:
async function asyncAwaitVersion ( ) {
const a = await getData ( )
const b = await getMoreData ( a )
const c = await getMoreData ( b )
const d = await getMoreData ( c )
const e = await getMoreData ( d )
// ...
}There are lots of ways to solve the issue of callback hells:
⬆回到頂部
The event loop handles all async callbacks. Callbacks are queued in a loop, while other code runs, and will run one by one when the response for each one has been received.
⬆回到頂部
XSS是指攻擊者將惡意腳本注入合法網站或Web應用程序的客戶端代碼注入。當應用程序未驗證用戶輸入並自由注入動態HTML內容時,通常可以實現這一點。
例如,如果評論系統不驗證或逃脫用戶輸入,則將處於危險之中。如果該評論包含未設計的HTML,則該註釋可以將<script>標籤注入其他用戶會根據其知識執行的網站。
textContent而不是innerHTML可防止瀏覽器通過HTML解析器運行字符串,該解析器將在其中執行腳本。
⬆回到頂部
MIT. Copyright (c) Stefan Feješ.