DAY - 16

공부 저장소·2021년 6월 30일

WILT [ What I Learn Today ]

목록 보기
16/17
post-thumbnail

나머지 매개변수

특정 갯수의 인자(매개변수)를 필요로 하는 함수에 함수 실행문에서의 인수를 인자 갯수보다 적게 보내면 함수는 undefined를 반환하지만 인자보다 인수가 더 많아서 인수가 남는 경우에 남는 변수를 나머지 매개변수(Rest parameters)라고 한다.

여러 번 사용되는 함수인데 인수의 개수가 특정 지어지지 않았을 때 사용되며 나머지 매개변수는 인자를 배열 형태로 받는 형식이다

(나머지 매개변수는 배열의 메소드 사용이 가능하다.(length(), reduce(), 등등...)

ex) 인수로 보내는 모든 수를 더하는 함수.

function addAll(...nums){
    let result = 0;
    nums.forEach(num => (result += num));
    return result;
}

console.log(addAll(1,2,3)); // 6
console.log(addAll(4,5,6)); // 15

ex) 생성자 함수 프로퍼티에 값이 하나가 아닐 때.

function User(name, age, ...skills){
    this.name = name;
    this.age = age;
    this.skills = skills;
}

let user1 = new User("Mike", 30, "HTML", "CSS");
let user2 = new User("Wonseo", 26, "JS", "React");
let user3 = new User("Sam", 20, "Java");

console.log(user1)	// User { name: 'Mike', age: 30, skills: [ 'HTML', 'CSS' ] }
console.log(user2)	// User { name: 'Wonseo', age: 26, skills: [ 'JS', 'React' ] }
console.log(user3)	// User { name: 'Sam', age: 20, skills: [ 'Java' ] }

나머지 매개변수는 인자에서 항상 마지막에 위치하여야 한다.
(오류 초래) Rest parameter must be last formal parameter]

전개 구문

전개구문 (Spread Syntax)이란 나머지 매개변수처럼 ...변수명의 형태로 생겼으나 생김새는 많이 다르다.

아래의 예로 간단히 살펴보겠다.

전개구문을 이용하여 한 객체의 모든 내용을 다른 객체 안에 집어넣기

const user1 = {name : "Mike"};
const user2 = {...user1, age : 30};	// user1 객체의 내용을 user2 객체 내 앞 부분에 삽입
user2.name = "Sam"

console.log(user1);	// { name: 'Mike' }
console.log(user2);	// { name: 'Sam', age: 30 }

배열 내에 순서를 건드리지 않고 배열 끼리의 순서를 바꿔 집어넣기

let arr1 = [1,2,3];
const arr2 = [4,5,6];

arr1 = [...arr2, ...arr1];	// arr1 배열 안에 전개 구문을 이용하여 arr2 배열을 넣고 그 뒤에 arr1을 넣음

console.log(arr1);	// [ 4, 5, 6, 1, 2, 3 ]

객체와 배열 형태들을 한 객체 안에 저장할 때

let user = {name : "Mike"};
let info = {age : 30};
let fe = ["JS", "React"];
let lang = ["Korean", "English"];

    user = {
        user,	// user 객체 내용을 넣고
        info,	// info 객체 내용을 넣고
        skills : [...fe, ...lang]	// skills 프로퍼티의 배열 값 안에는 fe와 lang의 모든 정보를 전개구문을 통하여 집어넣음
    };

console.log(user);
//	{
//		user: { name: 'Mike' },
//		info: { age: 30 },
//		skills: [ 'JS', 'React', 'Korean', 'English' ]
//	}

클로저

자바스크립트는 어휘적 환경(Lexical Enviroment)을 갖는다.

//스크립트 시작 준비 단계 (1)
let one;	// (2)
one = 1;	// (3)
function addOne(num){
    console.log( one + num );
}

addOne(5);	// (4)

해당 스크립트를 실행하였을 Lexical 환경의 변화는 아래와 같다.

(1) one : 초기화X [현재 사용불가]
addOne:function 이 Lexical 환경에 올라간다.

(2) 본격적으로 위에서부터 아래로 읽어내림
one : undefined [사용 가능]
addOne : function

(3) one : 1
addOne : function

(4) 함수를 실행하며 새로운 Lexical 환경 생성

내부 Lexical 환경 (함수를 실행하여 생성된 Lexical 환경)
함수가 넘겨받은 매개변수와 지역변수들이 저장 되어 있음.
num :5
전역 Lexical 환경 (기존에 존재하던 Lexical 함수)
전역 스코프의 변수와 함수가 저장되어 있음.
one : 1
addOne : function

내부 Lexical 환경은 전역 Lexical 환경을 참조하고 있음.

다만, 내부 Lexical 환경이 참조하는 바로 위 상위 값은 늘 전역 Lexical 환경은 아니고 상위 함수의 Lexical 환경을 참조할 수 있음.
예를 들면, addOne()함수 실행 시에 해당 함수 표현식대로 동작을 할 때에 num은 내부 Lexical 환경에 존재하여 바로 찾을 수 있지만 one은 내부 Lexical 환경에 존재하지 않아 참조하는 외부의 전역 Lexical 환경에서 변수를 가져옴

마무리로 예를 들며 어휘적 환경을 마무리 하도록 하겠다.

function makeAdder(x){
    return function(y){
        return x+y;
    };
}

const add3 = makeAdder(3);
console.log(add3(2));

순차 설명)
1. 전역 Lexical 환경에서 makeAdder()와 add3 상수를 선언 함.
2. const add3에 할당되는 makeAdder(3) 실행
3. 해당 함수는 add3에 makeAdder에서 return 되는 함수를 할당 하며 makeAdder Lexical 환경을 생성하며 안에는 x : 3의 값을 가지고 있음.

const add3 = function(y){
  return 3 + y;
}

해당 함수가 add3에 할당되는 구조.
4. console.log()안에서 add3(2)가 실행 되며 add3의 Lexical 환경이 생성되며 y : 2의 값을 가지고 있음.

x + y의 계산을 할 때에 x는 add3의 Lexical 환경에 존재하지 않기에 상위에 참조하는 makeAdder의 Lexical 환경에서 x의 값을에 접근하고 y의 값은 해당 add3의 Lexical 환경에서 참조하여 3 + 2(y인자)를 반환하여 콘솔 창에 5가 출력 됨.

이 함수는 생성될 당시의 외부 변수(전역 변수, 상위 함수의 Lexical 환경이 가지는 변수)를 기억하여 이후에도 계속 접근이 가능 한 이러한 함수와 Lexical 환경의 조합을 Closure 라고 한다.

setTimeout, setInterval

SetTimeout은 일정 시간이 지난 후 함수를 실행하는 것이다.

function fn(){
    console.log("타임 아웃");
}

setTimeout(fn, 3000);	// 3초 뒤 fn() 함수 실행

----------------------------------

setTimeout(function(){
  console.log(3);
}, 3000);	//위와 동일하게 작동(함수를 안에 작성)

-----------------------------------
  
function showName(name){
  console.log(name);
}

setTimeout(showName, 3000, "Mike");
// 실행 할 함수의 인수가 필요하다면 setTimeout의 인수의 맨 뒤에 넣어주면 된다.

인수로 동작할 함수와 실행 후 동작까지의 시간을 받는다.

같이 사용하는 함수로는 ClearTimeout(tId);이 있다.

const myTimeout = setTimeout((fn)=>console.log(`Time ${fn} !!`), 3000, "Out");
clearTimeout(myTimeout);

이 처럼 setTimeout은 값을 반환하는데 해당 값을 할당하여 해당 setTimeout의 이름처럼 사용할 수 있다.

값을 할당받은 변수를 clearTimeout에 인수로 넣어주면 해당 setTimeout의 실행을 막는다.

setInterval은 일정 시간 간격으로 함수를 반복하는 것이다.

const myInterval = setInterval((fn)=>console.log(`Time ${fn} !!`), 3000, "Interval");
clearInterval(myInterval);

setTimeInterval은 위처럼 setTimeout과 문법은 같다.

해당 함수들의 간단한 예로는

let num = 0;
function showTime(){
  
    console.log(`안녕하세요, 현재 접속하신지 ${num++}초 됐습니다.`);
  
    if(num > 5){
        clearInterval(tId);
    }
}

const tId = setInterval(showTime, 1000);
//안녕하세요, 현재 접속하신지 0초 됐습니다.
//안녕하세요, 현재 접속하신지 1초 됐습니다.
//안녕하세요, 현재 접속하신지 2초 됐습니다.
//안녕하세요, 현재 접속하신지 3초 됐습니다.
//안녕하세요, 현재 접속하신지 4초 됐습니다.
//안녕하세요, 현재 접속하신지 5초 됐습니다.
//		[num이 5가 넘었으므로 종료된다.]
profile
https://github.com/WonseoYang

0개의 댓글