JavaScript
매개변수
- 함수에 인수를 전달하는 방법은,
arguments
를 전달하는 방법과 나머지 매개변수를 사용하는 방법이 있다. - 과거에는
arguments
만 사용할 수 있었고 화살표 함수에는arguments
만 사용할 수 있다. - ES6로 넘어오며 나머지 매개변수를 사용할 수 있게 됐다.
arguments
는 함수로 넘어 온 모든 인수에 접근할 수 있으며 함수 내에서 이용 가능한 지역 변수를 말한다.lenght, index
를 사용할 수 있어 배열이라고 생각할 수 있지만Array
형태의 객체이다.- 함수에 인자를 전달하지 않아도 실행할 수 있지만
undefined
가 출력된다.
1
2
3
4
5
6
7
8
function example(name) {
console.log(name);
}
example("Mike"); // Mike
example("Mike", "Tom"); // Mike , undefined
example(); // undefined
나머지 매개변수
- ES6를 사용할 수 있는 환경에선 나머지 매개변수를 사용하는 것이 좋다.
- 나머지 매개변수는 배열이기 때문에 배열에 사용할 수 있는 메서드를 사용할 수 있다.
- 나머지 매개변수는 항상 마지막에 위치해야 한다.
1
2
3
4
5
6
7
8
function add(...nums) {
let result = 0;
nums.forEach((num) => (result += num));
console.log(result);
}
add(1, 2, 3); // 6
add(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); // 55
1
2
3
4
5
6
7
8
9
10
11
12
function User(name, age, ...skills) {
this.name = name;
this.age = age;
this.skills = skills;
}
const user1 = new User("Mike", 30, "html", "css");
const user2 = new User("Jane", 20, "react", "js");
const user3 = new User("Tom", 15, "vue");
// {name: "Mike", age: 30, Array(2)} {name: "Mike", age: 30, skills: ["html", "css"]}
// {name: "Jane", age: 20, Array(2)}
// {name: "Tom", age: 15, skills: vue}
전개구문 배열,객체,복제
- 배열에 메서드를 사용하지 않고, 전개구문을 사용하여 쉽게 추가할 수 있다.
1
2
3
4
5
6
7
8
// 배열
let arr1 = [1, 2, 3];
let arr2 = [4, 5, 6];
let result = [...arr1, ...arr2]; // [1,2,3,4,5,6]
// 객체
let user = { name: "Mike" };
let mike = { ...user, age: 30 }; // {name: "Mike", age: 30}
- 전개구문을 사용하지 않았을 때에 예시 1
1
2
3
4
5
6
7
8
9
10
let arr1 = [1, 2, 3];
let arr2 = [4, 5, 6];
// 원하는 값 [4,5,6,1,2,3]
// 전개구문을 사용하지 않았을 때
arr1 = arr2.reverse().forEach((item) => {
arr1.push(item);
});
// arr1 = [...arr1, ...arr2];
- 전개구문을 사용하지 않았을 때에 예시 2
1
2
3
4
5
6
7
8
9
10
11
12
13
let user = { name: "Mike" };
let age = { age: 30 };
let fe = ["react", "js", "css"];
user = Object.assign({}, user, age, {
skills: [],
});
fe.forEach((item) => {
user.skills.push(item);
});
// user = {...user, ...age, skills: [...fe]};
클로저
- 함수와 그 함수의 렉시컬 환경의 조합이다.
- 함수가 생성될 당시의 외부 변수를 기억하며, 생성 이후에도 계속 접근이 가능하다.
예제 1
1
2
3
4
5
6
7
8
let one;
one = 1;
function addOne(num) {
console.log(one + num);
}
addOne(5);
- 스크립트가 시작되면
Lexical Environment(어휘적 환경)
에one(초기화가 안 되었기 때문에 사용불가)
과addOne(function, 선언하자마자 초기화되기 때문에 사용가능)
이 추가된다.
- 변수에 선언된 함수는 초기화가 안 된다.
- 선언되고 코드가 첫 번째에 도달했을 때, 사용할 수 있게 된다.
one
은 아직undefined
이다.
- 이후,
addOne
에 도달했을 때, 함수가 실행되며 새로운Lexical Environment
이 생성되고 지역 변수인num
이 생성된다.- 전역
Lexical
에서는one: 1 , addOne: function
, 지역Lexical
에서는num: 5
- 전역
console.log
가 실행될 때, 지역 환경에서num: 5
를 찾았지만,one
은 존재하지 않는다.- 지역 환경에 존재하지 않기 때문에 전역 환경을 참조하게 되고, 전역 환경에서 선언된
one
을 사용하게 된다.
예제 2
1
2
3
4
5
6
7
8
9
10
function makeAdder(x) {
return function (y) {
return x + y;
};
}
const add3 = makeAdder(3);
console.log(add3(2));
const add10 = makeAdder(10);
console.log(add10(10));
- 마찬가지로 스크립트가 시작되면 전역
Lexical
환경에makeAdder: function, add3
이 선언되지만,add3
는 변수로 선언된 함수이기 때문에 초기화되지 않는다. add3
에 도달했을 때,makeAdder
의Lexical
환경이 만들어지게 되고 여기서x:3
이 선언된다.console.log
에 도달했을 때, 익명함수의Lexical
환경이 만들어지고y:2
가 선언된다.- 익명함수에서
makeAdder
환경을 참조하고,makeAdder
함수는 전역Lexical
환경을 참조하게 된다. add3
과add10
은 서로 다른 환경을 가지고 있다.
예제 3
1
2
3
4
5
6
7
8
9
10
11
12
13
function makeCouter() {
let num = 0;
return function () {
return num++;
};
}
let counter = makeCounter();
console.log(counter()); //0
console.log(counter()); //1
console.log(counter()); //2
makeCounter
는 내부 함수에서 외부함수를 참조하고 있다.- 내부 함수에서는
num
이 선언되지 않았지만, 참조하는 외부 함수에는num
이 선언되어 있기 때문에 이를 참조한다. num
은 외부 함수에 선언되어 있기 때문에 직접적으로num
에 접근하여 값을 수정할 수 없고,num
은 은닉화되었다고 한다.