let a = 'park';
let b = `hello, ${a}. nice to meed you`;
function func(m,n) {
console.log(m);
console.log(n);
}
func`hello, ${a}. nice to meed you`
//
(2) ['hello, ', '', raw: Array(2)]
0: "hello, "
1: ". nice to meed you"
length: 2
raw: (2) ['hello, ', '. nice to meed you']
[[Prototype]]: Array(0)
park
문서 해체분석기 가능
중괄호를 기준으로 문자들을 array 에 담아준다
→ 그래서 어디에 쓸건데 ?
글자의 순서를 바꿔볼까요 ?
function func(m,n) {
console.log(m[1] + n + m[0])
}
func`hello, ${a}. nice to meed you`
//
nice to meed youparkhello,
m[1] 은 중괄호를 기준으로 두번째(0부터 시작해서) 올 문장을 가리키므로
아주 쉽게 문장의 순서를 바꿔주는 코드를 짤 수 있다.
원래는 이렇게 복잡하고 바보같이 코드를 짜면 안되지만..
문자의 순서가 뒤죽박죽인것은 퀴즈 때문이니 나중에 다시 보더라도 부끄러워 하지 않아도 괜찮다.
$result.innerHTML = stockResult`바지${pants} 양말${socks}`;
function stockResult(m, n, n1) {
if (n === "0" && n1 === "0") {
return `남은 재고가 없습니다.`;
} else if (n === "0") {
return `${m[1]}은 ${n1}개, ${m[0]}는 팔지않습니다.`;
} else if (n1 === "0") {
return `${m[1]}은 팔지 않고, ${m[0]}는 ${n}개 판매중입니다.`;
} else {
return `${m[1]}은 ${n1}개, ${m[0]}는 ${n}개 판매중입니다.`;
}
}
백틱 기호 안의 문자를 마음대로 커스텀 할 function 을 하나 만든 후
결과값을 span class:result 에 넣어 출력하는 간단한 코딩.
버튼을 누르면 인풋이 초기화 되는 기능이나 조건문을 이용한 간단한 분기작업을 해줬다.
let array = ['hello', 'world']
console.log(array);
console.log(...array);
//
['hello', 'world']
0: "hello"
1: "world"
length: 2[[Prototype]]: Array(0)
hello world
let text = 'hello'
console.log(text)
console.log(...text)
//
hello
h e l l o
let a = [1,2,3]
let b = [4,5]
let c = [...a, ...b]
console.log(c)
[1, 2, 3, 4, 5]
배열을 합치거나 복사할 때 유용하다.
미분같다.
배열의 복사를 각각 독립적인 값을 가지도록 할 때 주로 쓰인다.
reference data type(array, object) 의 속성 때문인데, 배열을
let a = [1,2,3];
let b = a;
a[3] = 4;
console.log(a)
console.log(b)
(4) [1, 2, 3, 4]
(4) [1, 2, 3, 4]
이런식으로 복사하면 b가 a 배열의 주소값
을 복사하게된다.
주소값은 쉽게말해 가리킨다
라는 개념인데 특정 값이 저장되어있는 장소,
그러니까 이 경우에는 a라는 배열이 메모리 공간에 값을 저장한 주소를
b가 가리키게 복사를 한 경우이기 때문에
a의 값이 바뀌면 b는 a 배열의 메모리 공간을 가리키고 있으므로 값이 같이 변하게 된다.
이런 복사를 Shallow Copy, 얕은복사
라고 한다.
let a = [1,2,3];
let b = [...a];
a[3] = 4;
console.log(a)
console.log(b)
(4) [1, 2, 3, 4]
(3) [1, 2, 3]
spread operator 를 사용하면 배열의 주소값이 아닌 별도의 독립적인 값을 가지게 된다.
따라서 a의 값을 변경해도 b의 값이 변하지 않는다.
이런 복사를 Deep copy, 깊은복사
라고 한다.
object 도 쉽게 결합할 수 있다.
let o1 = {a:1, b:2};
let o2 = {...o1, c:3};
console.log(o2);
{a: 1, b: 2, c: 3}
주의할 점, object 는 값의 중복이 일어날 수 있다.
let o1 = {a:1, b:2}
let o2 = {a:3, ...o1}
console.log(o2)
// {a: 1, b: 2}
let o1 = {a:1, b:2}
let o2 = {...o1, a:3}
console.log(o2)
// {a: 3, b: 2}
object 를 복사할 때 중복되는 key 값이 있다면
나중에 오는 key 값의 value 의 값을 저장하게 된다.
function plus(a,b,c) {
console.log(a + b + c)
}
let array = [10,20,30]
Q. array 배열안에 있는 모든요소의 합을 구하시오.
A1.
plus(array[0], array[1], array[2])
// 60
A2.
plus.apply(undefined, array);
// 60
둘 다 메소드를 호출하는 메소드. 함수를 호출하는 방법이다.
파라미터를 받는 방식의 차이가 있는데 둘 다 첫번째 인자로는 this 를 대체할 값이 들어가며,
두번째 인자부터 call 은 각각의 인자를, apply 는 배열을 받는다.
예를들어,
function helloBot(name, age) {
console.log(`hello, my name is ${name}. i am ${age} year's old`)
}
helloBot('park', 30);
helloBot.call(null, 'park', 30);
helloBot.apply(null, ['park', 30]);
// hello, my name is park. i am 30 year's old
이런식으로 쓸 수 있다.
둘의 핵심은 this 의 이용에 있는데,
const obj1 = {
name : 'lee',
func : function() {
console.log(this.name)
}
}
const obj2 = {
name : 'park'
}
obj1.func();
obj1.func.apply(obj2);
// lee
// park
이런식으로 obj1 오브젝트의 함수를 obj2 오브젝트의 key 값을 this 로 찾아서 사용하는게 가능하다.
요컨데, 함수를 하나 구현해놓고 그때 그때 알맞는 객체로 바꿔서 해당 this 값에 맞는 기능을 실행할 수 있다.
또 다른 활용법으로는,
const park = {
이름 : 'park'
}
const lee = {
이름 : 'lee'
}
function user(나이, 생일, 성별) {
this.나이 = 나이;
this.생일 = 생일;
this.성별 = 성별;
}
user.call(park, 19, '0523', '남자');
user.apply(lee, [22, '0902', '여자']);
console.log(park);
console.log(lee);
//
{이름: 'park', 나이: 19, 생일: '0523', 성별: '남자'}
{이름: 'lee', 나이: 22, 생일: '0902', 성별: '여자'}
이런식으로 유저정보를 간단하게 업데이트 해주는 함수도 구현할 수 있다.
배열의 최소값, 최대값을 구할때도 쉽게 사용할 수 있는데,
const array = [1,3,20,40,60,80,90,2]
const max = Math.max.apply(undefined, array)
const min = Math.min.call(undefined, ...array)
// max = 90, min = 1;
이런식으로 쉽게 구현할 수 있다.
주의할점. call 함수는 파라미터로 각각의 숫자들이 와야하므로 spread operator 를 사용해야한다.
this 의 인자는 상관이 없으므로 undefined 를 입력.
A3.
plus(...array);
// 60
이렇게 spread operator 를 쓰면 간단하게 할 수도 있다.
function func1() {
return 10;
}
function func2(a, b = func1()) {
return a + b;
}
console.log(func2(2,3)) // 5
console.log(func2(2)) // 12
함수의 파라미터 값을 입력하지 않았을 경우에만 해당 값을 default 로 지정해줄 수 있다.
이 경우에 올 파라미터에 함수나 변수도 사용할 수 있다.
arguments = 모든 파라미터를 한꺼번에 다루고 싶을 경우 쓰는 키워드
키워드를 입력하면 함수의 모든 파라미터를 array 와 유사한 형식으로 묶어준다.
array형식이 아니라서 forEach 같은 메소드는 사용할 수 없다.
function func(a,b,c){
console.log(arguments);
for(let i=0; i < arguments.length; i++) {
console.log(arguments[i]);
}
}
func(1,2,3)
//
Arguments(3) [1, 2, 3, callee: ƒ, Symbol(Symbol.iterator): ƒ]
1
2
3
arguments 의 단점,
위의 함수에 임시 파라미터를 추가하고 싶다고 가정해보자.
function func(임시,a,b,c) {
...
}
이런식으로.
arguments 키워드를 쓰면 임시 파라미터를 추가했을 때
함수 내부의 값까지 바꿔주어야 정상적으로 작동할 것이다.
function func(a,b,c){
console.log(arguments);
for(let i=1; i < arguments.length; i++) {
console.log(arguments[i]);
}
}
i를 1부터 시작하게 하는 등, 작은 수정이 필요할 것 같다.
위의 함수는 함수라고 하기에도 부끄러울 정도로 아주 간단한 코드이지만
파라미터가 변하면 내부의 값을 수정해줘야 한다는 건
굉장히 골치아픈일이다.
그런 단점을 보완하여 나온 신 문법이 바로
function func2(...args) {
console.log(args);
}
func2(1,4,5,332,4,32,423,432,324,234325,52,25,52,25,23,3,25,25);
//(18) [1, 4, 5, 332, 4, 32, 423, 432, 324, 234325, 52, 25, 52, 25, 23, 3, 25, 25]
spread operator 를 사용하여 파라미터를 구성하면
파라미터 자리에 오는 모든 값을 array 에 담아 보관한다.
arguments 와 가장 큰 차이점이자 rest parameter 만의 장점은
let result = [];
function func3(a,...args) {
args.forEach( e => {
result.push(e * a);
})
}
func3(2,3,5,7,9,11,13,15,17)
console.log(result);
// (8) [6, 10, 14, 18, 22, 26, 30, 34]
헉 대박!
array 자료형이라서 forEach 도 쓸 수 있고,
인자를 구분해서 파라미터를 분리할 수도 있다!
첫번째 파라미터를 대상에 넣지않고 두번째 파라미터부터 계산한다.
단, rest 파라미터는 가장 마지막에 써야하고(’여기 뒤에 있는 모든 파라미터를 의미하기 때문’) 두번 쓸수 없다.