함수
함수 선언문
function hello() {}
함수 표현식
const hello = function () {}
함수선언문에서 호이스팅
함수 선언이 호출 아래에 있음에도 콘솔이 출력된다.
* 호이스팅이란? 함수(변수)의 선언이 유효한 범위내에서 최상위로 끌어올리지는 것을 의미한다.
함수 표현식에서 호이스팅
함수 표현식에서는 호출 아래 선언이 있는 경우 에러를 발생시킨다.
반환 및 종료
return 키워드 뒤에 값을 지정하지 않으면 undefined가 자동으로 반환된다.
매개 변수 패턴
매개 변수에 디폴트 value 를 설정할 수 있다.
user 라는 객체를 매개변수로 받아서 구조분해 하는 방법도 있지만
매개변수에서 바로 구조분해 할당하는 방법도 있다.
또한 매개변수에서 바로 구조분해하는 것에도 default value 를 명시할 수 있으며 변수명 또한 변경이 가능하다.
const user = {
name: 'HEROPY',
age: 85,
email: 'ehddud1006@naver.com'
}
function getEmail({ email: newEmail = '이메일이 없습니다.' }) {
return newEmail
}
console.log(getEmail(user))
배열 구조 분해
배열도 마찬가지로 매개변수에서 바로 구조분해가 가능하다.
두번째 배열 요소만 사용할 경우 아래처럼 나타낼 수 도 있다.
나머지 매개변수
argument 가 몇개가 들어올지 알 수 없다면 나머지 매개변수를 사용할 수 있다.
...rest (전개 연산자) 를 사용하여 매개변수를 받으면 배열로 접근할 수 있다.
두번째 예시로 볼때 1 은 a , 2 는 b 나머지 3,4 는 rest 배열에 포함된 것을 확인할 수 있다.
실은 자바스크립트에서는 몇개의 인수가 들어오는지에 대한 정보를 얻을 수 있는 변수가 존재한다.
arguments 는 유사배열이기 때문에 배열로 바꾸어서 배열메소드를 사용해주어야한다.
화살표 함수
화살표 함수의 내부 코드가 리턴문 한줄일 경우에는 return 을 생략할 수 있는데 다음처럼 객체를 반환할 때는 ( ) 괄호로 감싸주어야한다.
즉시실행함수 IIFE
별도의 함수 이름없이 바로 실행되기 원할 때 사용.
오.. 아래코드에서는 오류가 생기는데 이유가 뭘까?
double 이라는 함수를 호출 할때 괄호와 IIFE 의 괄호가 바로 나와 명령이 끝났다고 판단을 하지 못한다.
즉 아래와 같이 판단한다.
그래서 아래와 같이 ; 를 앞에 붙여주어 코드가 끝난 것을 명시해준다.
즉시 실행 함수의 매개변수
콜백 함수
함수가 실행될 때 인수로 들어가는 또 하나의 함수
const sum = (a, b, c) => {
setTimeout(() => {
c(a + b);
}, 1000);
};
sum(1, 2, value => {
console.log(value);
});
콜백함수를 사용하여 이미지가 로드 될때 요소에 img 태그를 삽입할 수 있다.
See the Pen Untitled by ehddud1006 (@ehddud1006-the-looper) on CodePen.
위 코드의 load 이벤트는 이미지의 자원이 불러와졌을 때 실행된다.
페이지 로드 관련 이벤트
DOMCotentLoaded
DOM 구성이 완료되었을 때 document 객체에서 실행된다.
만약 HTML 문서를 처리하는 도중에 <script> 태그를 만나게 되면 DOM 트리 구성을 멈추고 해당 스크립트의 실행이 끝난 후에 DOM 트리가 완성 된다. 따라서 DOMContentLoaded 역시 <script> 태그가 처리된 후 발생한다.
load
페이지를 비롯한 이미지 등의 자원이 모두 불러와졌을 때 window 에서 실행된다.
beforeunload
사용자가 페이지를 떠나려고 할때 window 객체에서 발생합니다. 이 이벤트를 사용하여 사용자에게 브라우저를 떠나기전에 save 하라는 안내를 할 수 있습니다.
unload
사용자가 최종적으로 페이지를 떠날 때 window 객체에서 발생합니다.
재귀
this
일반 함수 this → 호출 위치에서 정의
화살표 함수 this → 자신이 선언된 함수(렉시컬) 범위에서 정의
위 코드에서는 생성자 함수가 객체를 명시적으로 리턴하고 있다.
또한 u.getFullName 메소드를 호출하고 있기 때문에 this 는 u라는 인스턴스를 가르킨다.
호출의 결과값은 다음과 같다.
만약 화살표 함수로 메소드를 구현할 경우 this는 자신의 선언된 스코프를 가르키게 된다.
따라서 위 메소드를 호출했을 때 결과값은 다음과 같다
일반함수로 구현한 메소드의 경우 다음과 같이 축약을 할 수 있다.
function User() {
...
return {
...
getFullName: function(){
return `${this.firstName} ${this.lastName}`
}
}
}
// 축약
function User() {
...
return {
...
getFullName(){
return `${this.firstName} ${this.lastName}`
}
}
}
콜백 함수에서 this
setTimeout 의 콜백함수에서 this.title을 참조하면 undefined 값을 얻게 된다. 그 이유는 this 가 콜백함수를 가르키고 있기 때문이다.
만약 원래대로 TIMER! 라는 값을 얻기 위해서는 bind 를 사용하거나 timer 내부의 this 를 콜백함수로 위임 해줘야한다.
만약 화살표 함수를 사용한다면 어떠한 값을 얻게 될까?
화살표 함수의 this는 자신이 선언된 스코프를 가르킨다고 정리했다. 따라서 setTimeout은 timeout 이라는 일반함수에서 선언되었고, 화살표 함수의 this 는 timeout 함수의 this 와 동일하게 되는 것이다.
프로토타입
프로토타입을 사용하면 인스턴스에서 사용할 수 있는 메소드를 등록 할 수 있다.
const fruits = ['Apple','Banana','Cherry']
//배열에 heropy 라는 함수 등록
Array.prototype.heropy = function(){
console.log(this)
}
//호출
fruits.heropy()
다음과 같은 두개의 객체가 있다. 만약 neo 라는 객체에서도 heropy 객체의 getFullName 함수를 사용하고 싶다면 어떠한 방법을 사용할 수 있을까?
call을 사용할 수 있다.
이러한 방법을 사용하게 된 이유에는 getFullName 이라는 동일한 함수를 neo와 같은 객체에 반복적으로 만들고 싶지 않기 때문이다. 하지만 매번 call 을 사용해야하므로 그리 매력적이지 않은 방법이다.
function User(first, last) {
this.firstName = first
this.lastName = last
this.getHi = function() {
console.log('HI')
}
}
//일반함수를 할당 (화살표함수 X)
User.prototype.getFullName = function() {
return `${this.firstName} ${this.lastName}`
}
const heropy = new User('Heropy', 'Park') //생성자 함수
const neo = new User('Neo', 'Anderson')
console.log(heropy) // firstName : Heropy , lastName : Park 출력
console.log(neo) //firstName: Neo, lastName : Anderson 출력
//getFullName 메소드 호출
console.log(heropy.getFullName()) //Heropy Park 출력
console.log(neo.getFullName()) //Neo Anderson 출력
프로토타입으로 메소드 만드는 거랑 생성자 함수안에 넣는거랑 차이?
프로토타입 메소드 만들때 화살표 함수로 만들며 this 가 window를 가르킴킴
class
클래스를 사용하면 프로토타입을 통해 메서드를 선언하는 것 보다 편하게 인스턴스를 생성할 수 있다.
위 코드에서 눈 여겨 볼 것은 getFullName 이라는 메소드를 생성자 함수를 사용한 코드에서는 프로토타입을 사용하여 생성하였다면, class 를 사용한 코드는 클래스 내부에 명시되어있다.
class 를 사용해 생성된 인스턴스를 콘솔에 찍어본 결과 getFullName 메서드가 프로토타입에 존재한다.
Getter 와 Setter
getter 와 setter 는 접근자 프로퍼티이다. 따라서 데이터를 읽거나 쓸때 사용한다.
getter 는 프로퍼티의 값을 가져올 때, setter 는 프로퍼티 값을 할당할 때 사용한다.
class User {
constructor(first, last) {
this.firstName = first;
this.lastName = last;
}
get fullName() {
return `${this.firstName} ${this.lastName}`;
}
set fullName(value) {
[this.firstName, this.lastName] = value.split(' ');
}
}
const heropy = new User('Heropy', 'Park');
// 접근자 프로퍼티 fullName에 값을 저장하면 setter 함수가 호출된다.
// fullName의 value 에 'Neo Anderson'이 할당된다.
heropy.fullName = 'Neo Anderson';
// 접근자 프로퍼티 fullName에 접근하면 getter 함수가 호출된다.
console.log(heropy.fullName);
정적 메서드
정적 메서드는 인스턴스를 생성하지 않아도 호출할 수 있는 메서드 이다. static 키워드를 사용하여 만들 수 있다.
또한 인스턴스에서는 호출할 수 없다는 특징이 있다.
상속과 instanceof
- 자바스크립트에서도 상속을 통해 클래스 확장이 가능하다. 이를 가능하게 하는 예약어는 extends 이다.
- 상속을 통해 확장된 클래스는 서브 클래스, 서브 클래스에게 상속한 클래스는 수퍼 클래스라고 한다.
- 서브 클래스는 수퍼 클래스의 프로퍼티와 메서드를 사용할 수 있으며, 오버라이딩을 통해 메서드를 덮어쓸 수 있다.
- instanceof 는 인스턴스가 클래스로 부터 나온 인스턴스가 맞는지 불리언 값을 리턴한다. 이때 수퍼 클래스도 true 를 리턴한다.
- constructor 를 사용하면 인스턴스가 어떤 class 를 사용하여 만들어졌는지 알 수 있다.
class Vehicle {
constructor(acceleration = 1) {
this.speed = 0;
this.acceleration = acceleration;
}
accelerate() {
this.speed += this.acceleration;
}
decelerate() {
if (this.speed <= 0) {
console.log("정지");
return;
}
this.speed -= this.acceleration;
}
}
class Bicycle extends Vehicle {
constructor(price = 100, acceleration) {
super(acceleration);
this.price = price;
this.wheel = 2;
}
}
const bicycle = new Bicycle(200, 2);
class Car extends Bicycle {
constructor(license, price, acceleration) {
super(price, acceleration);
this.license = license;
this.wheel = 4;
}
accelerate() { // 오버라이딩
if (!this.license) {
console.error("무면허");
return;
}
this.speed += this.acceleration;
}
}
const car = new Car(true, 1000, 4);
class Boat extends Vehicle {
constructor(price, acceleration) {
super(acceleration);
this.price = price;
this.motor = 1;
}
}
const boat = new Boat(2000, 4)
console.log(bicycle instanceof Bicycle); // true
console.log(bicycle instanceof Vehicle); // true
console.log(car instanceof Car); // true
console.log(car instanceof Bicycle); // true
console.log(car instanceof Vehicle); // true
console.log(boat instanceof Vehicle); // true
console.log(boat instanceof Bicycle); // false
console.log(car.constructor === Car); // true
console.log(car.constructor === Bicycle); // false
'카카오 테크 캠퍼스 > HTML CSS JS' 카테고리의 다른 글
[카테캠 7주차] JS 기초 DOM (0) | 2023.05.28 |
---|---|
[카테캠 7주차] JS 기초 비동기 (0) | 2023.05.28 |
[카테캠 5주차] 자바스크립트 기초 (0) | 2023.05.14 |
[카테캠 4주차] 오버워치 캐릭터 선택 예제 (4) | 2023.05.07 |
[카테캠 4주차] CSS 속성 (0) | 2023.05.06 |