
이 readme는 Markdown-Builder를 사용하여 구축되었습니다.
인터뷰는 어려우며 가장 노련한 전문가조차도 압력을받는 것을 잊게 만들 수 있습니다. 커뮤니티가 대답 한 인터뷰에서 일반적으로 어떤 질문에 직면하고 있는지 검토하고 배우십시오. 경험과 실제 사례를 하나로 모으면 긴장에서 다음 큰 기회에 대비할 수 있습니다.

30 초의 인터뷰는 커뮤니티 노력이므로 가능한 모든 방법으로 자유롭게 기여하십시오. 모든 기여가 도움이됩니다!
훌륭한 아이디어가 있거나 목록에없는 멋진 질문을 알고 있습니까? 기여 가이드 라인을 읽고 풀 요청을 제출하십시오.
프로젝트 개발을 돕기 위해 Gitter 채널에 가입하십시오.
batches 만듭니다.bind 작성하여 메소드 Function.prototype.bind 와 기능적으로 동일합니다.setState 의 주장으로서 무엇입니까?children 소품은 무엇입니까?== 및 === 의 차이점은 무엇입니까?0.1 + 0.2 === 0.3 무엇을 평가합니까?map() 와 forEach() 의 차이점은 무엇입니까?# 로 문자열을 마스킹하는 함수를 만듭니다.this 컨텍스트를 올바르게 갖도록하려면 어떻게해야합니까?null 과 undefined 의 차이점은 무엇입니까?pipe 만듭니다.i++ 와 Prefix ++i 증가 연산자의 차이점은 무엇입니까?this 키워드는 무엇이며 어떻게 작동합니까?'use strict' 은 무엇을 사용하고 그것을 사용하는 데있어 주요 이점은 무엇입니까?var , let , const 및 키워드 명세서의 차이점은 무엇입니까?setState 의 주장으로서 무엇입니까?children 소품은 무엇입니까?class 대신 className 사용합니까?this 컨텍스트를 올바르게 갖도록하려면 어떻게해야합니까?alt 속성의 목적은 무엇입니까?<script> 태그의 defer 및 async 속성은 무엇입니까?<header> 요소가 포함될 수 있습니까? <footer> 요소는 어떻습니까?<header> , <article> , <section> , <footer>localStorage 및 sessionStorage 설명하십시오.rel="noopener" 속성은 어디에 그리고 왜 사용됩니까?em 과 rem Unit의 차이점은 무엇입니까?col-{n} / 12 비율을 차지하는 3 열 레이아웃을 만듭니다.@media 속성을 지정할 수 있습니까?상태 부족 구성 요소는 동작이 상태에 의존하지 않는 구성 요소입니다. 무국적 구성 요소는 기능적 또는 클래스 구성 요소 일 수 있습니다. 무국적 기능 구성 요소는 동일한 소품이 주어진 동일한 출력을 생성하도록 보장하고 테스트하기가 더 쉽습니다. 수명주기 후크를 사용할 필요가 없을 때 무국적 기능 구성 요소를 선호해야합니다.
this 키워드를 완전히 피합니다.
⬆ 위로 돌아갑니다
== 및 === 의 차이점은 무엇입니까? Triple Equals ( === ) 엄격한 평등을 점검합니다. 즉, 유형과 값이 모두 동일해야합니다. 반면에 Double Equals ( == )는 먼저 유형 강요를 수행하여 두 피연산자가 모두 같은 유형이고 엄격한 비교를 적용합니다.
== 직관적이지 않은 결과를 얻을 수 있기 때문입니다.
⬆ 위로 돌아갑니다
요소는 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++ 와 Prefix ++i 증가 연산자의 차이점은 무엇입니까?둘 다 변수 값을 1로 증가시킵니다. 차이는 그들이 평가하는 것입니다.
포스트 픽스 증분 연산자는 증가하기 전에 값으로 평가됩니다.
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, 함수, 세트 등)를 효과적으로 복제하기 위해 훨씬 더 복잡합니다.
다른 대안은 다음과 같습니다.
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 와 같은 함수는 메인 스레드를 차단하여 사용자가 닫을 때까지 사용자 입력이 등록되지 않도록합니다.
⬆ 위로 돌아갑니다
두 개의 다른 객체가 동일한 값의 동일한 속성을 가질 수 있지만 == 또는 === 사용하여 비교할 때 동일하게 간주되지 않습니다. 이는 값으로 비교되는 원시적 값과 달리 참조 (메모리의 위치)에 의해 비교되기 때문입니다.
두 객체가 구조가 동일인지 테스트하려면 도우미 기능이 필요합니다. 중첩 된 객체를 포함하여 동일한 값이 있는지 테스트하기 위해 각 객체의 자체 속성을 통해 반복합니다. 선택적으로, 객체의 프로토 타입은 또한 3 차 인수로 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는 공격자가 악의적 인 스크립트를 합법적 인 웹 사이트 또는 웹 응용 프로그램에 주입하는 클라이언트 측 코드 주입을 말합니다. 이는 응용 프로그램이 사용자 입력을 검증하지 않고 동적 HTML 컨텐츠를 자유롭게 주입 할 때 종종 달성됩니다.
예를 들어, 댓글 시스템이 사용자 입력을 유효성있게 유효하게하거나 탈출하지 않으면 위험에 처해 있습니다. 주석에 Escaped HTML이 포함 된 경우 주석은 다른 사용자가 자신의 지식에 대해 실행할 웹 사이트에 <script> 태그를 주입 할 수 있습니다.
innerHTML 대신 textContent 사용하면 HTML 파서를 통해 브라우저가 문자열을 실행하는 것을 방지하여 스크립트를 실행합니다.
⬆ 위로 돌아갑니다
크로스 오리핀 리소스 공유 또는 CORS는 추가 HTTP 헤더를 사용하여 웹 사이트 원점과 다른 원점에서 서버의 리소스에 액세스 할 수있는 브라우저 권한을 부여하는 메커니즘입니다.
크로스 오리핀 요청의 예는 http://mydomain.com 에서 http://yourdomain.com을 요청하는 http://yourdomain.com 에서 제공하는 웹 응용 프로그램입니다.
보안상의 이유로 브라우저는 JavaScript에서 시작한 크로스 오리핀 HTTP 요청을 제한합니다. XMLHttpRequest 및 fetch 동일한 오리핀 정책을 따르십시오. 즉, 해당 API를 사용하는 웹 응용 프로그램은 다른 원점의 응답에 올바른 CORS 헤더가 포함되지 않는 한 응용 프로그램에 액세스 한 동일한 원산지에서 HTTP 리소스 만 요청할 수 있습니다.
⬆ 위로 돌아갑니다
DOM (Document Object Model)은 HTML 및 XML 문서를 노드로 구성된 트리 구조로 취급하는 크로스 플랫폼 API입니다. 이러한 노드 (예 : 요소 및 텍스트 노드)는 프로그래밍 방식으로 조작 할 수있는 객체이며 이에 대한 가시적 변경 사항은 문서에 라이브로 반영됩니다. 브라우저 에서이 API는 DOM 노드를 조작하여 스타일, 내용, 문서의 배치 또는 이벤트 리스너를 통해 상호 작용할 수있는 JavaScript에서 사용할 수 있습니다.
<head> 에 defer 속성이있는 또는 DOMContentLoaded 이벤트 리스너 내부에 배치됩니다. 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 } 나머지 ... 와 함께 수집하여 임의의 인수를 수락하는 함수를 반환하십시오. 이 기능에서 fn Function.prototype.apply 으로 호출 한 결과를 반환하십시오.
const bind = ( fn , context ) => ( ... args ) => fn . apply ( context , args )
⬆ 위로 돌아갑니다
var , let , const 및 키워드 명세서의 차이점은 무엇입니까? 변수 할당 전에 키워드가 없으면 존재하지 않는 경우 글로벌 변수를 할당하거나 이미 선언 된 변수를 재 할당합니다. 비 스트릭 모드에서 변수가 아직 선언되지 않은 경우 변수를 글로벌 오브젝트 (브라우저의 window )의 속성으로 할당합니다. 엄격한 모드에서는 원치 않는 글로벌 변수가 생성되는 것을 방지하기 위해 오류가 발생합니다.
var ES2015까지 변수를 선언하는 기본 문자였습니다. 재 할 수있는 기능-스코핑 변수를 생성합니다. 그러나 블록 범위가 부족하여 변수가 블록 스코프 외부에 계속 존재하기 때문에 변수가 비동기 콜백을 포함하는 루프에서 변수가 재사용되는 경우 문제를 일으킬 수 있습니다.
아래에서 setTimeout 콜백이 실행될 때까지 루프가 이미 완료되었고 i 변수는 10 이므로 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 and const 에는 Temperal Dead Zone (TDZ)이라는 개념이 있습니다. 선언은 여전히 들어오고 있지만, 스코프에 들어가고 액세스 할 수없는 곳으로 선언되는 사이에는 기간이 있습니다.var 사용과 VAR을 해결할 수 let 방법과 var 유지하는 솔루션에 대한 일반적인 문제를 보여줍니다.var 피하고 나중에 재 할당 let 않는 한 모든 변수에 대한 기본 선언문으로서 const 선호해야합니다. let 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 에서 문서를 반응합니다
⬆ 위로 돌아갑니다
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
⬆ 위로 돌아갑니다
빈 길이 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 무엇을 평가합니까? JavaScript는 IEEE 754 표준을 수학에 사용하고 64 비트 부동물 숫자를 사용하기 때문에 false 로 평가됩니다. 이로 인해 소수점 계산을 수행 할 때는 정밀 오류가 발생합니다.
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" selector와 일치하는 요소가 없거나 포함되지 않은 경우 함수는 호출되지 않습니다. 첫 번째 피연산자가 거짓이되어 두 번째 피연산자가 평가되지 않기 때문입니다.
⬆ 위로 돌아갑니다
때때로. 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() 에 인수로 전달된다는 것을 의미합니다. 그러나 변수 선언으로 값이 들어오지 않으므로 출력은 2 아닌 undefined 되지 않습니다.
strict 모드에 대한 언급
⬆ 위로 돌아갑니다
호이 스팅은 컴파일 단계에서 가변 및 함수 선언이 메모리에 넣는 JavaScript 메커니즘입니다. 이는 기능과 변수가 어디에서 선언 되더라도 범위가 글로벌인지 로컬인지 여부에 관계없이 범위의 상단으로 이동 함을 의미합니다.
그러나 값은 선언과 함께 들어오지 않습니다.
다음 스 니펫 :
console . log ( hoist )
var hoist = "value"다음과 같습니다.
var hoist
console . log ( hoist )
hoist = "value" Therefore logging hoist outputs undefined to the console, not "value" .
Hoisting also allows you to invoke a function declaration before it appears to be declared in a program.
myFunction ( ) // No error; logs "hello"
function myFunction ( ) {
console . log ( "hello" )
}But be wary of function expressions that are assigned to a variable:
myFunction ( ) // Error: `myFunction` is not a function
var myFunction = function ( ) {
console . log ( "hello" )
}
⬆ Back to top
In HTML, the attribute name is in all lowercase and is given a string invoking a function defined somewhere:
< 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." )
}
⬆ Back to top
This technique is very common in JavaScript libraries. It creates a closure around the entire contents of the file which creates a private namespace and thereby helps avoid potential name clashes between different JavaScript modules and libraries. The function is immediately invoked so that the namespace (library name) is assigned the return value of the function.
const myLibrary = ( function ( ) {
var privateVariable = 2
return {
publicMethod : ( ) => privateVariable
}
} ) ( )
privateVariable // ReferenceError
myLibrary . publicMethod ( ) // 2
⬆ Back to top
function greet ( ) {
return
{
message : "hello"
}
} Because of JavaScript's automatic semicolon insertion (ASI), the compiler places a semicolon after return keyword and therefore it returns undefined without an error being thrown.
⬆ Back to top
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 >
)
}
⬆ Back to top
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.
⬆ Back to top
Lexical scoping refers to when the location of a function's definition determines which variables you have access to. On the other hand, dynamic scoping uses the location of the function's invocation to determine which variables are available.
⬆ Back to top
# except for the last four (4) characters. mask ( "123456789" ) // "#####6789"There are many ways to solve this problem, this is just one one of them.
Using String.prototype.slice() we can grab the last 4 characters of the string by passing -4 as an argument. Then, using String.prototype.padStart() , we can pad the string to the original length with the repeated mask character.
const mask = ( str , maskChar = "#" ) =>
str . slice ( - 4 ) . padStart ( str . length , maskChar )
⬆ Back to top
const a = [ 1 , 2 , 3 ]
const b = [ 1 , 2 , 3 ]
const c = "1,2,3"
console . log ( a == c )
console . log ( a == b ) The first console.log outputs true because JavaScript's compiler performs type conversion and therefore it compares to strings by their value. On the other hand, the second console.log outputs false because Arrays are Objects and Objects are compared by reference.
⬆ Back to top
In the classical inheritance paradigm, object instances inherit their properties and functions from a class, which acts as a blueprint for the object. Object instances are typically created using a constructor and the new keyword.
In the prototypal inheritance paradigm, object instances inherit directly from other objects and are typically created using factory functions or Object.create() .
⬆ Back to top
MIME is an acronym for Multi-purpose Internet Mail Extensions . It is used as a standard way of classifying file types over the Internet.
MIME type actually has two parts: a type and a subtype that are separated by a slash (/). For example, the MIME type for Microsoft Word files is application/msword (ie, type is application and the subtype is msword).
⬆ Back to top
The Promise object represents the eventual completion (or failure) of an asynchronous operation, and its resulting value. An example can be the following snippet, which after 100ms prints out the result string to the standard output. Also, note the catch, which can be used for error handling. Promise s are chainable.
new Promise ( ( resolve , reject ) => {
setTimeout ( ( ) => {
resolve ( "result" )
} , 100 )
} )
. then ( console . log )
. catch ( console . error ) Promise s!
⬆ Back to top
The latest ECMAScript standard defines seven data types, six of them being primitive: Boolean , Null , Undefined , Number , String , Symbol and one non-primitive data type: Object .
Symbol data typeArray , Date and function are all of type object
⬆ Back to top
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 )
} )Advantages include:
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.
*/
⬆ Back to top
Callbacks are functions passed as an argument to another function to be executed once an event has occurred or a certain task is complete, often used in asynchronous code. Callback functions are invoked later by a piece of code but can be declared on initialization without being invoked.
As an example, event listeners are asynchronous callbacks that are only executed when a specific event occurs.
function onClick ( ) {
console . log ( "The user clicked on the page." )
}
document . addEventListener ( "click" , onClick ) However, callbacks can also be synchronous. The following map function takes a callback function that is invoked synchronously for each iteration of the loop (array element).
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]
⬆ Back to top
null and undefined ? In JavaScript, two values discretely represent nothing - undefined and null . The concrete difference between them is that null is explicit, while undefined is implicit. When a property does not exist or a variable has not been given a value, the value is undefined . null is set as the value to explicitly indicate “no value”. In essence, undefined is used when the nothing is not known, and null is used when the nothing is known.
typeof undefined evaluates to "undefined" .typeof null evaluates "object" . However, it is still a primitive value and this is considered an implementation bug in JavaScript.undefined == null evaluates to true .
⬆ Back to top
Often used to store one occurrence of data.
const person = {
name : "John" ,
age : 50 ,
birthday ( ) {
this . age ++
}
}
person . birthday ( ) // person.age === 51 Often used when you need to create multiple instances of an object, each with their own data that other instances of the class cannot affect. The new operator must be used before invoking the constructor or the global object will be mutated.
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 Creates a new object similar to a constructor, but can store private data using a closure. There is also no need to use new before invoking the function or the this keyword. Factory functions usually discard the idea of prototypes and keep all properties and methods as own properties of the object.
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()Sets the prototype of the newly created object.
const personProto = {
birthday ( ) {
this . age ++
}
}
const person = Object . create ( personProto )
person . age = 50
person . birthday ( ) // person.age === 51 A second argument can also be supplied to Object.create() which acts as a descriptor for the new properties to be defined.
Object . create ( personProto , {
age : {
value : 50 ,
writable : true ,
enumerable : true
}
} )
⬆ Back to top
Parameters are the variable names of the function definition, while arguments are the values given to a function when it is invoked.
function myFunction ( parameter1 , parameter2 ) {
console . log ( arguments [ 0 ] ) // "argument1"
}
myFunction ( "argument1" , "argument2" ) arguments is an array-like object containing information about the arguments supplied to an invoked function.myFunction.length describes the arity of a function (how many parameters it has, regardless of how many arguments it is supplied).
⬆ Back to top
JavaScript always passes by value. However, with objects, the value is a reference to the object.
⬆ Back to top
You can use an arrow function to wrap around an event handler and pass arguments, which is equivalent to calling bind :
< button onClick = { ( ) => this . handleClick ( id ) } />
< button onClick = { this . handleClick . bind ( this , id ) } / >
⬆ Back to top
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 />
</ >
) ;
}
⬆ Back to top
pipe that performs left-to-right function composition by returning a function that accepts one argument. 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))) Gather all supplied arguments using the rest operator ... and return a unary function that uses Array.prototype.reduce() to run the value through the series of functions before returning the final value.
const pipe = ( ... fns ) => x => fns . reduce ( ( v , fn ) => fn ( v ) , x )
⬆ Back to top
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.
⬆ Back to top
NaN (Not-a-Number) is the only value not equal to itself when comparing with any of the comparison operators. NaN is often the result of meaningless math computations, so two NaN values make no sense to be considered equal.
isNaN() and Number.isNaN()const isNaN = x => x !== xNaN
⬆ Back to top
The two terms can be contrasted as:
In JavaScript, objects are mutable while primitive values are immutable. This means operations performed on objects can change the original reference in some way, while operations performed on a primitive value cannot change the original value.
All String.prototype methods do not have an effect on the original string and return a new string. On the other hand, while some methods of Array.prototype do not mutate the original array reference and produce a fresh array, some cause mutations.
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
⬆ Back to top
Big O notation is used in Computer Science to describe the time complexity of an algorithm. The best algorithms will execute the fastest and have the simplest complexity.
Algorithms don't always perform the same and may vary based on the data they are supplied. While in some cases they will execute quickly, in other cases they will execute slowly, even with the same number of elements to deal with.
In these examples, the base time is 1 element = 1ms .
arr [ arr . length - 1 ]1msConstant time complexity. No matter how many elements the array has, it will theoretically take (excluding real-world variation) the same amount of time to execute.
arr . filter ( fn )1000msLinear time complexity. The execution time will increase linearly with the number of elements the array has. If the array has 1000 elements and the function takes 1ms to execute, 7000 elements will take 7ms to execute. This is because the function must iterate through all elements of the array before returning a result.
arr . some ( fn )1ms <= x <= 1000msThe execution time varies depending on the data supplied to the function, it may return very early or very late. The best case here is O(1) and the worst case is O(N).
arr . sort ( fn )10000ms Browsers usually implement the quicksort algorithm for the sort() method and the average time complexity of quicksort is O(NlgN). This is very efficient for large collections.
for ( let i = 0 ; i < arr . length ; i ++ ) {
for ( let j = 0 ; j < arr . length ; j ++ ) {
// ...
}
}1000000msThe execution time rises quadratically with the number of elements. Usually the result of nesting loops.
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 (practically) msThe execution time rises extremely fast with even just 1 addition to the array.
⬆ Back to top
A pure function is a function that satisfies these two conditions:
Pure functions can mutate local data within the function as long as it satisfies the two conditions above.
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 ).
⬆ Back to top
Recursion is the repeated application of a process. In JavaScript, recursion involves functions that call themselves repeatedly until they reach a base condition. The base condition breaks out of the recursion loop because otherwise the function would call itself indefinitely. Recursion is very useful when working with data structures that contain nesting where the number of levels deep is unknown.
For example, you may have a thread of comments returned from a database that exist in a flat array but need to be nested for display in the UI. Each comment is either a top-level comment (no parent) or is a reply to a parent comment. Comments can be a reply of a reply of a reply... we have no knowledge beforehand the number of levels deep a comment may be. This is where recursion can help.
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: [] }
]
*/ In the above example, the base condition is met if filter() returns an empty array. The chained map() won't invoke the callback function which contains the recursive call, thereby breaking the loop.
⬆ Back to top
Memoization is the process of caching the output of function calls so that subsequent calls are faster. Calling the function again with the same input will return the cached output without needing to do the calculation again.
A basic implementation in JavaScript looks like this:
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
}
}
⬆ Back to top
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.
⬆ Back to top
These two types of programming can roughly be summarized as:
A common example of declarative programming is CSS. The developer specifies CSS properties that describe what something should look like rather than how to achieve it. The "how" is abstracted away by the browser.
On the other hand, imperative programming involves the steps required to achieve something. In JavaScript, the differences can be contrasted like so:
const numbers = [ 1 , 2 , 3 , 4 , 5 ]
const numbersDoubled = [ ]
for ( let i = 0 ; i < numbers . length ; i ++ ) {
numbersDoubled [ i ] = numbers [ i ] * 2
}We manually loop over the numbers of the array and assign the new index as the number doubled.
const numbers = [ 1 , 2 , 3 , 4 , 5 ]
const numbersDoubled = numbers . map ( n => n * 2 )We declare that the new array is mapped to a new one where each value is doubled.
⬆ Back to top
Functional programming is a paradigm in which programs are built in a declarative manner using pure functions that avoid shared state and mutable data. Functions that always return the same value for the same input and don't produce side effects are the pillar of functional programming. Many programmers consider this to be the best approach to software development as it reduces bugs and cognitive load.
.map , .reduce etc.)
⬆ Back to top
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.
⬆ Back to top
Event-driven programming is a paradigm that involves building applications that send and receive events. When the program emits events, the program responds by running any callback functions that are registered to that event and context, passing in associated data to the function. With this pattern, events can be emitted into the wild without throwing errors even if no functions are subscribed to it.
A common example of this is the pattern of elements listening to DOM events such as click and mouseenter , where a callback function is run when the event occurs.
document . addEventListener ( "click" , function ( event ) {
// This callback function is run when the user
// clicks on the document.
} )Without the context of the DOM, the pattern may look like this:
const hub = createEventHub ( )
hub . on ( "message" , function ( data ) {
console . log ( ` ${ data . username } said ${ data . text } ` )
} )
hub . emit ( "message" , {
username : "John" ,
text : "Hello?"
} ) With this implementation, on is the way to subscribe to an event, while emit is the way to publish the event.
⬆ Back to top
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 )
⬆ Back to top
Static methods belong to a class and don't act on instances, while instance methods belong to the class prototype which is inherited by all instances of the class and acts on them.
Array . isArray // static method of Array
Array . prototype . push // instance method of Array In this case, the Array.isArray method does not make sense as an instance method of arrays because we already know the value is an array when working with it.
Instance methods could technically work as static methods, but provide terser syntax:
const arr = [ 1 , 2 , 3 ]
arr . push ( 4 )
Array . push ( arr , 4 )
⬆ Back to top
A closure is a function defined inside another function and has access to its lexical scope even when it is executing outside its lexical scope. The closure has access to variables in three scopes:
In JavaScript, all functions are closures because they have access to the outer scope, but most functions don't utilise the usefulness of closures: the persistence of state. Closures are also sometimes called stateful functions because of this.
In addition, closures are the only way to store private data that can't be accessed from the outside in JavaScript. They are the key to the UMD (Universal Module Definition) pattern, which is frequently used in libraries that only expose a public API but keep the implementation details private, preventing name collisions with other libraries or the user's own code.
⬆ Back to top
this keyword and how does it work? The this keyword is an object that represents the context of an executing function. Regular functions can have their this value changed with the methods call() , apply() and bind() . Arrow functions implicitly bind this so that it refers to the context of its lexical environment, regardless of whether or not its context is set explicitly with call() .
Here are some common examples of how this works:
this refers to the object itself inside regular functions if the object precedes the invocation of the function.
Properties set as this do not refer to the object.
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 refers to the element listening to the event.
document . body . addEventListener ( "click" , function ( ) {
console . log ( this ) // document.body
} ) this refers to the newly created object.
class Example {
constructor ( ) {
console . log ( this ) // myExample
}
}
const myExample = new Example ( ) With call() and apply() , this refers to the object passed as the first argument.
var myFunction = function ( ) {
return this
}
myFunction . call ( { customThis : true } ) // { customThis: true } this Because this can change depending on the scope, it can have unexpected values when using regular functions.
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 is the global object ( window in browsers), while in strict mode global this is undefined .Function.prototype.call and Function.prototype.apply set the this context of an executing function as the first argument, with call accepting a variadic number of arguments thereafter, and apply accepting an array as the second argument which are fed to the function in a variadic manner.Function.prototype.bind returns a new function that enforces the this context as the first argument which cannot be changed by other functions.this context to be changed based on how it is called, you must use the function keyword. Use arrow functions when you want this to be the surrounding (lexical) context. this on MDN
⬆ Back to top
children prop? 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 >
)
}
⬆ Back to top
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() .
⬆ Back to top
The main purpose is to avoid manipulating the DOM directly and keep the state of an application in sync with the UI easily. Additionally, they provide the ability to create components that can be reused when they have similar functionality with minor differences, avoiding duplication which would require multiple changes whenever the structure of a component which is reused in multiple places needs to be updated.
When working with DOM manipulation libraries like jQuery, the data of an application is generally kept in the DOM itself, often as class names or data attributes. Manipulating the DOM to update the UI involves many extra steps and can introduce subtle bugs over time. Keeping the state separate and letting a framework handle the UI updates when the state changes reduces cognitive load. Saying you want the UI to look a certain way when the state is a certain value is the declarative way of creating an application, instead of the imperative way of manually updating the UI to reflect the new state.
⬆ Back to top
'use strict' do and what are some of the key benefits to using it? Including 'use strict' at the beginning of your JavaScript source file enables strict mode, which enforces more strict parsing and error handling of JavaScript code. It is considered a good practice and offers a lot of benefits, such as:
eval() and arguments .this coercion, throwing an error when this references a value of null or undefined .delete .
⬆ Back to top
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:
⬆ Back to top
The virtual DOM (VDOM) is a representation of the real DOM in the form of plain JavaScript objects. These objects have properties to describe the real DOM nodes they represent: the node name, its attributes, and child nodes.
< div class =" counter " >
< h1 > 0 </ h1 >
< button > - </ button >
< button > + </ button >
</ div >The above markup's virtual DOM representation might look like this:
{
nodeName : "div" ,
attributes : { class : "counter" } ,
children : [
{
nodeName : "h1" ,
attributes : { } ,
children : [ 0 ]
} ,
{
nodeName : "button" ,
attributes : { } ,
children : [ "-" ]
} ,
{
nodeName : "button" ,
attributes : { } ,
children : [ "+" ]
}
]
}The library/framework uses the virtual DOM as a means to improve performance. When the state of an application changes, the real DOM needs to be updated to reflect it. However, changing real DOM nodes is costly compared to recalculating the virtual DOM. The previous virtual DOM can be compared to the new virtual DOM very quickly in comparison.
Once the changes between the old VDOM and new VDOM have been calculated by the diffing engine of the framework, the real DOM can be patched efficiently in the least time possible to match the new state of the application.
⬆ Back to top
this context in React component classes? 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.
⬆ Back to top
A stateless component is a component whose behavior does not depend on its state. Stateless components can be either functional or class components. Stateless functional components are easier to maintain and test since they are guaranteed to produce the same output given the same props. Stateless functional components should be preferred when lifecycle hooks don't need to be used.
this keyword altogether.
⬆ Back to top
A stateful component is a component whose behavior depends on its state. This means that two separate instances of the component if given the same props will not necessarily render the same output, unlike pure function components.
// 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() .
⬆ Back to top
Comments must be wrapped inside curly braces {} and use the /* */ syntax.
const tree = (
< div >
{ /* Comment */ }
< p > Text </ p >
</ div >
)
⬆ Back to top
An element is a plain JavaScript object that represents a DOM node or component. Elements are pure and never mutated, and are cheap to create.
A component is a function or class. Components can have state and take props as input and return an element tree as output (although they can represent generic containers or wrappers and don't necessarily have to emit DOM). Components can initiate side effects in lifecycle methods (eg AJAX requests, DOM mutations, interfacing with 3rd party libraries) and may be expensive to create.
const Component = ( ) => "Hello"
const componentElement = < Component />
const domNodeElement = < div />
⬆ Back to top
When several components need to share the same data, then it is recommended to lift the shared state up to their closest common ancestor. For example, if two child components share the same data, it is recommended to move the shared state to parent instead of maintaining the local state in both child components.
⬆ Back to top
className instead of class like in HTML? React's philosophy in the beginning was to align with the browser DOM API rather than HTML, since that more closely represents how elements are created. Setting a class on an element meant using the className API:
const element = document . createElement ( "div" )
element . className = "hello"Additionally, before ES5, reserved words could not be used in objects:
const element = {
attributes : {
class : "hello"
}
}In IE8, this will throw an error.
In modern environments, destructuring will throw an error if trying to assign to a variable:
const { class } = this . props // Error
const { className } = this . props // All good
const { class : className } = this . props // All good, but cumbersome! However, class can be used as a prop without problems, as seen in other libraries like Preact. React currently allows you to use class , but will throw a warning and convert it to className under the hood. There is currently an open thread (as of January 2019) discussing changing className to class to reduce confusion.
⬆ Back to top
You can use an arrow function to wrap around an event handler and pass arguments, which is equivalent to calling bind :
< button onClick = { ( ) => this . handleClick ( id ) } />
< button onClick = { this . handleClick . bind ( this , id ) } / >
⬆ Back to top
setState ? The callback function is invoked when setState has finished and the component gets rendered. Since setState is asynchronous, the callback function is used for any post action.
setState ( { name : "sudheer" } , ( ) => {
console . log ( "The name has updated and component re-rendered" )
} ) setState finishes and is used for any post action.setState
⬆ Back to top
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.
⬆ Back to top
In HTML, the attribute name is in all lowercase and is given a string invoking a function defined somewhere:
< 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." )
}
⬆ Back to top
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 >
)
}
⬆ Back to top
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.
⬆ Back to top
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.
⬆ Back to top
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() .
⬆ Back to top
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 />
</ >
) ;
}
⬆ Back to top
this context in React component classes? 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.
⬆ Back to top
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
}
}
⬆ Back to top
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 )
⬆ Back to top
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.
⬆ Back to top
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 )
⬆ Back to top
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.
⬆ Back to top
children prop? 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 >
)
}
⬆ Back to top
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.
⬆ Back to top
alt attribute on images? 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.
⬆ Back to top
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.
⬆ Back to top
<header> elements? What about <footer> elements? Yes to both. 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.
⬆ Back to top
<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>
⬆ Back to top
rel="noopener" attribute used? 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.
⬆ Back to top
defer and async attributes on a <script> tag?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.
⬆ Back to top
In HTML, the attribute name is in all lowercase and is given a string invoking a function defined somewhere:
< 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." )
}
⬆ Back to top
Some of the key differences are:
<DOCTYPE>checked="checked" instead of checked )
⬆ Back to top
The DOM (Document Object Model) is a cross-platform API that treats HTML and XML documents as a tree structure consisting of nodes. These nodes (such as elements and text nodes) are objects that can be programmatically manipulated and any visible changes made to them are reflected live in the document. In a browser, this API is available to JavaScript where DOM nodes can be manipulated to change their styles, contents, placement in the document, or interacted with through event listeners.
<head> with a defer attribute, or inside a DOMContentLoaded event listener. Scripts that manipulate DOM nodes should be run after the DOM has been constructed to avoid errors.document.getElementById() and document.querySelector() are common functions for selecting DOM nodes.innerHTML property to a new value runs the string through the HTML parser, offering an easy way to append dynamic HTML content to a node.
⬆ Back to top
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)
⬆ Back to top
localStorage and 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.
⬆ Back to top
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 {
}
⬆ Back to top
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.
⬆ Back to top
col-{n} / 12 ratio of the container. < 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 ;
}
⬆ Back to top
@media properties?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
⬆ Back to top
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 .
⬆ Back to top
em and rem units? 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
⬆ Back to top
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.
⬆ Back to top
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;
}
⬆ Back to top
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.
⬆ Back to top
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.
⬆ Back to top
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.
⬆ Back to top
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
⬆ Back to top
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.
⬆ Back to top
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 >
⬆ Back to top
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 )
} )Advantages include:
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.
*/
⬆ Back to top
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
⬆ Back to top
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:
⬆ Back to top
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.
⬆ Back to top
XSS refers to client-side code injection where the attacker injects malicious scripts into a legitimate website or web application. This is often achieved when the application does not validate user input and freely injects dynamic HTML content.
For example, a comment system will be at risk if it does not validate or escape user input. If the comment contains unescaped HTML, the comment can inject a <script> tag into the website that other users will execute against their knowledge.
textContent instead of innerHTML prevents the browser from running the string through the HTML parser which would execute scripts in it.
⬆ Back to top
MIT. Copyright (c) Stefan Feješ.