[JavaScript] 자바스크립트의 객체에 대하여

지인·2024년 2월 6일
3

[프론트엔드]

목록 보기
3/5
post-thumbnail

객체란?

자바스크립트는 객체(object) 기반의 프로그래밍 언어다.
심지어 자바스크립트를 구성하는 거의 모든 것이 객체다!


그렇다면 객체란 무엇인가? 😵‍💫


객체 타입은 다양한 타입의 값을 하나의 단위로 구성한 복합적인 자료구조다.
객체프로퍼티(property)메서드(method)의 집합이다.

프로퍼티

객체의 프로퍼티는 변수와 같은 개념이다.
자바스크립트에서 사용할 수 있는 모든 값은 프로퍼티 값이 될 수 있다!

메서드

자바스크립트의 함수는 일급 객체이므로 값으로 취급할 수 있다.
따라서 함수도 프로퍼티 값으로 사용할 수 있는데, 이때 일반 함수와 구분하기 위해 메서드라 부르다.

객체 생성

var person = {
  name: 'Lee', // 프로퍼티
  sayHello: function () { // 메서드
    console.log(`Hello! My name is ${this.name}.`);
  }
};

위 코드는 중괄호({...}) 내에 0개 이상의 프로퍼티를 정의함으로써 객체를 생성한다.
자바스크립트 엔진은 변수에 할당되는 시점에 객체 리터럴을 해석해 객체를 생성한다.

var empty = {};
console.log(typeof empty); // object

중괄호 내에 프로퍼티를 정의하지 않음으로써 빈 객체를 생성할 수도 있다.


이때 객체 리터럴의 중괄호는 코드 블록을 의미하지 않는다.
코드 블록의 닫는 중괄호 뒤에는 세미콜론을 붙이지 않는데, 객체 리터럴은 값으로 평가되는 표현식이므로 닫는 중괄호 뒤에 세미콜론을 붙인다.

리터럴이란?
사람이 이해할 수 있는 문자 또는 약속된 기호를 사용하여 값을 생성하는 표기법이다.




프로퍼티

객체의 프로퍼티에 대해 더욱 자세히 알아보자.

var person = {
  name: 'Lee', // 프로퍼티 키는 name, 프로퍼티 값은 'Lee'
  age: 20 // 프로퍼티 키는 age, 프로퍼티 값은 30
};

객체는 프로퍼티의 집합이며, 프로퍼티는 키와 값으로 구성된다.
프로퍼티를 나열할 때는 쉼표로 구분하며, 일반적으로 마지막 프로퍼티 뒤에는 쉼표를 사용하지 않으나 사용해도 좋다!


프로퍼티의 키와 값으로 사용할 수 있는 값은 아래와 같다.

  • 프로퍼티 키 : 빈 문자열을 포함하는 모든 문자열 또는 심벌 값
  • 프로퍼티 값 : 자바스크립트에서 사용할 수 있는 모든 값

프로퍼티 접근

프로퍼티에 접근하는 방법은 두 가지가 있다.

  • 마침표 표기법 : 마침표 프로퍼티 접근 연산자(.) 사용
  • 대괄호 표기법 : 대괄호 프로퍼티 접근 연산자([...]) 사용
var person = {
  name: 'Lee',
  age: 20
};

// 마침표 표기법에 의한 프로퍼티 접근
console.log(person.name); // Lee
// 대괄호 표기법에 의한 프로퍼티 접근
console.log(person['name']); // Lee

이때, 대괄호 표기법을 사용하는 경우 대괄호 프로퍼티 접근 연산자 내부에 지정하는 프로퍼티 키는 반드시 따옴표로 감싼 문자열이어야 한다.

var person = {
  name: 'Lee',
};

console.log(person.age); // undefined

객체에 존재하지 않는 프로퍼티에 접근하면 undefined를 반환한다.
이때 ReferenceError가 발생하지 않으므로 주의할 것!

프로퍼티 값 갱신

var person = {
  name: 'Lee',
};

person.name = 'Kim';

console.log(person.name); // Kim

이미 존재하는 프로퍼티에 값을 할당함으로써 프로퍼티 값을 갱신할 수 있다.

프로퍼티 동적 생성

var person = {
  name: 'Lee',
};

person.age = 20;

console.log(person); // {name: 'Lee', age: 20}

존재하지 않는 프로퍼티에 값을 할당하면 프로퍼티가 동적으로 생성되어 추가되고 프로퍼티 값이 할당된다.

프로퍼티 삭제

var person = {
  name: 'Lee',
  age: 20;
};

delete person.age;

console.log(person); // {name: 'Lee'}

delete 연산자는 객체의 프로퍼티를 삭제한다.
만약 존재하지 않는 프로퍼티를 삭제할 경우 아무런 에러 없이 무시된다.



생성자 함수

function Person(name, age) { // 함수 첫 글자는 대문자로 시작한다.
  this.name = name;
  this.age = age;
};

const person1 = new Person("지인", 24);
const person2 = new Person("길동", 30);

생성자 함수(constructor function)는 일반 함수와 기능적인 차이가 없다.

그러나 일반 함수와 달리 생성자 함수는 new 연산자와 함께 자바스크립트에서 객체를 생성하기 위해 사용된다.

function Person(name, age) {
  this.name = name;
  this.age = age;
  this.getName = function() { // 메서드
    return "제 이름은 " + this.name + "입니다.";
  }
};

const person1 = new Person("지인", 24);
const person2 = new Person("길동", 30);

console.log(person1.getName()); // 제 이름은 지인입니다.

생성자 함수 내에 메서드를 정의하여 사용하는 것도 물론 가능하다.




프로토타입

C++, 자바와 같은 클래스 기반의 객체지향 프로그래밍 언어와 달리
자바스크립트는 프로토타입(prototype)을 기반으로 객체지향 프로그래밍을 할 수 있다.

클래스 기반의 객체지향 프로그래밍들에서는 클래스를 먼저 정의한 다음 객체를 생성하는 반면 자바스크립트는 클래스 없이도 프로토타입을 이용하여 객체 생성이 가능하다.

모든 자바스크립트 객체들은 프로토타입 객체로부터 프로퍼티와 메서드를 상속받는다.

function Person(name, age) {
  this.name = name;
  this.age = age;
};

Person.id = "20massalia"; // 프로퍼티 추가

const person1 = new Person("지인", 24);

console.log(person1.id); // undefined

이미 생성된 생성자 함수에 위와 같이 프로퍼티를 추가하려 하면 추가가 불가능하다.
출력할 경우 undefined가 나오는 것을 확인할 수 있다.


function Person(name, age) {
  this.name = name;
  this.age = age;
};

Person.prototype.id = "20massalia"; // 프로퍼티 추가
Person.prototype.getId = function() {
  return "아이디는 " + this.id + "입니다.";
};

const person1 = new Person("지인", 24);

console.log(person1.id); // 20massalia
console.log(person1.getId()); // 아이디는 20massalia입니다.

이때 프로토타입을 사용하여 기존의 생성자 함수에 프로퍼티와 메서드를 추가하는 것이 가능하다.

이처럼 프로토타입을 사용하면 생성자 함수에 의해 생성된 모든 객체들에 새로운 프로퍼티와 메서드를 추가할 수 있다!




클래스

클래스(class)는 객체를 생성하기 위한 툴, 즉 템플릿(template)이다.
이 클래스를 이용하면 C++이나 자바와 같은 방식으로 객체지향 프로그래밍이 가능하다.

자바스크립트에서 클래스는 프로토타입을 이용하여 만들어졌지만,
프로토타입을 사용한 객체지향 프로그래밍과는 문법이 다르고 사용 방법 또한 다르다.
자바스크립트에서 클래스는 함수와 유사한 구조를 가지는 '특별한 함수'라 볼 수 있다.

클래스 기본 구조

class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
  getName() {
  	return "제 이름은 " + this.name + "입니다.";
  }
}

const person1 = new Person("지인", 24); // 인스턴스 생성

console.log(person1.getName()); // 제 이름은 지인입니다.

class 키워드를 사용하여 정의하며, 클래스 또한 값으로 사용할 수 있는 일급 객체이다.
좀 더 자세히 말하자면, 클래스도 함수다!

클래스 몸체에는 constructor(생성자), 프로토타입 메서드, 정적 메서드 세 가지를 정의할 수 있다.

constructor

constructor는 인스턴스를 생성하고 초기화하기 위한 특수한 메서드다.

이름을 변경할 수 없으며, constructor는 메서드로 해석되는 것이 아니라 클래스가 평가되어 생성한 함수 객체 코드의 일부가 된다.

constructor는 생성자 함수와 유사하지만 몇 가지 차이가 존재한다.

  • constructor는 클래스 내에 최대 한 개만 존재할 수 있다. 2개 이상 포함할 경우 문법 에러가 발생한다.

  • constructor는 생략할 수 있다.

  • constructor를 생략하면 클래스에 빈 constructor가 암묵적으로 정의된다.

  • constructor를 생략한 클래스는 빈 constructor에 빈 객체를 생성한다.

  • constructor 내에서는 인스턴스의 생성과 동시에 인스턴스 프로퍼티 추가를 통해 인스턴스의 초기화를 실행한다. 따라서 인스턴스를 초기화하려면 constructor를 생략해서는 안된다.

  • constructor는 별도의 반환문을 갖지 않아야 한다.

프로토타입 메서드

생성자 함수를 사용하여 인스턴스를 생성하는 경우,
프로토타입 메서드를 생성하기 위해서는 다음과 같이 명시적으로 프로토타입에 메서드를 추가해야 한다.

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

// 프로토타입 메서드
Person.prototype.sayHi = function () {
  console.log(`Hi! My name is ${this.name}`);
};

const me = new Person('Lee');
me.sayHi(); // Hi! My name is Lee

정적 메서드

정적(static) 메서드는 인스턴스를 생성하지 않아도 호출할 수 있는 메서드를 말한다.

생성자 함수의 경우 정적 메서드를 생성하기 위해서는 다음과 같이 명시적으로 생성자 함수에 메서드를 추가해야 한다.

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

// 정적 메서드
Person.sayHi = function () {
  console.log('Hi!');
};

Person.sayHi(); // Hi!

클래스의 경우 static 키워드를 붙이면 정적 메서드(클래스 메서드)가 된다.

class Person {
  constructor(name) {
    this.name = name;
  }
  
  // 정적 메서드
  static sayHi() {
	console.log('Hi!');
  }
}

클래스 상속

클래스 상속은 다른 클래스에 있는 프로퍼티와 메서드를 상속받아 사용하는 것을 말한다.

상속을 함으로써 하나의 클래스에서 부모 클래스가 가지고 있는 자원과 기능을 확장하여 사용할 수 있다.

이때 extends 키워드를 사용한다.

class Person {
  constructor(name) {
    this.name = name;
  }
  
  sayHi() {
	console.log('Hi!');
  }
}

class Student extends Person {
  constructor(name, major) {
    super(name);
    this.major = major;
  }
  
  intro() {
    console.log(this.sayHi());
	console.log(`${this.major} 학생입니다.`);
  }
}

const stud1 = new Student("지인", "컴공");
stud1.intro();



긴 글 읽어주셔서 감사합니다!

더 좋은 글로 돌아올게요. 🙇🏻‍♀️

profile
이게.., 김민경이,.., 그려준 나.,.,.?!

0개의 댓글