JS 튜토리얼 기본 4부

밍글·2023년 4월 22일
0

JS튜토리얼정리

목록 보기
4/10
post-thumbnail

이번 4부에는 저번파트를 계속 이어서 진행할 것이고 함수에 대해서 좀 더 알아볼 것이다. 예전에 다룬 함수파트는 기본파트였다면 이번에 다룰 함수파트는 업그레이드 된 버전이라고 생각하면 될 것이다. 그럼 시작해보도록 하겠다😆


자료구조와 자료형(나머지 Part)

구조 분해 할당(그 중 '...'다루기)

배열이나 객체에서 앞쪽에 위치한 값 일부만 필요하고 그 이후 나머지는 한데 모아서 저장하는 방법이다. 이 때 점 세게 ...를 붙인 배개변수 하나를 추가하면 나머지 요소를 가져올 수 있다. 다음은 이를 활용한 예시이다.

//배열예시
let [name1, name2, ...rest]
= ["Julius", "Caesar", "Consul", "of the Roman Republic"];
//이 때 rest는 배열이다.
alert(rest[0]); // Consul
alert(rest[1]); // of the Roman Republic
alert(rest.length); // 2
//객체예시
let options = {
  title: "Menu",
  height: 200,
  width: 100
};
// title = 이름이 title인 프로퍼티
// 이 때 프로퍼티 이름이 해당 객체에 없다면 default가 들어가게 된다.
// rest = 나머지 프로퍼티들
let {title, ...rest} = options;
// title엔 "Menu", rest엔 {height: 200, width: 100}이 할당된다.

JSON과 메서드

객체를 문자열로 전환해야 할 때 사용하는 방법이다. JSON (JavaScript Object Notation)은 값이나 객체를 나타내주는 범용 포맷이다. 자바스크립트가 제공하는 JSON 관련 메서드는 다음과 같다.

  • JSON.stringify : 객체를 JSON으로 바꿔준다. ❗️객체뿐만 아니라 원시값에도 적용할 수 있다.
  • JSON.parse : JSON을 객체로 바꿔준다.
let student = {
  name: 'Joe',
  age: 25,
  isAdmin: false,
  courses: ['html', 'css', 'js'],
  wife: null
};

let json = JSON.stringify(student);

alert(typeof json); // 문자열이라고 뜬다

alert(json);
/* JSON으로 인코딩된 객체로 나오게 된다.
{"name":"Joe",
  "age":25,
  "isAdmin":false,
  "courses":["html","css","js"],
  "wife":null
}
*/

⭐️객체에 toJSON이라는 메서드가 구현되어 있으면 객체를 JSON으로 바꿔준다. JSON.stringify는 이런 경우를 감지하고 toJSON을 자동으로 호출해준다.

//toJSON예시
let room = {
  number : 23,
  toJSON(){
  	return this.number;
  }
};

let meet = {
  title : "팀플활동",
  room
};

alert(JSON.stringify(meet));
/*
{
	"title":"팀플활동",
	"room":23
}
*/

심화학습(함수Part)

⚠️이 파트도 재귀같은 부분은 생략되어 있다⚠️

스프레드 문법

배열을 통째로 매개변수에 넘겨줄 때 '...'을 사용해줘야 한다. 예시는 아래 코드와 같다. 이 때 ...arr는 나머지 매개변수가 아닌 인수 목록으로 '확장’되는 역할을 하게 된다.

let arr = [3, 5, 1];
let arr2 = [1, 4, 11];
let arr3 = [...arr]; // arr의 복사본

alert( Math.max(arr) ); // NaN
alert( Math.max(...arr) ); // 5

//여러 개를 전달하는 것도 가능하다.
alert( Math.max(...arr , ...arr2) ); // 11

//복사본 관련
//요소 동일 여부
alert(JSON.stringify(arr) === JSON.stringify(arr3)); // true
// 두 배열 일치 여부
alert(arr === arr3); // false (참조가 다름)

arr.push(50);
alert(arr); // 3, 5, 1, 50
alert(arr3); // 3, 5, 1

참조가 다르기 때문에 기존 요소를 변경하여도 복사본에 영향을 받지 않는다.
➡️ 즉, 각 요소를 분리한 뒤, 매개변수 목록으로 만든 다음에 새로운 곳에 할당하는 것이다.

클로저

먼저 클로저를 이해하기 이전에 스코프에 대한 이해가 숙지되어있어야 한다.
자바스크립트에는 함수 스코프가 있고, 함수 내부에서 정의된 변수라면 함수의 어느 부분에서든 접근할 수 있다. 즉, 내부 함수에서 자신을 포함하는 외부 함수의 스코프에 접근할 수 있다는 뜻이다.

let outer = function (){
 let a = 1;
  let inner = function(){
   	let b = 2;
    let c = 3;
    
    a = a + b + c; //외부 함수에 있는 변수에 접근할 수 있다.
    alert(a);
  };
  inner();
};
outer();

내부 함수가 외부 함수보다 오래 살아남아 있을 경우에는 어떻게 될까?
즉, 저 함수에서 inner()로 끝나는 것이 아닌 return으로 inner을 반환하여 다른 변수에 할당하여 외부함수가 끝났음에도 불구하고 내부 함수가 반환되어있다는 것이다. ➡️ 그럼에도 기존과 똑같은 값을 반환한다.

클로저란 폐쇄된 공간에 대한 접근 권한을 가진 함수를 뜻한다.

클로저를 이용하면 비공개 데이터를 만들 수 있게 된다.

let student =(function(){
  let name = 'Joe';
  let age = 25;
  
  return{
      getName : function(){
    alert(name);
  	return name;
  },
  getAge : function(){
    alert(age);
  	return age;
  }
  };
})();
student.name = 'Min'; 
student.getName(); //Min으로 변경하여도 Joe가 출력된다.

호출 스케줄링

일정 시간이 지난 후에 원하는 함수를 예약 실행(호출)할 수 있게 하는 것을 호출 스케줄링이라고 한다.
구현하는 방법 2가지
1. setTimeout을 이용해 일정 시간이 지난 후에 함수를 실행하는 방법
2. setInterval을 이용해 일정 시간 간격을 두고 함수를 실행하는 방법

//setTimeout예시
function sayHi() {
  alert('안녕하세요.');
}
setTimeout(sayHi, 1000); //1초 뒤에 실행된다
//setInterval예시
//2초 간격으로 메시지 호출
let timerId = setInterval(() => alert('째깍'), 2000);
// 함수 호출을 중단하려면 clearInterval(timerId)을 사용
//10초 뒤 정지
setTimeout(() => { clearInterval(timerId); alert('정지'); }, 5000);

setTimeout이나 setInterval의 경우 밀리초이기 때문에 1000이 1초로 된다.

setInterval을 이용하지 않고 중첩setTimeout을 통해서도 일정 간격을 두고 시행할 수 있는데 중첩setTimeout이 지연간격을 보장한다는 장점이 존재한다. 그 이유는 지연 간격이 보장되는 이유는 이전 함수의 실행이 종료된 이후에 다음 함수 호출에 대한 계획이 세워지기 때문이다. 아래의 그림을 보면 차이가 보일 것이다.
첫 번째 그림은 setInterval로 1초마다 실행하는 모습이다. 그림을 보면 호출 시간보다 더 짧은 모습을 볼 수가 있는데 그 이유는 함수를 실행하는 데 ‘소모되는’ 시간도 지연 간격에 포함시키기 때문이다.

두 번째 그림은 중첩 setTimeout으로 사용한 모습이다. 이전 함수의 실행이 종료된 이후에 다음 함수 호출에 대한 계획이 세워지기 때문에 지연 간격이 1초로 잘 되어 있는 모습을 볼 수 있다.

//중첩 setTimeout예시
let timerId = setTimeout(function tick() {
  alert('째깍');
  timerId = setTimeout(tick, 2000); // (*)
}, 2000);

call, apply, bind

call() : this의 값을 바꿀 수도 있고 함수를 실행할 때 사용할 인수도 전달할 수 있다.

//call 예시
function sayHi(value) {
  alert(`내 이름은 ${this.name}${value}를 좋아해`);
}

let user = { name: "John" };
let otherUser = { name: "Amy" };

// call을 사용해 원하는 객체가 'this'가 되도록 한다.
sayHi.call( user, "hiking");
// 내 이름은 John고 hiking를 좋아해 -> 여기서 this는 John
sayHi.call( otherUser, "biking" ); 
// 내 이름은 Amy고 biking를 좋아해 -> 여기서 this는 Amy

apply() : 함수를 실행할 때 인수를 배열로 묶어 한번에 전달하는 역할을 한다. call은 하나하나 보낼 수 있다면 apply는 배열로 묶어서 한꺼번에 묶어서 보낼 수 있다.

call()이랑 형식은 비슷하다.

//apply 예시
function sayHi(item1, item2){
	[item1,item2].forEach(function(e){
      alert(`안녕! ${this.name}, 여긴 ${e}의 집이야`)
    }, this) //forEach 안에서 this를 선언을 해줘야 this를 전달받음
}

let user = {
  name : "John"	
}

sayHi.apply(user,["Amy","Jenny"]);
//this에는 John을 가리키고 되고 Amy,Jenny순으로 alert 수행

bind() : this 값을 어디서 사용하든 호출 객체가 바뀌지 않게 고정시킨다.

//bind 예시
let user = {
  firstName: "John",
  say(phrase) {
    alert(`${phrase}, ${this.firstName}!`);
  }
};

let say = user.say.bind(user);
//this는 user로 고정된다.

say("Hello"); // Hello, John ("Hello"가 say로 전달되었다.)
say("Bye"); // Bye, John ("Bye"가 say로 전달되었다.)

🚨 화살표 함수 사용시 유의할 점

  • this를 가지지 않는다.
  • arguments를 지원하지 않는다.
  • new와 함께 호출할 수 없다.
  • 클래스에서 사용 되는 super가 없다
profile
예비 초보 개발자의 프로젝트와 공부 기록일지

0개의 댓글