const Meal = function(food) {
this.food = food
}
Meal.prototype.eat = function() {
return 'great!'
}
// old
class Meal {
constructor (food) {
this.food = food
}
eat() {
return 'great!'
}
}
// new
두 문법은 내부적으로 완전히 같은 구조다.
// 클래스
class Person {
// 이전에서 사용하던 생성자 함수는 클래스 안에 `constructor`라는 이름으로 정의합니다.
constructor({name, age}) { //생성자
this.name = name;
this.age = age;
}
// 객체에서 메소드를 정의할 때 사용하던 문법을 그대로 사용하면, 메소드가 자동으로 `Person.prototype`에 저장됩니다.
introduce() {
return `안녕하세요, 제 이름은 ${this.name}입니다.`;
}
}
const person = new Person({name: '외데고르', age: 19});
console.log(person.introduce()); // 안녕하세요, 제 이름은 외데고르입니다.
constructor는 인스턴스를 생성하고 클래스 필드를 초기화하기 위한 특수한 메서드이다.constructor는 클래스 안에 한 개만 존재할 수 있다. 2개 이상 있을 경우 Syntax Error가 발생하니까 주의this.변수 문법으로 자동 생성될수 있다는 점이다.class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} makes a sound.`);
}
}
// Animal을 상속받아 생성자를 그대로 사용하는 모습.
class Dog extends Animal {
speak() {
console.log(`${this.name} barks.`);
}
}
let dog = new Dog('Rex');
dog.speak();// 출력: Rex barks.
class Shape {
area() {
return 0;
}
}
class Circle extends Shape {
constructor(radius) {
super();
this.radius = radius;
}
area() {
return Math.PI * this.radius ** 2;
}
}
// 둘다 Shape 를 상속받았지만 생성자나 내부 함수의 형태는 다르다.
class Rectangle extends Shape {
constructor(width, height) {
super();
this.width = width;
this.height = height;
}
area() {
return this.width * this.height;
}
}
let shapes = [new Circle(5), new Rectangle(4, 5)];
shapes.forEach(shape => console.log(shape.area()));
class Person {
constructor(name) {
this.name = name;
}
sayHello() {
console.log(`Hello, I'm ${this.name}`);
}
}
let person = new Person('John');
person.sayHello();// 출력: Hello, I'm John
function Person(name) {
this.name = name;
}
// class와는 다르게 prototype을 통해 내부 함수를 지정해줌.
Person.prototype.sayHello = function() {
console.log(`Hello, I'm ${this.name}`);
};
let person = new Person('John');
person.sayHello();// 출력: Hello, I'm John// 런타임에 메서드 추가
Person.prototype.sayGoodbye = function() {
console.log(`Goodbye from ${this.name}`);
};
person.sayGoodbye();// 출력: Goodbye from John
외부 스코프의 thisclass Person {
constructor(name) {
this.name = name;
}
introduce() {
console.log(`My name is ${this.name}`);
}
}
let person = new Person('Alice');
person.introduce();// 출력: My name is Alice
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} makes a sound.`);
}
}
class Dog extends Animal {
constructor(name, breed) {
super(name);// 부모 클래스의 생성자 호출
this.breed = breed;
}
speak() {
super.speak();// 부모 클래스의 메서드 호출
console.log(`${this.name} barks.`);
}
introduce() {
console.log(`I'm ${this.name}, a ${this.breed}`);
}
}
let dog = new Dog('Rex', 'German Shepherd');
dog.speak();
// 출력: Rex makes a sound. Rex barks.
dog.introduce();// 출력: I'm Rex, a German Shepherd
ES6에서 등장한 새로운 문법으로
하다는 특징이 있다.
// 기존 함수
const foo = function () {
console.log('기존 함수');
}
// 화살표 함수
const foo = () => console.log('화살표 함수');
그렇다면 이걸 왜쓰냐? this 바인딩에 차이가 있기 때문이다.
굉장히 묘한데, JS에서의 this는 상황에 따라 다르게 바인딩된다.
대표적으로
class 및 객체에 종속) 호출시 내부의 this: 메소드를 호출한 객체독립적으로 존재) 호출 시 함수 내부의 this : 지정되지 않는다.지정되지 않음 = this는 전역 객체를 바라본다는 뜻이다. 이게 뭔말이냐 하면
const Arsenal = {
captain: 'Odegaard',
foo1: function() {
const foo2 = function() {
console.log(this.captain);
}
foo2();
}
};
Arsenal.foo1(); // undefined
foo1을 실행하게 되면 내부 함수 foo2가 실행되면서 this.captain을 호출하는데, foo2 내부에 this가 지정되지 않아서 전역 객체를 가리킨다. 즉, 전역 객체엔 captain이 없으므로 undefined가 출력된다.
const Arsenal = {
captain: 'Odegaard',
foo1: function() {
const foo2 = () => {
console.log(this.captain);
}
foo2();
}
};
Arsenal.foo1(); // Odegaard
화살표 함수로 this를 출력하면 제대로 동작이 된다!
이유인 즉슨, 화살표 함수로 선언한 함수에는 this가 없어서, 상위 환경으로 거슬러 올라가다 우리가 지정한 this를 참조한다는 것이다. 다시 말해 선언될 시점에서의 상위 스코프가 this로 바인딩됩니다.
현실에 존재하는 복잡성을 극복하는 것어떤 종류의 연산이 해당 데이터에 대해 수행될 수 있는지를 결정전통적인 데이터 타입의 개념은 객체의 타입에도 그대로 적용된다.
객체가 수행하는 행동이다. 동일한 행동을 수행할 수 있다면 동일한 타입으로 분류될 수 있다.즉, 객체의 내부 표현 방식이 다르더라도 어떤 객체들이 동일하게 행동한다면 그 객체들은 동일한 타입에 속함.
훌륭한 객체지향 설계는 외부에 행동만을 제공하고 데이터는 행동 뒤로 감춰야 한다. 이 원칙을 캡슐화라고 부른다.
객체를 디자인하기 위해서는 데이터가 아니라 행동을 먼저 생각해야 한다.
외부 인터페이스 뒤로 캡슐화해야 한다.데이터를 먼저 결정하고 객체의 책임을 결정하는 방법은 유연하지 못한 설계라는 악몽을 초래한다.
https://medium.com/@limsungmook/자바스크립트는-왜-프로토타입을-선택했을까-997f985adb42
가볍게 정리하면
그것의 본질이 존재한다는 것이 플라톤의 주장.개체의 속성이 동일한 경우 개체 그룹이 같은 범주에 속한다. 범주는 정의와 구별의 합이다 진정한 본래의 의미란 존재하지 않고 상황과 맥락에 의해서 결정된다. 맥락(컨텍스트)가 중요.가장 좋은 보기(prototype, exemplar)로부터 범주화된다.누가 어떤 상황(context)에서 접했나에 따라 의미가 달라진다는 것입니다. (의미사용이론)