var 대신에 const 혹은 let을 사용 -> block scope
호이스팅
JavaScript에서 호이스팅(hoisting)이란, 인터프리터가 변수와 함수의 메모리 공간을 선언 전에 미리 할당하는 것을 의미합니다.
var
로 선언한 변수의 경우 호이스팅 시undefined
로 변수를 초기화합니다. 반면let
과const
로 선언한 변수의 경우 호이스팅 시 변수를 초기화하지 않습니다.
https://developer.mozilla.org/ko/docs/Glossary/Hoisting
console.log(name)
var name = 'test';
console.log(name);
// 결과
> undefined
> test
const, let을 사용하면 호이스팅 X
tom1 === tom2
let tom1 = {
name: "Tom",
age: 10,
region: "Seoul",
}
let tom2 = {
"name": "Tom",
"age": 10,
"region": "Seoul",
}
Key 게산이 필요한 경우
const tom2 = {
"name": "Tom",
"age": 10,
"region": "Seoul"
["score" + "1"]: 100,
}
단축 속성명
tom1 === tom2
let name = "Tom";
let age = 10;
let tom1 = {
name: name,
age: age,
print: function() {
console.log(`name: ${this.name}, age: ${this.age}`);
}
};
let tom2 = {
name,
age,
print() {
console.log(`name: ${this.name}, age: ${this.age}`);
}
};
JS는 Object/Array에 대해서는 대입 시에 얕은 복사 (Shallow Copy)
const obj1 = { value1: 10 };
const obj2 = obj1;
const obj3 = JSON.parse(JSON.stringify(obj1)) // 깊은 복사
obj1.value1 += 1;
console.log(`obj1:`, obj1);
console.log(`obj2:`, obj2);
console.log(`obj3:`, obj3);
JSON.parse()
메서드는 JSON 문자열의 구문을 분석하고, 그 결과에서 JavaScript 값이나 객체를 생성합니다.
JSON.stringify()
메서드는 JavaScript 값이나 객체를 JSON 문자열로 변환
템플릿 리터럴은 내장된 표현식을 허용하는 문자열 리터럴입니다. 여러 줄로 이뤄진 문자열과 문자 보간기능을 사용할 수 있습니다.
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Template_literals
Multi-line string
String Interpolation
`string text ${expression} string text`
백틱(`) 사용
let [name] = ["Tom", 10,"Seoul"] // "Tom" 대입
let [, age,] = ["Tom", 10, "Seoul"] // 10만 대입
let [name, age, region, height] = ["Tom", 10, "Seoul"] // height 값은 undefined
let [name, age, region, height=150] = ["Tom", 10, "Seoul"] // height 디폴트값 할당
const tom = {
name: "Tom",
age: 10,
region: "Seoul"
}
const { age, name, height } = tom;
// 객체에서 필요한 값들만 추출, height는 undefined
const print_person = ({ name }) => {
console.log(name)
}
const person = {
name: "Tom",
age: 10,
region: {
country: '서울',
postcode:'06222'
}
}
// region은 할당되지 않고 경로로만 사용된 것
const { name, region: { postcode }} = person
const tom = {
name: "Tom",
age: 10,
region: "Seoul"
}let [name, ...rest] = ["Tom", 10, "Seoul"] // name에는 "Tom", rest에는 나머지 인자가 대입(Array)
// 여러 개의 인자를 전달받을 때
let printArgs = (...args) => {
console.log(args)
}
//
const tom = {
name: "Tom",
age: 10,
region: "Seoul"
}
// 속성명이 중복될 경우, 마지막 값이 대입
const steve = {
...tom,
name: "Steve"
}
리액트에서는 수많은 값들을 불변객체로서 처리
👉 Spread Operator
모든 타입의 값들을 디폴트 파라미터로 지정할 수 있다
function hello(name="Tom", age=10) {
console.log(`나느 ${name}. ${age} 살`)
}
const get_default_age = () => 10
function hello(name="Tom", age=get_default_age()) {
console.log(`나느 ${name}. ${age} 살`)
}
디폴트 값에 함수를 적용할 경우
👉 자바스크립트에서는 값이 필요할 때 호출
객체 비구조화를 활용
function print_person1(name, age, region) {
console.log('1>', name, age, region)
}
print_person1('Tom', 10, 'Seoul') // Index에 맞게 대입
function print_person2({ name, age, region }) {
console.log('2>', name, age, region)
}
print_person2({ name: 'Tom', age: 10, region: 'Seoul' })
return을 사용하지 않아도, 계산된 값을 반환
인자가 1개일 경우, 소괄호 생략 가능
let hello1 = (name, age) => {
return `안녕. 나는 ${name}. ${age}이야.`;
}
// 함수를 중괄호로 감싸지 않으면, return 문을 쓰지 않아도 반환값으로 사용
let hello2 = (name, age) => `안녕. 나는 ${name}. ${age}이야.`;
this와 arguments를 바인딩하지 않음
모든 객체에는 this가 존재
var tom = {
name: "Tom",
print1: function() {
console.log(`[print1-1] name: ${this.name}`)
(function() {
// 내부 function의 this로 변경
console.log(`[print1-2] name: ${this.name}`)
})
}
}
> [print1-1] name: Tom
> [print1-2] name: undefined
const mysum1 = (x, y) => x + y;
const mysum1 = (x, y) => x + y;
const mysum1 = (x, y) => ({x: x, y: y}); // 콜론으로 인해, 소괄호 필요 (함수로 인지하기 때문)
const mysum1 = (x, y) => {
return {x: x, y: y}
}
비동기 개발을 할 때 많이 사용하는 기법
const fs = require('fs')
fs.readdir('.', function (err, files) {
if (err) {
cosole.log('Error finding files: ' + err)
} else {
console.log(files);
}
})
// 위 fs.readdir이 끝나기 전에 수행
console.log("ENDED")
const fs = require('fs')
const fsPromises = fs.promises
fsPromises.readdir('.')
.then(files => {
cosole.log('Error finding files: ' + err)
})
.catch(err => console.error(err))
})
// 위 fsPromises.readdir이 끝나기 전에 수행
console.log("ENDED")
ES8 (ECAM 2017) 부터 지원
await : promise의 then을 기다림 (await를 사용하면 함수는 항상 async)
비동기이지만 동기적인 방식으로 이해할 수 있는 로직
const fs = require('fs')
const fsPromises = fs.promises
async function fn() {
try {
let files = await fsPromises.readdir('.');
console.log(files);
}
catch(err) {
console.error(err)
}
}
fn() // async 함수이기에,완료 전에 다음 로직이 동작
console.log("ENDED")
예전 웹 상의 자바스크립트에서는 script 태그를 통해서만 로딩
2가지 모듈 시스템
IE를 포함한 구형 브라우저에서는 미지원
node 이후에 ES6 Module이 나왔기에, node에서는 왠만한 ES6 문법은 지원하지만, 모듈은 ES6 module 지원하지 않고, CommonJS만을 지원
문법: export, import
node에서 지원하는 일반적인 모듈 패턴
문법: module.export, require
함수를 인자로 받거나 반환이 가능하고, 다른 함수를 조작하는 함수
함수/클래스 역시 모두 객체