'변수가 어디까지 쓰일 수 있는지'의 범위를 의미하는, 변수가 선언되고 사용할 수 있는 공간이다.
중괄호({})로 감싸진 것. function 내부, for문, if문도 하나의 block이다.
- block 내부({})에서 변수가 정의되면 변수는 오로지 그 내부에서만 사용할 수 있다.
- 이렇게 block 내부에서 정의된 변수는 지역(local)변수라고 한다.
function getResult() {
let result = 10;
return result;
}
console.log(result);
// 위와 같이 코드를 작성하면 console창에 아래와 같은 에러가 뜬다.
// console.log(result); console.log(result)에서 getResult 내부에 접근 불가
// ^
// ReferenceError: result is not defined
scope 외부(block 바깥)에서는 특정 scope의 변수에 접근할 수 없다.
block 밖인 global scope에서 만든 변수를 전역변수(global variable)이라고 한다. 코드 어디서든 접근가능해서 변수값을 확인할 수 있다.
const color = 'red'; // color 변수는 전역 변수이기 때문에 returnColor 함수의 block에서도 접근 가능
console.log(color);
function returnColor() {
console.log(color);
return color; // 함수 밖에 있는 color 변수 return
}
console.log(returnColor());
전역변수는 프로그램 어디에서나 사용될 수 있기때문에 남용되면 프로그램을 오염시킬 수 있다.
전역변수가 계속 살아있어 변수값이 계속 변한다면 해당 변수 트래킹이 어렵다.
let stars = 'North Star';
const callMyNightSky = () => {
stars = 'Sirius'; // 깜박하고 block 내에서 stars에 새로운 값 할당하여 전역변수 stars 값이 함께 변경됨 : scope의 오염
}
- 클래스는 객체지향 프로그래밍의 핵심이다.
cf. 객체지향 프로그래밍이란 프로그램을 객체들로 구성하고, 객체들 간에 서로 상호작용하도록 작성하는 방법. 여기서 객체는 앞에서 나왔던 객체({}형태)가 아닌 말그대로 사물(object)을 의미한다.- 객체는 특정로직을 갖고 있는 행동(method)과 변경 가능한 상태(멤버 변수)를 가지는데, 원하는 구조의 객체 틀을 짜놓고 비슷한 모양의 객체를 공장처럼 찍어낼 수 있다.
- 객체는 매번 만들어서 사용할 수도 있지만, 큰 규모의 객체 또는 비슷한 모양의 객체를 계속해서 만들어내는 것은 비효율적이다.
- 이 때 필요한 것이
class
.class
는 객체를 만드는 설계도라고 할 수 있다.
예를 들어, 자동차 'ray'의 정보를 담은 아래의 객체가 있다고 해보자.
만약 동일한 프로퍼티를 가진 'avante'의 정보가 필요하다면? 'avante'의 객체를 똑같이 생성하는 것은 비효율적일 것이다.
let ray = {
name: "Ray",
price: 2000000,
getName: function () {
return this.name; // 객체 내부에서 해당 객체의 프로퍼티에 접근 시 'this'키워드 사용
},
getPrice: function () {
return this.price;
},
applyDiscount: function (discount) {
return this.price * discount;
},
};
/* 가격 가져오는 방법
const rayPriceByPropertyName = ray.price;
console.log("프로퍼티명으로 접근 => " + rayPriceByPropertyName);
const rayPrice = ray.getPrice();
console.log("함수로 접근 =>" + rayPrice); */
객체의 설계도인 class는 객체와 문법이 비슷하다. 객체와 class의 가장 큰 차이는
constructor
라는 생성자 함수이다.
class로 객체를 생성하는 과정을 '인스턴스화'라고 하며, class를 통해 생성된 객체를 '인스턴스'라고 한다. class는 새로운 인스턴스를 생성할 때마다 constructor()
메서드를 호출한다.
// class로 객체 생성
class Car { // 클래스 이름: Car, 항상 대문자로 시작하고 CamelCase로 작성해야 함.
constructor(name, price) { // Car class의 instance를 생성할때마다 constructor 호출. name, price 인자를 받음.
this.name = name; // class의 실행범위(context)에서 this는 해당 instance를 의미
this.price = price;
this.department = "선릉지점";
this.salesAmount = 0;
}
// class 내에서 name, price와 같이 변경 가능한 상태값이자 class 실행범위 어느 곳에서나 사용할 수 있는 변수를 '멤버변수'라고 부른다. 멤버변수는 'this' 키워드로 접근 가능.
class를 통해 생성된 객체로 인스턴스마다 모두 다른 property 값을 가지고 있다.
- 인스턴스는 class 이름에 new를 붙여 생성
- 클래스 이름 우측의 괄호 내부에 constructor에서 필요한 정보(name, price)를 인자로 넘겨줌
const morning = new Car('Morning', 20000000);
// Car class의 instance를 morning이라는 변수에 저장,
// 다른 instance 생성 시,
const spaceship = new Car('우주선', 25000000); // Car class의 instance를 spaceship이라는 변수에 저장.
console.log(spaceship);
console.log(spaceship.name); // spaceship 인스턴스의 이름에 접근.
console.log(spaceship.price);
Car 클래스의 새로운 인스턴스를 생성하려면 new
키워드가 필요하며, new
키워드는 constructor() 메서드를 호출하고 새로운 instance를 return한다!!
객체가 프로퍼티 값으로 갖고 있는 것을 메서드라고 한다. class의 메서드는 객체의 문법과 동일하지만, property마다 세미콜론(;)으로 구분한다. (객체는 콤마(,)로 구분)
class Car {
constructor(name, price) {
this.name = name;
this.price = price;
this.department = "선릉지점";
}
applyDiscount(discount) {
return this.price * discount;
}
changeDepartment(departmentName) {
return this.department = departmentName;
}
}
const morning = new Car("모닝", 20000000);
console.log(morning);
console.log(morning.name);
console.log(morning.changeDepartment("마곡지점"));
class 생성 연습: MyMath라는 class를 생성해주세요.
constructor에서는 숫자 2개를 인자로 받아 프로퍼티로 저장합니다.
총 4개의 메서드를 구현해주세요.
getNumber: 인자로 받은 두 개의 숫자가 무엇인지 배열로 반환하는 메서드
add: 두 개의 숫자를 더하는 메서드
substract: 두 개의 숫자를 빼는 메서드
multiply: 두 개의 숫자를 곱하는 메서드class MyMath { constructor(a, b) { this.num1 = a; this.num2 = b; } getNumber() { const array = [this.num1, this.num2]; return array; } add() { return this.num1 + this.num2; } substract() { return this.num1 - this.num2; } multiply() { return this.num1 * this.num2; } }