소개
저는 Mastering Modern JavaScript라는 새로운 책을 작업 중이며 마침내 발표되었습니다.
오늘날 끊임없이 변화하는 세상에서 코드 품질을 개선하는 데 매우 유용한 새로운 콘텐츠와 업데이트가 자바 스크립트에 많이 제공됩니다.
고액의 일자리를 얻거나 최신 동향을 파악하고 코드 품질을 개선하거나 현재 작업을 유지하기 위해서는 이러한 사항을 아는 것이 정말 중요합니다.
인터넷에는 이러한 사항을 설명하는 많은 자습서 / 기사가 있습니다. 하지만 필요한 정보와 소화하기 쉬운 정보를 찾는 것은 매우 어렵습니다.
그래서 그 주제를 수정할 무언가를 끊임없이 검색하는 대신에 필요한 모든 정보를 한 번에 찾을 수 있는 책을 만들기로 결정했습니다.
따라서 이 책은 ES6 이상에 추가 된 모든 최신 JavaScript 기능과 함께 가장 자주 사용되는 Array 메서드 및 자주 묻는 코딩 질문과 솔루션 및 설명을 다룹니다.
최신 JavaScript 기술을 마스터하는 데 필요한 유일한 가이드입니다.
이 책은 이해하고 이해하기 쉬운 총 144 페이지의 전문 콘텐츠를 포함하고 있습니다.
Mastering Modern JavaScript 책에는 다음이 포함됩니다.
목차
이 웹 사이트에서 이 책에 대한 모든 것을 탐색 할 수 있습니다.
이 책에서 다루는 몇 가지 사항을 살펴 보겠습니다.
Let과 const
ES6가 나오기 전에 JavaScript는 var 키워드를 사용했기 때문에 JavaScript에는 함수와 전역 범위 만 있었습니다. 블록 수준 범위가 없었습니다.
let 및 const JavaScript가 추가되면서 블록 범위 지정이 추가되었습니다.
let 사용 :
let 키워드를 사용하여 변수를 선언 할 때 나중에 해당 변수에 새 값을 할당 할 수 있지만 동일한 이름으로 다시 선언 할 수는 없습니다.
// ES5 Code
var value = 10;
console.log(value); // 10
var value = "hello";
console.log(value); // hello
var value = 30;
console.log(value); // 30
위에서 볼 수 있듯이 var 키워드를 여러 번 사용하여 변수 값을 다시 선언했습니다.
ES6 이전에는 의미 있는 용도가 없는 이전에 이미 선언 된 변수를 다시 선언 할 수 있었으며 대신 혼란을 야기했습니다.
이미 다른 곳에 동일한 이름으로 선언 된 변수가 있고 해당 변수가 이미 있다는 사실을 모르고 다시 선언하는 경우 변수 값을 재정 의하여 문제를 디버깅 하기 어려울 수 있습니다.
따라서 let 키워드를 사용할 때 같은 이름의 변수를 다시 선언하려고 하면 오류가 발생합니다. 이는 좋은 일입니다.
// ES6 Code
let value = 10;
console.log(value); // 10
let value = "hello"; // Uncaught SyntaxError: Identifier 'value' has already been declared
그러나 다음 코드는 유효합니다.
// ES6 Code
let value = 10;
console.log(value); // 10
value = "hello";
console.log(value); // hello
값 변수에 새 값을 다시 할당하지만 값을 다시 선언하지 않기 때문에 위 코드에서 오류가 발생하지 않습니다.
이제 아래 코드를 살펴보십시오.
// ES5 Code
var isValid = true;
if(isValid) {
var number = 10;
console.log('inside:', number); // inside: 10
}
console.log('outside:', number); // outside: 10
var 키워드로 변수를 선언 할 때 위 코드에서 볼 수 있듯이 if 블록 외부에서도 사용할 수 있습니다.
// ES6 Code
let isValid = true;
if(isValid) {
let number = 10;
console.log('inside:', number); // inside: 10
}
console.log('outside:', number); // Uncaught ReferenceError: number is not defined
위의 코드에서 볼 수 있듯이 let 키워드를 사용하여 선언 된 number 변수는 if 블록 내부에서만 액세스 할 수 있고 블록 외부에서는 사용할 수 없으므로 if 블록 외부에서 액세스하려고 하면 참조 오류가 발생합니다.
그러나 if 블록 외부에 숫자 변수가 있으면 아래와 같이 작동합니다.
// ES6 Code
let isValid = true;
let number = 20;
if(isValid) {
let number = 10;
console.log('inside:', number); // inside: 10
}
console.log('outside:', number); // outside: 20
여기에는 별도의 범위에 두 개의 숫자 변수가 있습니다. 따라서 if 블록 외부에서 숫자 값은 20이 됩니다.
아래 코드를 살펴보십시오.
// ES5 Code
for(var i = 0; i < 10; i++){
console.log(i);
}
console.log('outside:', i); // 10
var 키워드를 사용할 때 for 루프 외부에서도 사용할 수 있었습니다.
// ES6 Code
for(let i = 0; i < 10; i++){
console.log(i);
}
console.log('outside:', i); // Uncaught ReferenceError: i is not defined
그러나 let 키워드를 사용하면 루프 외부에서 사용할 수 없습니다.
따라서 위 코드 샘플에서 볼 수 있듯이 let 키워드를 사용하면 해당 블록 내부에서만 변수를 사용할 수 있으며 블록 외부에서는 액세스 할 수 없습니다.
다음과 같이 중괄호 쌍으로 블록을 만들 수도 있습니다.
let i = 10;
{
let i = 20;
console.log('inside:', i); // inside: 20
i = 30;
console.log('i again:', i); // i again: 30
}
console.log('outside:', i); // outside: 10
기억 하시나요? 같은 블록에서 let 기반 변수를 다시 선언 할 수는 없지만 다른 블록에서는 다시 선언 할 수 있다고 말씀 드렸습니다. 위의 코드에서 볼 수 있듯이 i를 다시 선언하고 블록 내부에 새 값 20을 할당하고 선언하면 해당 변수 값은 해당 블록에서만 사용할 수 있습니다.
해당 변수를 인쇄 할 때 블록 외부에서 이전에 할당 된 값인 30 대신 10을 얻었습니다. 블록 외부에는 내부 i 변수가 존재하지 않기 때문입니다.
외부에서 선언 한 변수가 없으면 아래 코드에서 볼 수 있는 오류가 발생합니다.
{
let i = 20;
console.log('inside:', i); // inside: 20
i = 30;
console.log('i again:', i); // i again: 30
}
console.log('outside:', i); // Uncaught ReferenceError: i is not defined
const 사용 :
const 키워드는 블록 범위 지정 기능의 let 키워드와 정확히 동일하게 작동합니다. 그래서 그들이 어떻게 다른지 살펴 보겠습니다.
변수를 const로 선언하면 값이 변하지 않는 상수 변수로 간주됩니다.
let 의 경우 다음과 같이 나중에 해당 변수에 새 값을 할당 할 수 있습니다.
let number = 10;
number = 20;
console.log(number); // 20
하지만 const의 경우에는 그렇게 할 수 없습니다.
const number = 10;
number = 20; // Uncaught TypeError: Assignment to constant variable.
심지어 const 변수를 다시 선언 할 수도 없습니다.
const number = 20;
console.log(number); // 20
const number = 10; // Uncaught SyntaxError: Identifier 'number' has already been declared
이제 아래 코드를 살펴보십시오.
const arr = [1, 2, 3, 4];
arr.push(5);
console.log(arr); // [1, 2, 3, 4, 5]
const 변수는 값이 변하지 않는 상수라고 말했지만 위에서 상수 배열을 변경했습니다. 그래서 반대 아닌가?
아니요. 배열은 JavaScript의 기본 유형이 아닌 참조 유형입니다.
따라서 실제로 arr에 저장되는 것은 실제 배열이 아니라 실제 배열이 저장된 메모리 위치의 참조 (주소)뿐입니다.
그래서 arr.push (5); 우리는 실제로 arr이 가리키는 참조를 변경하지 않지만 해당 참조에 저장된 값을 변경합니다.
객체의 경우도 마찬가지입니다.
const obj = {
name: 'David',
age: 30
};
obj.age = 40;
console.log(obj); // { name: 'David', age: 40 }
여기에서도 obj가 가리키는 위치의 참조를 변경하지 않고 해당 참조에 저장된 값을 변경합니다.
따라서 위 코드는 작동하지만 아래 코드는 작동하지 않습니다.
const obj = { name: 'David', age: 30 };
const obj1 = { name: 'Mike', age: 40 };
obj = obj1; // Uncaught TypeError: Assignment to constant variable.
const 변수가 가리키는 참조를 변경하려고 했기 때문에 위 코드는 작동하지 않습니다.
따라서 const를 사용할 때 기억해야 할 요점은 const를 사용하여 변수를 상수로 선언 할 때 다시 정의 할 수 없고 해당 변수를 다시 할당 할 수 없지만 변수가 다음과 같은 경우 해당 위치에 저장된 값을 변경할 수 있다는 것입니다. 참조 유형.
따라서 아래 코드는 새 값을 다시 할당하기 때문에 유효하지 않습니다.
const arr = [1, 2, 3, 4];
arr = [10, 20, 30]; // Uncaught TypeError: Assignment to constant variable.
그러나 앞에서 본 것처럼 배열 내부의 값을 변경할 수 있습니다. const 변수를 다시 정의하는 다음 코드도 유효하지 않습니다.
const name = "David";
const name = "Raj"; // Uncaught SyntaxError: Identifier 'name' has already been declared
결론
ES6 Import 및 Export 구문
ES6가 작동하기 전에는 다음과 같은 다른 자바 스크립트 파일을 가져 오기 위해 단일 HTML 파일에 여러 스크립트 태그가 있었습니다.
<script type="text/javascript" src="home.js"></script>
<script type="text/javascript" src="profile.js"></script>
<script type="text/javascript" src="user.js"></script>
따라서 다른 자바 스크립트 파일에 동일한 이름의 변수가 있는 경우 이름 충돌이 발생하고 예상하는 값이 실제 값이 아닙니다.
ES6는 모듈 개념으로 이 문제를 해결했습니다.
ES6에서 작성한 모든 자바 스크립트 파일은 모듈로 알려져 있으며 각 파일에서 선언 한 변수와 함수는 해당 파일에서 특별히 내보내고 다른 파일로 가져올 때까지 다른 파일에서 사용할 수 없습니다.
따라서 파일에 정의 된 함수와 변수는 각 파일에 대해 비공개이며 파일을 내보낼 때까지 파일 외부에서 액세스 할 수 없습니다.
내보내기에는 두 가지 유형이 있습니다.
Named Exports
단일 값을 명명 된 내보내기로 내보내려면 다음과 같이 내 보냅니다.
export const temp = "This is some dummy text";
내보낼 항목이 여러 개있는 경우 변수 선언 앞이 아닌 별도의 행에 내보내기 문을 작성하고 내보낼 항목을 중괄호로 지정할 수 있습니다.
const temp1 = "This is some dummy text1";
const temp2 = "This is some dummy text2";
export { temp1, temp2 };
내보내기 구문은 개체 리터럴 구문이 아닙니다. 따라서 ES6에서 무언가를 내보내기 위해 다음과 같은 키-값 쌍을 사용할 수 없습니다.
// This is invalid syntax of export in ES6
export { key1: value1, key2: value2 }
이름이 지정된 내보내기로 내 보낸 항목을 가져 오려면 다음 구문을 사용합니다.
import { temp1, temp2 } from './filename';
파일에서 항목을 가져 오는 동안 기본적으로 고려되는 파일 이름에 .js 확장자를 추가 할 필요가 없습니다.
// import from functions.js file from current directory
import { temp1, temp2 } from './functions';
// import from functions.js file from parent of current directory
import { temp1 } from '../functions';
Codesandbox 데모 : https://codesandbox.io/s/hardcore-pond-q4cjx
한 가지 유의해야 할 점은 내보낼 때 사용하는 이름이 가져 오는 동안 사용하는 이름과 일치해야 한다는 것입니다.
따라서 다음과 같이 내보내는 경우 :
// constants.js
export const PI = 3.14159;
가져 오는 동안에는 내보낼 때 사용한 것과 동일한 이름을 사용해야 합니다.
import { PI } from './constants';
다음과 같은 다른 이름은 사용할 수 없습니다.
import { PiValue } from './constants'; // This will throw an error
그러나 내 보낸 변수와 이름이 같은 변수가 이미 있는 경우 다음과 같이 가져 오는 동안 이름 바꾸기 구문을 사용할 수 있습니다.
import { PI as PIValue } from './constants';
여기서 PI의 이름을 PIValue로 변경 했으므로 이제 PI 변수 이름을 사용할 수 없습니다. PI의 내 보낸 값을 가져 오기 위해 PIValue 변수를 사용해야 합니다.
내보낼 때 이름 바꾸기 구문을 사용할 수도 있습니다.
// constants.js
const PI = 3.14159;
export { PI as PIValue };
가져 오는 동안 다음과 같이 PIValue를 사용해야 합니다.
import { PIValue } from './constants';
이름이 지정된 내보내기로 내보내려면 먼저 선언해야 합니다.
export 'hello'; // this will result in error
export const greeting = 'hello'; // this will work
export { name: 'David' }; // This will result in error
export const object = { name: 'David' }; // This will work
여러 개의 명명 된 내보내기를 가져 오는 순서는 중요하지 않습니다.
아래 validations.js 파일을 살펴보십시오.
// utils/validations.js
const isValidEmail = function(email) {
if (/^[^@ ]+@[^@ ]+\.[^@ \.]{2,}$/.test(email)) {
return "email is valid";
} else {
return "email is invalid";
}
};
const isValidPhone = function(phone) {
if (/^[\\(]\d{3}[\\)]\s\d{3}-\d{4}$/.test(phone)) {
return "phone number is valid";
} else {
return "phone number is invalid";
}
};
function isEmpty(value) { if (/^\s*$/.test(value)) {
return "string is empty or contains only spaces";
} else {
return "string is not empty and does not contain
spaces";
}
}
export { isValidEmail, isValidPhone, isEmpty };
index.js에서는 다음과 같은 함수를 사용합니다.
// index.js
import { isEmpty, isValidEmail } from "./utils/validations";
console.log("isEmpty:", isEmpty("abcd")); // isEmpty: string is not empty and does not contain spaces
console.log("isValidEmail:", isValidEmail("abc@11gmail.com")); // isValidEmail: email is valid
console.log("isValidEmail:", isValidEmail("ab@c@11gmail.com")); // isValidEmail: email is invalid
Codesandbox 데모 : https://codesandbox.io/s/youthful-flower-xesus
보시다시피 필수 내 보낸 항목 만 순서에 관계없이 가져올 수 있으므로 다른 파일에서 내 보낸 순서를 확인할 필요가 없습니다. 이것이 바로 명명 수출의 아름다움입니다.
Default Exports
앞서 말했듯이 단일 파일에 최대 하나의 기본 내보내기가 있을 수 있습니다.
그러나 여러 명명 된 내보내기와 하나의 기본 내보내기를 단일 파일에 결합 할 수 있습니다.
기본 내보내기를 선언하려면 다음과 같이 내보내기 키워드 앞에 기본 키워드를 추가합니다.
//constants.js
const name = 'David';
export default name;
기본 내보내기를 가져 오기 위해 다음과 같이 명명 된 내보내기에서 했던 것처럼 중괄호를 추가하지 않습니다.
import name from './constants';
다음과 같이 여러 개의 명명 된 내보내기와 하나의 기본 내보내기가 있는 경우 :
// constants.js
export const PI = 3.14159;
export const AGE = 30;
const NAME = "David";
export default NAME;
그런 다음 한 줄로 모두 가져 오려면 중괄호 앞에 기본 내 보낸 변수를 사용해야 합니다.
// NAME is default export and PI and AGE are named exports here
import NAME, { PI, AGE } from './constants';
기본 내보내기의 한 가지 전문은 가져 오는 동안 내 보낸 변수의 이름을 변경할 수 있다는 것입니다.
// constants.js
const AGE = 30;
export default AGE;
그리고 다른 파일에서 가져 오는 동안 다른 이름을 사용할 수 있습니다.
import myAge from ‘./constants’;
console.log(myAge); // 30
여기서는 기본 내보내기 변수의 이름을 AGE에서 myAge로 변경했습니다.
이는 기본 내보내기가 하나만 있을 수 있으므로 원하는 이름을 지정할 수 있기 때문에 작동합니다.
기본 내보내기에 대해 주의해야 할 또 다른 사항은 내보내기 기본 키워드가 다음과 같이 변수 선언 앞에 올 수 없다는 것입니다.
// constants.js
export default const AGE = 30; // This is an error and will not work
따라서 다음과 같이 별도의 줄에 export default 키워드를 사용해야 합니다.
// constants.js
const AGE = 30;
export default AGE;
그러나 다음과 같이 변수를 선언하지 않고도 기본 값을 내보낼 수 있습니다.
//constants.js
export default {
name: "Billy",
age: 40
};
다른 파일에서 다음과 같이 사용하십시오.
import user from './constants';
console.log(user.name); // Billy
console.log(user.age); // 40
다음 구문을 사용하여 파일로 내 보낸 모든 변수를 가져 오는 또 다른 방법이 있습니다.
import * as constants from './constants';
여기서 우리는 constants.js에 있고 상수 변수에 저장된 모든 명명 된 내보내기와 기본 내보내기를 가져옵니다. 따라서 상수는 이제 객체가 될 것입니다.
// constants.js
export const USERNAME = "David";
export default {
name: "Billy",
age: 40
};
다른 파일에서는 아래와 같이 사용합니다.
// test.js
import * as constants from './constants';
console.log(constants.USERNAME); // David
console.log(constants.default); // { name: "Billy", age: 40 }
console.log(constants.default.age); // 40
Codesandbox 데모 : https://codesandbox.io/s/green-hill-dj43b
default 및 named에 대해 별도의 줄로 내 보내지 않으려는 경우 다음과 같이 결합 할 수 있습니다.
// constants.js
const PI = 3.14159; const AGE = 30;
const USERNAME = "David";
const USER = {
name: "Billy",
age: 40
};
export { PI, AGE, USERNAME, USER as default };
여기서는 USER를 기본 내보내기로 내보내고 나머지는 명명 된 내보내기로 내보내고 있습니다.
다른 파일에서 다음과 같이 사용할 수 있습니다.
import USER, { PI, AGE, USERNAME } from "./constants";
Codesandbox 데모 : https://codesandbox.io/s/eloquent-northcutt-7btp1
결론
Default Parameters
ES6는 함수를 정의하는 동안 기본 매개 변수를 제공하는 매우 유용한 기능을 추가했습니다.
사용자가 시스템에 로그인하면 다음과 같은 환영 메시지를 표시하는 애플리케이션이 있다고 가정합니다.
function showMessage(firstName) {
return "Welcome back, " + firstName;
}
console.log(showMessage('John')); // Welcome back, John
그러나 등록하는 동안 선택 필드 였으므로 데이터베이스에 사용자 이름이 없으면 어떻게 될까요? 그런 다음 로그인 후 사용자에게 Welcome Guest 메시지를 표시 할 수 있습니다.
따라서 firstName이 제공되었는지 먼저 확인한 다음 해당 메시지를 표시해야 합니다. ES6 이전에는 다음과 같은 코드를 작성해야 합니다.
function showMessage(firstName) {
if(firstName) {
return "Welcome back, " + firstName;
} else {
return "Welcome back, Guest";
}
}
console.log(showMessage('John')); // Welcome back, John
console.log(showMessage()); // Welcome back, Guest
그러나 이제 기본 함수 매개 변수를 사용하는 ES6에서 아래와 같이 위의 코드를 작성할 수 있습니다.
function showMessage(firstName = 'Guest') {
return "Welcome back, " + firstName;
}
console.log(showMessage('John')); // Welcome back, John
console.log(showMessage()); // Welcome back, Guest
함수 매개 변수에 기본값으로 모든 값을 할당 할 수 있습니다.
function display(a = 10, b = 20, c = b) {
console.log(a, b, c);
}
display(); // 10 20 20
display(40); // 40 20 20
display(1, 70); // 1 70 70
display(1, 30, 70); // 1 30 70
보시다시피 a 및 b 함수 매개 변수에 고유 한 값을 할당했지만 c의 경우 b 값을 할당합니다. 따라서 함수를 호출하는 동안 c에 제공된 특정 값이 없는 경우 b에 대해 제공 한 값이 c에 할당됩니다.
위의 코드에서 함수에 대한 모든 인수를 제공하지 않았습니다. 따라서 위의 함수 호출은 아래와 같습니다.
display(); // is same as display(undefined, undefined, undefined)
display(40); // is same as display(40, undefined, undefined)
display(1, 70); // is same as display(1, 70, undefined)
따라서 전달 된 인수가 정의되지 않은 경우 해당 매개 변수에 기본값이 사용됩니다.
복잡하거나 계산 된 값을 기본값으로 할당 할 수도 있습니다.
const defaultUser = {
name: 'Jane',
location: 'NY',
job: 'Software Developer'
};
const display = (user = defaultUser, age = 60 / 2 ) => {
console.log(user, age);
};
display();
/* output
{
name: 'Jane',
location: 'NY',
job: 'Software Developer'
} 30
*/
이제 아래 ES5 코드를 살펴보십시오.
// ES5 Code
function getUsers(page, results, gender, nationality) {
var params = "";
if(page === 0 || page) {
params += `page=${page}&`;
}
if(results) {
params += `results=${results}&`;
}
if(gender) {
params += `gender=${gender}&`;
}
if(nationality) {
params += `nationality=${nationality}`;
}
fetch('https://randomuser.me/api/?' + params)
.then(function(response) {
return response.json();
})
.then(function(result) {
console.log(result);
})
.catch(function(error) {
console.log('error', error);
});
}
getUsers(0, 10, 'male', 'us');
이 코드에서는 getUsers 함수에서 다양한 선택적 매개 변수를 전달하여 Random user API에 API를 호출합니다.
따라서 API 호출을 하기 전에 매개 변수 추가 여부를 확인하는 다양한 if 조건을 추가했으며 이를 기반으로 https://randomuser.me/api/?와 같은 쿼리 문자열을 구성합니다. page = 0 & results = 10 & gender = 남성 & 국적 = 미국
그러나 if 조건을 너무 많이 추가하는 대신 아래와 같이 함수 매개 변수를 정의하는 동안 기본 매개 변수를 사용할 수 있습니다.
function getUsers(page = 0, results = 10, gender = 'male',nationality = 'us') {
fetch(`https://randomuser.me/api/?page=${page}&results=${results}&gender=${gender}&nationality=${nationality}`)
.then(function(response) {
return response.json();
})
.then(function(result) {
console.log(result);
})
.catch(function(error) {
console.log('error', error);
});
}
getUsers();
보시다시피 코드를 많이 단순화했습니다. 따라서 getUsers 함수에 인수를 제공하지 않으면 기본값이 사용되며 다음과 같은 자체 값도 제공 할 수 있습니다.
getUsers(1, 20, 'female', 'gb');
따라서 함수의 기본 매개 변수를 재정의 합니다.
null is not equal to undefined
그러나 한 가지 알아야 할 것은 기본 매개 변수를 정의하는 동안 null과 undefined는 두 가지 다른 것입니다.
아래 코드를 살펴보십시오.
function display(name = 'David', age = 35, location = 'NY'){
console.log(name, age, location);
}
display('David', 35); // David 35 NY
display('David', 35, undefined); // David 35 NY
표시 할 첫 번째 호출에서 세 번째 매개 변수를 제공하지 않았으므로 기본적으로 정의되지 않으므로 두 함수 호출 모두에서 location의 기본값이 사용됩니다. 그러나 아래 함수 호출은 동일하지 않습니다.
display('David', 35, undefined); // David 35 NY
display('David', 35, null); // David 35 null
인수로 null을 전달하면 undefined와 동일하지 않은 위치 매개 변수에 null 값을 할당하도록 구체적으로 지시하므로 기본값인 NY를 사용하지 않습니다.
Closing points
이 책은 총 144 페이지에 달하는 전문 콘텐츠를 자세히 설명하고 이해하기 쉬운 방법으로 설명합니다.
이 책은 JavaScript에서 더 나은 개발자가 되기 위해 만들어졌으며 React, Angular, Vue 등과 같은 모든 라이브러리 또는 프레임 워크에 이 지식을 적용 할 수 있습니다.
현재 책은 2020 년 12 월 11 일까지 원래 가격에서 43 % 할인 된 $ 13에 구입할 수 있습니다.
12 월 11 일 이후에는 책의 가격이 23 달러로 상승하므로 43 % 할인 된 가격에 구입하세요.
이 책에 대해 다시는 그렇게 큰 할인을 받지 못할 것입니다. 그러니 놓치지 마세요.
이 웹 사이트에서 책에 대한 자세한 정보를 찾을 수 있습니다.
위에서 언급 한 웹 사이트에서 이 책의 다른 미리보기 콘텐츠를 다운로드 할 수도 있습니다.
https://dev.to/myogeshchavan97/master-modern-javascript-skills-with-this-amazing-guide-l34
등록된 댓글이 없습니다.