new로 호출할 수 있는 함수// class Person {
// name = "Max";
// constructor() {
// this.age = 30;
// }
// greet() {
// console.log(
// "Hi, I am " + this.name + " and I am " + this.age + " years old."
// );
// }
// }
function Person() {
this.age = 30;
this.name = "Max";
this.greet = function () {
console.log(
"Hi, I am " + this.name + " and I am " + this.age + " years old."
);
};
}
// class로 생성한 Person과 생성자함수로 만든 Person에 대한 결과값이 동일하다.
const person = new Person();
person.greet();
new 키워드가 이면해서 하는 것은 클래스에서 하는 일이기도 하다.function Person(){...}와 같은 생성자 함수는 프로토타입이라는 개념으로 구현이 된다. → Person.prototype만약
person.sayHello()라고 입력을 했는데, person 객체에 sayHello() 메서드가 없을 경우에 JavaScript는 자동적으로 객체의 prototype을 찾고 그곳의 속성(property)나 메서드를 찾는다. 프로토타입의 프로토타입.. 까지 찾았는데도 없다면 → 특성(property)의 경우 undefined / 메서드일 경우 오류를 발생
function Person() {
this.age = 30;
this.name = "Max";
this.greet = function () {
console.log(
"Hi, I am " + this.name + " and I am " + this.age + " years old."
);
};
}
console.dir(Person); // __proto__와 prototype이 있음
const person = new Person();
person.greet();
console.log(person.__proto__);
// {constructor: ƒ}
// constructor: ƒ Person()
// [[Prototype]]: Object
console.log(person.__proto__ === Person.prototype); // true
// ============================================
Person.prototype = {
printAge() {
console.log(this.age);
},
};
console.log(person.__proto__); // {printAge : f}
person.printAge(); // 30
// ============================================
console.log(person.__proto__ === Person.prototype); // true
console.log(person.__proto__ === Person.__proto__); // false
__proto__ : JavaScript의 모든 객체에 있다.prototype__proto__ 특성이 있다.class AgedPerson {
printAge() {
console.log(this.age);
}
}
class Person extends AgedPerson {
name = "Max";
constructor() {
super();
this.age = 30;
}
greet() {
console.log(
"Hi, I am " + this.name + " and I am " + this.age + " years old."
);
}
}
const person = new Person();
person.greet();
console.log(person.__proto__);
//AgedPerson {constructor: ƒ, greet: ƒ}
// constructor: class Person
// greet: ƒ greet()
// [[Prototype]]: Object
person.printAge(); // 30
Object는 생성자 함수로 많은 빌트인 프로퍼티 혹은 메서드를 호출할 수 있다.Object.prototype ← 기본 프로토타입Object.prototype이 프로토타입 체인이 끝나는 지점이다.console.dir(Object);
객체 리터럴 표기법으로 생성된 어떤 객체 혹은 JavaScript로 생성된 객체는 자동으로 기본 프로토타입을 가지는데 이는 Object 생성자 함수에 기반하는 것이며 이 프로토타입(Object.prototype)을 폴백 객체로 사용할 것이다.
prototype property : 생성자 함수를 기반으로 생성된 객체에 추가될 내용을 구성하는 역할을 한다.__proto__ : 생성자 함수나 함수 객체 뿐만 아니라 모든 객체에서 사용 가능하다. 이는 결국 객체에 할당된 프로토타입을 가리키는데 즉 객체에 할당된 폴백 객체를 가리킨다.class AgedPerson {
printAge() {
console.log(this.age);
}
}
class Person extends AgedPerson {
name = "Max";
constructor() {
super();
this.age = 30;
}
greet() {
// 이렇게 축약형으로 쓰면 JavaScript에서 자동적으로 최적화 진행..
console.log(
"Hi, I am " + this.name + " and I am " + this.age + " years old."
);
}
// greet = function(){...} 이렇게나 greet = () => {...} 이런식으로 쓰면 해당 객체 안에서 greet이라는 property가 생성이 된다. 즉, JavaScript에서 최적화를 진행하지 X.
// => 성능이 떨어지고 메모리 영향이 있음. 그렇지만 크게 대단한 영향은 아니다..!
}
const p = new Person();
console.log(p);
//Person {name: 'Max', age: 30}
// age: 30
// name: "Max"
// [[Prototype]]: AgedPerson
// constructor: class Person
// greet: ƒ greet()
// [[Prototype]]: Object
// constructor: class AgedPerson
// printAge: ƒ printAge()
// [[Prototype]]: Object
const p2 = new Person();
console.log(p.__proto__ === p2.__proto__); // true => 메모리에 있는 완전히 동일한 객체를 사용하므로 true 리턴.
// =============
function Person() {
this.age = 30;
this.name = "Max";
}
Person.prototype.greet = function () {
console.log(
"Hi, I am " + this.name + " and I am " + this.age + " years old."
);
}; // 이렇게 생성자함수를 통해서 만드는 것과 같은 결과.
(+) 추가
class Person {
name = "Max";
constructor() {
this.age = 30;
}
greet = () => {
console.log(
"Hi, I am " + this.name + " and I am " + this.age + " years old."
);
};
}
const p = new Person();
const button = document.querySelector("button");
button.addEventListener("click", p.greet);
addEventListener와 같이 화살표함수를 이용하면 this를 이용(?)하기에 좋다. 만약 화살표가 아니라 축약형으로 greet을 작성한다면 다음과 같이 작성해야한다.
button.addEventListener("click", p.greet.bind(p));
이렇게 함으로써 this가 p임을 인식하도록 해야한다.
Array와 String에도 prototype이 있다.
class Person {
name = "Max";
constructor() {
this.age = 30;
}
greet = () => {
console.log(
"Hi, I am " + this.name + " and I am " + this.age + " years old."
);
};
}
const course = {
title: "JavaScript",
rating: 5,
};
console.log(Object.getPrototypeOf(course)); // course.__proto__ 를 한 값과 동일.
Object.setPrototypeOf(course, {
...Object.getPrototypeOf(course), // 해당 코드는 이전의 __proto__에 있던 기존의 메서드를 포함하고 싶을 때 사용.
printRating: function () {
console.log(`${this.rating}/5`);
},
});
course.printRating(); // 5/5
// 객체 생성2
const student = Object.create({
printProgress: function () {
console.log(this.progress);
},
}, {
name: {
configurable: true,
enumerabe: true,
value: 'Max',
writable:true
}
});
// student.name = 'Max';
Object.defineProperty(student, 'progress', {
configurable: true,
enumerable: true,
value: 0.8,
writable: true
})
student.printProgress(); //0.8
console.log(student);
// {name: 'Max', progress: 0.8}
// name: 'Max'
// progress: 0.8
// __proto__: Object
// printProgress: f ()
// __proto__: Object
Object.setPrototypeOf : 프로토타입을 설정할 객체, 사용할 프로토타입 을 입력