index
② 객체 리터럴에 의한 객체 생성
②-1 객체 생성 방식
②-1-1 클래스 기반 객체지향 언어 (Java)
②-1-2 프로토타입 기반 객체지향 언어 (Javascript)
②-2 클래스 정의
②-3 상속 방식
②-4 런타임 동적 확장
②-5 코드 구조
③ 프로퍼티 접근
1. 객체(object)란 무엇일까?
자바스크립트는 객체(object)기반의 프로그래밍 언어이며, 자바스크립트를 구성하는 거의 “모든 것”이 객체다. 원시 값을 제외한 나머지 값(함수, 배열, 정규표현식 등)은 모두 객체다.
객체는 0개 이상의 프로퍼티로 구성된 지합이며, 프로퍼티는 키와 값으로 구성된다. 프로퍼티의 값이 함수일 경우, 일반 함수와 구분하기 위해 메서드(method)라 부른다.
프로퍼티: 객체의 상태를 나타내는 값(data)
메서드: 프로퍼티(상태 데이터)를 참조하고 조작할 수 있는 동작(behavior)
2. 객체 리터럴에 의한 객체 생성
🧐 Q. 클래스 기반의 객체지향언어와 프로토타입 기반의 객체지향 언어는 어떠한 차이가 있을까?

object oriented language difference explanation
Jay Tak.
// <클래스 기반 객체 생성 (Java)>
// 부모 클래스 정의
class Animal {
String name;
// 생성자
Animal(String name) {
this.name = name;
}
// 메서드 (동물의 기본 발화 메서드)
void speak() {
System.out.println(name + " speaks");
}
}
// 자식 클래스 정의 (Animal 클래스를 상속)
class Dog extends Animal {
// 생성자
Dog(String name) {
super(name); // 부모 클래스의 생성자를 호출하여 name 속성을 초기화
}
@Override
void speak() { // 부모 클래스의 speak 메서드를 오버라이드 (재정의)
System.out.println(name + " barks");
}
}
// 실행을 위한 Main 클래스
public class Main {
public static void main(String[] args) {
// Dog 객체 생성 (name = "Buddy")
Dog dog = new Dog("Buddy");
// 오버라이딩된 speak 메서드 호출
dog.speak(); // 출력: Buddy barks
}
}
dog.newMethod(); // 불가능: Java에서는 런타임 중에 메서드나 속성을 동적으로 추가할 수 없음
// <프로토타입 기반 객체 생성 (JavaScript)>
const animal = {
name: "Animal",
speak: function () {
console.log(this.name + " speaks");
},
};
const dog = Object.create(animal);
dog.name = "Buddy";
dog.speak(); // Buddy speaks
const cat = Object.create(animal); // ③ 프로토타입 체인에 의한 상속
cat.name = "Whiskers";
cat.speak(); // Whiskers speaks
dog.newMethod = function () {
console.log("New method");
};
dog.newMethod(); // 가능: 런타임 중에 메서드 추가 및 호출 가능
2.1 객체 생성 방식
클래스 기반 객체지향 언어 (Java)
Java와 같은 클래스 기반 객체지향 언어에서는 클래스를 정의한 후에 그 클래스를 기반으로 인스턴트화하여 객체를 생성한다. 클래스 필요
Dog dog = new Dog("Buddy");
// ① Dog 클래스의 생성자를 호출하여 객체를 생성하며, 생성된 객체는 해당 클래스의 인스턴스이다.
// ② 생성자가 실행되며, 객체의 초기 속성값(name)이 설정된다.
프로토타입 기반 객체지향 언어 (Javascript)
JavaScript와 같은 프로토타입 기반 객체지향 언어에서는 클래스가 필요 없이 기존 객체를 프로토타입으로 복제하여 객체를 생성합니다. 클래스 불필요
const animal = { name: "Animal" };
const dog = Object.create(animal);
dog.name = "Buddy";
// ① Object.create(animal)을 통해 프로토타입 상속을 기반으로 새로운 객체가 생성됩니다.
// ② dog 객체는 animal 객체를 프로토타입으로 상속받으며, 런타임에서 dog.name을 동적으로 변경가능
// ③ 클래스의 개념 없이 기존 객체를 활용해 객체가 생성됩니다.
2.2 클래스 정의
클래스 기반 객체지향 언어 (Java)
Java에서는 클래스를 명시적으로 정의하고, 클래스는 객체의 속성과 메서드를 포함하는 청사진(blueprint) 역할을 한다. 객체 생성을 위해 클래스 명시적 정의
class Dog extends Animal {
Dog(String name) { super(name); }
void speak() { System.out.println(name + " barks"); }
}
// ① Dog 클래스는 Animal 클래스를 상속하며, 객체가 생성되기 전에 클래스를 먼저 정의해야 한다.
프로토타입 기반 객체지향 언어 (Javascript)
JavaScript에서는 클래스가 필요 없이 객체 자체가 프로토타입 역할을 합니다. 모든 객체는 다른 객체의 프로토타입으로 상속받을 수 있다. 객체 생성을 위해 클래스 불필요, 동적으로 속성이나 메서드도 추가가능
const animal = {
name: "Animal",
speak: function () {
console.log(this.name + " speaks");
},
};
const dog = Object.create(animal);
dog.speak = function () {
console.log(this.name + " barks");
};
// ① 클래스 없이 객체를 직접 생성하고, 메서드를 추가할 수 있다. 여기서 dog는 animal을 프로토타입으로 상속받아 객체를 정의하고, 동적으로 메서드를 추가할 수 있다.
2.3 상속 방식
클래스 기반 객체지향 언어 (Java)
클래스 기반 언어에서는 클래스 간 상속이 이루어집니다. 자식 클래스는 부모 클래스에서 정의한 속성과 메서드를 상속받습니다. 클래스간 상속 + 상속 구조 고정적
class Dog extends Animal {
Dog(String name) { super(name); }
@Override
void speak() { System.out.println(name + " barks"); }
}
// ① Dog 클래스는 Animal 클래스를 상속받아 speak() 메서드를 오버라이딩한다. 클래스 상속구조는 컴파일 타임에 결정되며 변경할 수 없다.
프로토타입 기반 객체지향 언어 (Javascript)
프로토타입 기반 언어에서는 객체 간 프로토타입 상속이 이루어집니다. 객체는 다른 객체를 프로토타입으로 지정하여 상속받는다. 객체 간 상속 + 상속 관계는 런타임 중 동적 변경 가능
const animal = { name: "Animal" };
const dog = Object.create(animal); // 프로토타입 상속
dog.speak = function () {
console.log(this.name + " barks");
};
// dod 객체는 animal 객체를 프로토타입으로 상속받으며, 동적으로 속성과 메서드를 추가하거나 수정할 수 있다.
2.4 런타임 동적 확장
클래스 기반 객체지향 언어 (Java)
클래스 기반 언어에서는 런타임 중에 객체의 구조(속성 및 메서드)를 동적으로 변경할 수 없습니다. 모든 속성과 메서드는 컴파일 타임에 결정된다. 객체 구조 고정적 </span>
dog.newMethod(); // 불가능: Java에서는 런타임 중에 메서드나 속성을 동적으로 추가할 수 없음
프로토타입 기반 객체지향 언어 (Javascript)
JavaScript에서는 런타임 중에 객체의 구조를 동적으로 변경할 수 있습니다. 새로운 속성이나 메서드를 언제든지 추가하거나 수정할 수 있다. 객체 구조 유연적
dog.newMethod = function () {
console.log("New method");
};
dog.newMethod(); // 가능: 런타임 중에 메서드 추가 및 호출 가능
2.5 코드 구조
클래스 기반 객체지향 언어 (Java)
클래스 기반 언어에서는 클래스와 객체의 구조가 명확히 구분됩니다. 객체는 클래스의 인스턴스이며, 클래스는 속성과 메서드를 정의한다. 클래스와 객체 명확 구분
class Animal {
String name;
void speak() { System.out.println(name + " speaks"); }
}
프로토타입 기반 객체지향 언어 (Javascript)
프로토타입 기반 언어에서는 모든 것이 객체입니다. 클래스가 없으며, 모든 객체는 다른 객체를 상속받아 구조를 형성한다. 모든 객체는 다른객체를 프로토타입으로 상속 가능
const animal = { name: "Animal" };
const dog = Object.create(animal);
3. 프로퍼티 접근
(The part that I often get confused about)
프로퍼티 키가 식별자 네이밍 규칙을 준수하지 않는 이름, 즉 자바스크립트에서 사용가능한 유효한 이름이 아니면반드시 대괄호 표기법을 사용해야 한다.
단, 프로퍼티 키가 숫자로 이뤄진 문자열인 경우 따옴표를 생략할 수 있다그 외의 경우 대괄호 내에 들어가는 프로퍼티 키는 반드시 따옴표로 감싼 문자열이어야 한다
var person = {
'last-name': 'Lee',
1: 10
};
person. 'last-name';
// SyntaxError: Unexpected string
person.last-name;
// 브라우저 환경: NaN
// Node.js : ReferenceError: name is not defined
Node.js 환경에서는 어디에도 name(변수, 함수등의 이름) 선언이 없으므로
RefefenceError:name is not defined라는 에러가 발생한다.
그런데 브라우저 환경에서는 name이라는 전역변수(전역객체 window의 프로퍼티)가 암묵적으로 존재한다.
전역변수 name은 창(window)의 이름을 가리키며, 기본값은 빈문자열이다.
person [last-name];
// ReferenceError: last is not defined
person[ 'last-name'];
// Lee
// 프로퍼티 키가 숫자로 이뤄진 문자열인 경우 따옴표를 생략할 수 있다.
person.1;
// SyntaxError: Unexpected number
person. '1';
// SyntaxError: Unexpected string
person [1];
// 10: person[1] person['1']
person['1'];
// 10