web/javascript 기초

[패스트캠퍼스] 국비지원 17일차 학습일지

xudegloss 2023. 5. 21. 01:05

1. 함수 복습하기

  • 함수 실행을 반복해야 하는 경우에는 변수에 담아서 이용하는 것이 좋다. 하지만 단일 이용하는 경우에는 그냥 실행하는 것이 좋다.
  • 익명 함수 ↔ 기명 함수
  • return은 데이터를 반환하거나 그 순간에서 종료할 때 이용한다. (return 밑에 있는 코드는 실행되지 않는다. 즉, 코드 실행을 마치고 싶은 경우에 return 이용하기.)
  • return 뒤에 어떠한 데이터도 지정하지 않는 경우에는 undefined 반환된다.

 

// arguments
// parameters 지정하지 않고도 arguments 불러와서 적용 가능하다.
// 하지만, 매개변수 명시하는 것이 더 권장된다.

function arguments() {
  console.log(arguments);
  return arguments[0] + arguments[1];
}

console.log(arguments(1, 4)); // 매개변수 지정 안 해도, arguments 가져올 수 있다.

 

arguments를 이용하여 매개 변수 지정하지 않아도 데이터 받아올 수 있게 할 수 있지만, 매개 변수의 의미를 알기 힘들기 때문에 자주 이용하지 않는다.

 

 

2. 화살표 함수

// Arrow Function

const 함수 이름 = () => {
	출력하고자 하는 명령어;
}

 

// 객체를 반환하는 방법 : 소괄호 이용하기.
// 화살표 함수는 축약형이 가능하다.

// const objectArrow = (x) => ({ name: "FastCampus" });

const objectArrow = (x) => ({
  name: "FastCampus",
});

console.log("objectArrow: ", objectArrow());

 

객체 받아오는 방법은 소괄호를 이용하여 받아올 수 있다.

 

// 위와 동일하지만, 위는 축약형이다.

const objectArrow = (x) => {
  return {name: "FastCampus"}
};

console.log("objectArrow: ", objectArrow());

 

소괄호를 이용한 축약형이 가능하다.

 

 

3. 즉시 실행 함수 IIFE

Immediately Invoked Function Expression

 

const x = 7;

function double(x){
	return x * 2;
}

double();

// 위의 코드를 IIFE로 변경할 수 있다.

 

📌 (익명 함수)(); 형태로 IIFE 표현 가능하다.

 

(function () {
  console.log(a * 2);
})(); // (익명 함수)();

 

IIFE로 표현하면, 실행하지 않아도 바로 실행된다.

 

 

4. 호이스팅  Hoisting

함수 선언부가 유효 범위 최상단으로 끌어 올려지는 현상을 의미한다. 즉, 선언 전에 호출 가능하다는 의미이다.

 

어떤 경우에 유용할까? 미리 실행하고 맨 밑에 함수를 선언하면, 실행되는 함수 이름을 보고 함수의 기능을 유추할 수 있기 때문에 코드를 보기 편리하다는 장점이 있다.

 

따라서 익명 함수와 호이스팅을 이용하여 코드를 보기 더 편리하게 제작한다.

 

 

5. 타이머 함수

 

타이머 함수는 많은 경우에서 이용되기 때문에, 잘 알아두는 것이 좋다.

setTimeout(함수, 시간)  * 시간은 ms로 작성하고, 1000ms가 1s이다.
setInterval(함수, 시간)  * 시간은 ms로 작성하고, 1000ms가 1s이다.

clearTimeout(반환되는 특정 타이머 값)
clearInterval(반환되는 특정 타이머 값)

 

  • setTimeout과 setInterval은 특정 타이머 값을 반환할 수 있다.
  • setTimeout과 setInterval 안에 함수를 작성하는 경우에는 익명 함수를 이용하는 것이 여러모로 유리하다. (this 라는 개념 때문에)

 

// 특정한 타이머 값을 반환할 수 있다.

const timer = setTimeout(() => {
  console.log("3초 후에 실행됩니다.");
}, 3000);

// 버튼을 클릭하면 함수 종료하는 로직 제작하기.
// clearTimeout으로 타이머를 제어할 수 있다.

const clearBtn = document.querySelector(".clear__timer");

clearBtn.addEventListener("click", () => {
  clearTimeout(timer);
  console.log("3초 후에 실행하는 타이머를 종료합니다.");
});

// setInterval

const timerRepeat = setInterval(() => {
  console.log("3초 마다 실행됩니다.");
}, 3000);

const clearBtnRepeat = document.querySelector(".clear__timer__repeat");

clearBtnRepeat.addEventListener("click", () => {
  clearInterval(timerRepeat);
  console.log("3초 마다 실행하는 타이머를 종료합니다.");
});

 

6. 콜백 함수 Callback

  • 함수의 인수로 사용되는 함수를 의미한다.
  • 예를 들면 setTimeout(함수, 시간) 에서 setTimeout 인수로 있는 함수가 콜백 함수이다.

 

Callback
1. 함수의 인수로 사용하는 함수를 의미한다.
2. 특정한 실행 위치를 보장하는 용도로 쓰인다.

 

콜백 함수를 이용하여 setTimeout  함수가 실행된 뒤에 명령문을 실행할 수 있다.

 

// setTimeout(함수, 시간)
// setTimeout 인수인 함수를 콜백이라고 부른다.

function timeout(callback) {
  setTimeout(() => {
    console.log("3초 후에 실행됩니다.");
    callback();
  }, 3000);
}

// callback 함수 이용하여 3초 후에 실행되는 Done을 출력하는 로직 구성하기.

timeout(() => {
  console.log("Done!");
}); // 3초 후에 실행된다.
// console.log("Done!"); // 바로 실행된다.

 

해석하는 방법

 

1. timeout 함수 호출 시에 하나의 익명 함수 (콜백 함수)를 인수로 사용한다.

2. 하나의 인수는 timeout 함수의 callback 이라는 매개 변수로 들어간다.

3. 매개 변수는 호출하지 않은 함수이기 때문에, 실행하고 싶은 위치에서 실행한다.

 

7. 프로토타입 Prototype

  • 생성자 함수를 만드는 경우에 prototype을 이용한다.
  • 동일한 메소드와 속성을 계속 선언하는 것은 메모리 낭비이기 때문에 생성자 함수를 이용하여 반복을 줄여준다. (멤버 = 속성 + 메소드)
  • 리터럴 : 약속된 기호를 통하여 값을 생성하는 표기법이다.
  • 예를 들면, { }은 객체를 생성하는 리터럴이다.
  • [ ]은 배열을 생성하는 리터럴이다.
  • " "은 문자열을 생성하는 리터럴이다.

 

// class 제작하는 방법

// 생성자 함수 : 하나의 객체 데이터 생성하기.

function User(first, last) {
  // 다른 데이터가 들어오기 때문에 이런 식으로 접근하기.
  this.firstName = first;
  this.lastName = last;
}

// getFullName은 동일하게 들어오기 때문에, prototype 이용하기.

User.prototype.getFullName = function () {
  return `${this.firstName} ${this.lastName}`;
};

// {}로 객체 만드는 방식을 리터럴 방식이라고 한다.
// new 통하여 생성자 함수 실행하기.
// 반환된 변수들은 인스턴스이다.

const james = new User("James", "Park");
const anne = new User("Anne", "Lee");
const sally = new User("Sally", "Kim");

console.log(james);
console.log(anne);
console.log(sally);

// 한 번만 만들어진 함수를 참조하는 방식이다.

console.log(james.getFullName());
console.log(anne.getFullName());
console.log(sally.getFullName());

 

 

  • 속성은 function 클래스명을 이용하여 정의한다. 이 때 클래스명 첫 글자는 대문자로 시작한다. this 이용하기.
  • 메소드는 클래스명.prototype.메소드명 = function( ){ }을 이용하여 정의한다. this 이용하기.
  • 클래스 불러올 때 앞에 new를 붙여준다.

 

마지막 과정을 진행하면 인스턴스가 제작된다. 

즉, 반환된 변수가 인스턴스이다.

 

그리고 메소드를 불러오는 형식은 한 번만 만들어진 함수를 참조하는 방식이다. (여러 번 함수를 만드는 것이 아니다.)

 

8. this

 

Normal Function Arrow Function
함수가 실행되는 위치에서 this가 정의된다. 자신이 선언된 함수 범위에서 this가 정의된다.

 

// this
// 일반 함수는 호출 위치에 따라 this 정의
// 화살표 함수는 자신이 선언된 함수 범위에서 this 정의

const james = {
  name: "James",
  normal: function () {
    console.log(this.name);
  },
  arrow: () => {
    console.log(this.name);
  },
};

james.normal(); // James
james.arrow(); // undefined

const anne = {
  name: "Anne",
  // 아래의 코드는 함수 자체를 가져온 코드를 의미한다.
  normal: james.normal,
  arrow: james.arrow,
};

anne.normal(); // Anne
anne.arrow(); // undefined

// class + this

// User는 생성자 함수이다.

function User(name) {
  this.name = name;
}

User.prototype.normal = function () {
  console.log(this.name);
};

User.prototype.arrow = () => {
  console.log(this.name);
};

const jason = new User("Jason");

jason.normal(); // Jason
jason.arrow(); // undefined

// setTimeout + this !!!

const timer = {
  name: "timerName",
  timeout: function () {
    setTimeout(() => {
      console.log(this.name);
    }, 2000);
  },
};

timer.timeout();

 

 

따라서 타이머 함수에서 콜백은 Arrow Function으로 사용하는 것이 좋다. * 상황에 따라 선택하여 사용하기.

 

 

9. ES6 Classes

앞에서는  prototype을 이용하여 메소드를 생성하였는데, 그럴 필요가 없어진다.

 

class 클래스명(){
	constructor(){
    
    }
    .
    .
    .
    메소드명(){
    
    }
}

 

위와 같은 코드를 이용하여 클래스 제작할 수 있다.

function 함수명( ){ } 을 함수명( ){ } 으로 축약하여 normal function으로 적을 수 있다.

 

class User {
  // constructor 내부 함수
  // normal function

  constructor(first, last) {
    this.firstName = first;
    this.lastName = last;
  }

  // prototype 없이 prototype으로 만들어지는 메소드 만들 수 있다.

  getFullName() {
    return `${this.firstName} ${this.lastName}`;
  }
}

const neo = new User("Neo", "Park");

console.log(neo);
console.log(neo.getFullName());

 

 

 

10. 상속 (확장) Inheritance

클래스에서 공통되는 부분은 상속을 통하여 처리하고, 추가적인 부분은 추가하여 사용할 수 있다.

 

class Vehicle {
  constructor(name, wheel) {
    this.name = name;
    this.wheel = wheel;
  }
}

const myVehicle = new Vehicle("운송수단", 2);
console.log(myVehicle);

// 확장 (상속)
// super는 Vehicle 의미한다.

class Bicycle extends Vehicle {
  constructor(name, wheel) {
    super(name, wheel);
  }
}

const myBicycle = new Bicycle("삼천리 자전거", 2);
const daughterBicycle = new Bicycle("세발 자전거", 3);

console.log(myBicycle);
console.log(daughterBicycle);

// 확장 (상속)
// super는 Vehicle 의미한다.

class Car extends Vehicle {
  constructor(name, wheel, license) {
    super(name, wheel);

    // 추가적인 부분은 추가해서 이용하기.
    this.license = license;
  }
}

const myCar = new Car("벤츠", 4, true);
const daughterCar = new Car("포르쉐", 4, false);

console.log(myCar);
console.log(daughterCar);

 

 

해석하는 방법

 

1. super를 설정하여, Inheritance를 진행할 수 있다. 즉, Vehicle의 로직을 Bicycle에 상속할 수 있다.

2. Bicyle에 Vehicle의 constructor인 name, wheel로 내용이 들어간다.

3. 내부에 있는 로직이 실행된다.

4. 추가적인 부분은 this를 이용하여 추가하여 이용할 수 있다. (normal function으로 만들어지기 때문에, this는 실행하는 위치에서 결정된다.)