JavaScript
- 함수 선언을 값처럼 → 함수 표현식
- 함수 선언 : 호이스팅, 함수 내에서 선언된것이 아닌 코드블록 내에서는 전역변수처럼 사용
- 함수 표현식 : 호이스팅되지 않음, 스코프 존재, 선언 이후에만 호출 가능.
- 둘중 한가지 방식으로 일관되게 사용하는것이 좋음, 함수 선언이 조금 더 권장
function 함수(파라미터) { // 함수 선언
return 리턴값;
}
const p = function() { // 함수 표현식
return 리턴값;
};
btn.addEventListener('click', function() {
...
});
Named Function Expression(기명 함수 표현식)
- 재귀 함수에서는 기명 함수 표현식을 쓰는것이 좋음.
- 재귀함수 사용 시 사용하려는 함수가 null이 되버리면 문제가 되므로 네이밍을 다르게 해준다.
const func = function test() {
...
}
test() // Error
const factorial = function (n) {
if (n <= 1)
return 1
return n * factorial(n-1);
}
let f = factorial;
factorial = null;
t = f(5) // => 오류
const factorial = function fact(n) {
if (n <= 1)
return 1
return n * fact(n-1);
}
let f = factorial;
factorial = null;
t = f(5) // 에러 x
즉시 실행 함수
- 함수가 선언된 순간 바로 실행 (IIFE)
- Immediately Invoked Function Expression
- 외부에서 사용 불가능, 재귀함수로 만들 때는 이름 필요
(function func() {
실행문
})();
func(); // 에러 발생
(function init() {
// 초기화
})();
const fact = (function factorial(n) { // 재귀함수 만들때 이름 및 변수에 바로 리턴값 저장
if (n <= 1)
return 1
return n * factorial(n-1);
})(5); // 입력한 매개변수가 위 인자로 들어감
함수 값
- typeof 함수 ⇒ function, 함수는 객체
- 파라메터에 함수이름 ⇒ 콜백 함수
- 함수를 리턴할 수도 있음.
function a(b, c) {
return b() + c()
}
function f1() {
return 1;
}
function f2() {
return 2;
}
a(f1, f2) // f1, f2를 콜백함수라고 함
function a(b, c) {
return function() {
return b() + c(); // 여기서 b + c 하면 함수 코드 문자열 자체가 더해지는듯..
};
}
function f1() {
return 1;
}
function f2() {
return 2;
}
console.log(a(f1, f2)()) // 괄호를 하나 더 써줘서 바로 함수 호출하도록
Parameter
Argument
함수 호출시 a(b, c)에서 b,c는 argument
Argument의 개수에 따라 유연하게 동작하는 함수
function a(b, c, d) {
arguments // argument에 어떤것들이 전달되었는지
for (let arg of arguments) {
console.log(arg);
}
}
a('a', 'b', 'c', 'd')
- 따라서, 변수/함수명을 arguments로 지어서는 안됨!!
파라메터의 개수보다 적거나 많이 입력하더라도 입력한 개수만큼 출력
유사배열 → 배열의 메서드 사용 불가능
인덱싱을 통한 세분화가 필요함.
Rest Parameter
- ...변수명으로 선언
- args가 배열이므로 배열의 메서드들 사용 가능
- 일반 파라메터와 함께 사용 가능, 하지만 앞에 정의된 파라메터에 argument를 먼저 할당하고 나머지 argument를 배열로 묶으므로 가장 마지막에 선언해주어야 함
function a(...args) {
arguments // argument에 어떤것들이 전달되었는지
for (let arg of args) {
console.log(arg);
}
}
a('a', 'b', 'c', 'd')
function a(...args) { // 단 3개만 나오도록
let temp = args.slice(0, 3);
for (let arg of temp) {
console.log(arg);
}
}
a('a', 'b', 'c', 'd')
// 맨 앞 아규먼트만 빼고 나머지 출력하기
function ignoreFirst(a, ...args) {
for (let arg of args) {
console.log(arg)
}
}
function ignoreFirst(...args) {
args.shift()
for (let arg of args) {
console.log(arg)
}
}
Arrow Function
- 파라메터 1개 → 소괄호 생략 가능
- 파라메터가 없거나 2개이상 → 소괄호 필수
- return문 한개만 존재한다면 return문도 생략 가능
- return문 외에 다른 구문 필요시 생략 불가능
- return문이 객체인 경우는 함수의 중괄호와 헷갈릴 수 있으므로 () 감싸주어야 함.
- arguments 객체 사용하는 경우는 Arrow Function으로 바꾸기 어려움.
- rest parameter은 사용 가능.
const calc = (a, b)=>{
return a + b;
}
const calc = (a,b) => a+b;
const calc = (a,b) => ({answer: a+b}); // 소괄호 빼면 오류
This
- this : 함수를 호출하는 객체를 가르키는 키워드
- Arrow Function에서의 this는 arrow function이 선언되기 직전에 유효한 this 값
- 다른 객체(a)의 메소드에서 this를 사용하더라도, 또다른 객체(b)가 해당 메소드(a.f)를 가져와서 사용하는 경우 this에는 b가 들어간다.
console.log(this) // window
const obj = {
a: "11",
b: "22",
f: function () {
console.log(this)
}
}
const obj2 = {
a: "112",
b: "223",
f: function () {
console.log(this)
},
f2: obj.f
};
obj.f(); // obj
obj2.f(); // obj2
obj2.f2(); // obj2
조건 연산자
- if문을 간결하게 표현
- 표현식 ? true일때 : false일때
if (조건) {
} else {
}
switch(변수) {
case 1:
break
default:
}
// 조건 ? truthy일때 표현식 : falsy일때 표현식
function half(i) {
return i>50 ? true : false;
}
console.log(half(10)) // false
Spread 구문
const numbers = [1, 2, 3]
console.log(...numbers); // 1,2,3으로 출력됨.
console.log(1, 2, 3)
- slice()로 배열 복사해야 하는 문제점 해소 및 배열 concat시 사용
const numbers = [1, 2, 3]
const numbers_copy = [...numbers, 4]
const numbers2 = [4, 5, 6]
const numbers_concat = [...numbers, ...numbers2]
function a(b, c, d) {
return b + c + d;
}
a(...numbers); // spread, numbers를 여러개의 값으로 펼침
// ...numbers를 일반 변수에 대입 X
console.log({...numbers}) // 객체화 하는 경우 0:1, 1:2, 2:3 이런식으로 ..
모던한 프로퍼티 표기법
프로퍼티명과 변수/함수명이 같은 경우 프로퍼티명만 써주어도 됨.
const a = 'a'; const b = 'b'; const c = 'c'; const obj = { a, // == a:a b, c, }; console.log(obj)
객체 내부에서 function 선언하는 경우 :(콜론 기호)와 function 키워드 생략 가능
const obj = {
c() {
return 5;
}
}
obj.c();
⇒ 함수 이름이 반드시 필요하기 때문에 Arrow Function 사용시도 이름 써주어야 함.
프로퍼티명을 표현식으로
const obj = { //[표현식]:값
["a" + "b"]:1
}
옵셔널 체이닝
Destructuring(구조 분해)
배열 순서에 따라 값 매핑
const arr = ['a', 'b', 'c', 'd']
const [r1, r2, r3, r4] = arr // 인덱스에 따라 순서대로 할당, arr이 더 길더라도 순서대로만
const [r1, r2, r3, ...r4] = arr // r1~r3은 순서대로 할당, 나머지 값들은 r4에 넣어줌
const [r1='1', r2, r3, r4] = arr // 기본값 입력 가능
// Destructuring을 활용한 swap
let a = 10;
let b = 15;
[a, b] = [b, a]
console.log(a + "//" + b)
// 만약 arr의 길이가 더 짧다면 매핑 안되는 부분은 undefined
/* r1 = arr[0] r2 = arr[1] r3 = arr[2] */`
객체 Destructuring
- 프로퍼티 이름에 대해 매핑
- Rest → {프로퍼티명, ...프로퍼티명} = 객체
const obj = { a: 'a' b: 'b' }
const { a, b } = obj //
const { a: d, b: e} = obj // d, e로 선언(이름 지정)
// 객체 내부에 변수 이름으로 사용할수 없는 프로퍼티명이 있는 경우 반드시 필요
// [] 사용하여 표현식 쓸수 있음.
const { a: d, b: e, c=123 } = obj // 기본값 지정
const { a, ...rest } = obj
console.log(a)
console.log(b)
```