멋쟁이사자처럼FE 2기/TIL

스코프&클래스(Class)

(범) 2022. 5. 18. 15:55

스코프란?


변수값의 생존범위

 

스코프 체인이란?


var func1 = function () {
//   var a = 1;
  var b = 2;
  console.log(a + b);
};

var a = 20;

func1();​

이때 a+b의 값은 22가 된다.

func1 안에서 a의 값을 찾지 못하자 스코프를 더 넓혀서 바깥에 있는 a의 값을 적용하였다.

이러한 현상을 스코프체인이라고 한다.​

 

스코프 체인: 안에 없으면 밖에 찾기, 상위 요소로 찾아 찾아 올라가기

 

전역스코프

어디서든 접근 가능.

협업 시 얽힐 수 있다는 단점.

 

함수스코프

함수 내부의 공간.

 

function test() {
  val1 = "hello";
  var val1 = "world";
}
test();
console.log(val1);
console.log(val2);​

var를 없앤다면 val1은 전역함수로 선언된다.​

 

 

class


ES6 부터 class라는 키워드를 사용할 수 있게 되었습니다. 클래스란 객체를 생산하는 생산 도면 혹은 청사진이란 표현을 자주 사용합니다. 즉 엄청나게 많이 사용하는 비유, 클래스는 붕어빵의 틀이다 라는 표현이 등장합니다.

1.1 class의 사용법


class 키워드 + 이름 + 대괄호로 이루어져 있습니다.

클래스의 결과물은 인스턴스를 생성하는것입니다. 생성자를 이용한 타입 생성과 그 결과가 정확하게 일치합니다.

// function Robot(name) {
//     this.name = name;
// }

// Robot.prototype.sayYourName = function () {
//     console.log(`삐리비리. 제 이름은 ${this.name}입니다. 주인님.`);
// }

class Robot {
    // 클래스의 생성자 함수입니다. 하나의 클래스는 하나의 생성자만 정의할 수 있습니다. 
		// 그리고 생성자 함수는 new 키워드가 호출될때 자동으로 실행됩니다.
    constructor(name) {
        this.name = name;
    }

    // 메소드를 정의합니다. 메소드는 클래스가 생성한 인스턴스를 통해 사용할 수 있습니다.
    sayYourName() {
        console.log(`삐리비리. 제 이름은 ${this.name}입니다. 주인님.`);
    }
}

자바스크립트만의 사용자 정의 타입 생성(객체 생성) 방법을 다른 언어의 클래스 문법처럼 바꿔준 것이 바로 자바스크립트 클래스(class)입니다!

<aside> 💡 이처럼 내부적인 동작은 동일하지만 더 보기 좋고 편리하게 개선된 문법을 슈가신텍스 (Syntactic sugar) 라고 부릅니다.

</aside>

  • 실습 : 우리가 위에서 만들어본 여러분 자신의 생성자 함수를 class 문법으로 변경해봅시다.

1.2 class 상속받기


클래스의 상속은 extends 키워드를 사용합니다.

상속을 받는 클래스는 ‘파생 클래스’(derived classes)라고 부릅니다. 이때 부모 클래스의 프로퍼티를 상속받기 위해 super 함수를 사용합니다. 이때 super는 부모 생성자를 참조합니다.

super 사용시 주의할 점

  • 만약 파생 클래스에 생성자 함수를 사용하고 싶다면 반드시 super 함수를 사용해야합니다.
  • 파생클래스에 생성자 함수가 없다면 super 함수가 자동으로 호출되어 부모 클래스의 프로퍼티를 상속 받게 합니다.
  • 생성자 함수에서 this 값을 사용할 경우 super 함수는 반드시 this 보다 먼저 실행되어야 합니다.
  • 파생 클래스가 아닌 클래스에서 사용하려고 해도 에러가 발생합니다.
class BabyRobot extends Robot {
    constructor(name) {
        super(name);
        this.ownName = '아이크';
    }

    sayBabyName() {
				// 또한 상속을 받게되면 부모 클래스의 메소드를 사용할 수 있게 됩니다. 때문에 this로 접근 할 수 있습니다.
        this.sayYourName();
        console.log('Suceeding you, Father!');
    }
}
  • 실습 : 소시지를 만드는 클래스를 정의해봅시다.
  1. 생성자 함수는 두 가지 매개변수를 전달 받을 수 있으며 전달되는 매개변수에 따라 소시지의 맛이 결정됩니다.
  2. 소시지 객체는 taste 라는 메서드가 존재합니다. 생성자함수에서 전달받은 재료에 따라 맛을 나타내는 콘솔로그를 출력하는 역할을 합니다. (예시 : ‘소고기’ 와 ‘파’ 를 매개변수로 전달하였을 경우, ‘소고기와 파 맛이 난다!’ 는 콘솔 메세지를 출력합니다.)
  3. 소시지 클래스를 상속받는 FiresSausage 파생클래스를 생성해봅니다. 파생클래스의 taste 메서드를 실행하면 콘솔 메세지에 불맛이 나기 시작합니다.

1.3 비공개(private) 프로퍼티


비공개 프로퍼티는 객체 안의 중요한 정보를 안전하게 보호하여 프로그램이 뜻하지 않게 변경되는 것을 막는 역할을 합니다.

만약 여러분이 class를 통해 인스턴스를 만들었을 때 보통 우리는 아무런 제약없이 인스턴스의 프로퍼티에 접근하는 것이 가능합니다.

class Robot {
          
    constructor(name) {
        this.name = name;
    }

    sayYourName() {
        console.log(`삐리비리. 제 이름은 ${this.name}입니다. 주인님.`);
    }
}

const bot = new Robot('smith');

bot.name // smith

또한 프로퍼티의 값을 수정하는 것도 가능합니다.

bot.name = 'jay';
bot.name // jay

하지만 중요한 데이터를 조심스럽게 다뤄야 할 경우, 그래서 이런 데이터를 외부에서 함부로 수정할 수 없게 만들고 싶을 때 우리는 비공개 프로퍼티로 데이터를 변경할 수 있습니다.

class Robot {
    #password

    constructor(name, pw) {
        this.name = name;
        this.#password = pw;
    }

    sayYourName() {
        console.log(`삐리비리. 제 이름은 ${this.name}입니다. 주인님.`);
    }

    getPassword() {
        return this.#password
    }

    setPassword(pw) {
        this.#password = pw;
    }
}

키워드를 이용하면 프로퍼티를 비공개로 전환할 수 있습니다.

이제 #password 의 값에 접근하고 수정하려면 반드시 해당하는 기능을 하는 메서드를 사용해야합니다.

이때 값을 불러오는 메서드를 getter 메서드, 값을 수정하는 메서드를 setter 메서드로 부릅니다.

get, set 키워드를 이용해 아래처럼 코드를 좀 더 단순화 할 수 있습니다.

class Robot {
    #password

    constructor(name, pw) {
        this.name = name;
        this.#password = pw;
    }

    sayYourName() {
        console.log(`삐리비리. 제 이름은 ${this.name}입니다. 주인님.`);
    }

    get password() {
        return this.#password
    }

    set password(pw) {
        this.#password = pw;
    }
}

const bot = new Robot('재현', 1234);

이렇게 get과 set 키워드를 사용하면 마치 객체의 프로퍼티에 접근하듯 값을 다룰수 있게 됩니다.

 

💡 get 과 set을 사용할 때 주의할 점! get과 set을 사용하면 마지 객체의 프로퍼티를 수정하는것 같은 간편함을 느낄 수 있습니다. 하지만 해당 코드를 직접 작성하지 않은 협업자들에게는 오해를 일으킬 소지가 있습니다. get, set 안에 어떤 로직이 들어있는지 파악하지 못하고 단순히 객체의 프로퍼티를 수정한다는 착각을 일으킬 수 있기 때문입니다. 때문에 협업 시에는 주석이나, 가이드 문서를 만들어 충분한 정보를 제공해주는것이 좋습니다.

 

  • 실습 : 우리가 위에서 만들어본 여러분 자신의 class에 비공개 프로퍼티를 추가해봅시다.

실습

TodoList 만들기


class Todo {

            constructor(item, finished) {
                this.item = item;
                this.finished = finished;
            }

            changeState() {
                this.finished = !this.finished
            }
        }

        class TodoManager {
            constructor() {
                this.todoList = [];
            }

            addItem(item, finished = false) {
                // const todo = new Todo(item, finished);
                this.todoList.push(new Todo(item, finished))
            }

            getItems() {
                return this.todoList;
            }

            getLeftTodoCount() {
                return this.todoList.reduce((total, current) => {
                    if (current.finished === false) {
                        return ++total;
                    } else {
                        return total;
                    }
                }, 0
                );
            }
        }


        const todoManager = new TodoManager();

'멋쟁이사자처럼FE 2기 > TIL' 카테고리의 다른 글

Server(Linux, Ubuntu, AWS)  (0) 2022.06.07
웹 최적화(Optimization)  (0) 2022.05.19
객체지향 프로그래밍  (0) 2022.05.18
20일차_Sass(1)  (4) 2022.04.25
SVG로 지도 만들기  (0) 2022.04.21