
μλ°μ€ν¬λ¦½νΈλ νλ‘ν νμ
κΈ°λ°μΌλ‘, functionκ³Ό prototypeμΌλ‘ μμμ ꡬννλ€.
function Animal(name) {
this.name = name;
}
Animal.prototype.speak = function () {
console.log(this.name + ' makes a noise.');
};
function Dog(name) {
Animal.call(this, name); // μμ
}
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
const dog = new Dog('Buddy');
dog.speak(); // Buddy makes a noise.
νμ§λ§ μ΄ λ°©λ²μ ν΄λμ€ κΈ°λ° μΈμ΄(C++, Java λ±)μ μ΅μν κ°λ°μλ€μκ²λ 볡μ‘νλ€. κ·Έλμ ES6λΆν° class λ¬Έλ²μ΄ λμ λμλ€. class λ¬Έλ²μ μλ‘μ΄ κ°μ²΄μ§ν₯ λͺ¨λΈμ μ 곡νλ κ²μ΄ μλλ©°, ν΄λμ€λ μ¬μ€μ ν¨μμ΄λ€. λ¨μ§ κΈ°μ‘΄ λ°©μμ λ μ½κΈ° μ’κ³ μ°κΈ° νΈνκ² λ°κΎΌ κ²μΌ λΏμ΄λ€.
μλ°μ€ν¬λ¦½νΈμ λͺ¨λ κ°μ²΄λ μμ μ λΆλͺ¨ μν μ λ΄λΉνλ κ°μ²΄μ μ°κ²°λμ΄ μλ€. κ·Έλ¦¬κ³ μ΄κ²μ λ§μΉ κ°μ²΄ μ§ν₯μ μμ κ°λ κ³Ό κ°μ΄ λΆλͺ¨ κ°μ²΄μ νλ‘νΌν° λλ λ©μλλ₯Ό μμλ°μ μ¬μ©ν μ μκ² νλ€. μ΄λ¬ν λΆλͺ¨ κ°μ²΄λ₯ΌΒ Prototype(νλ‘ν νμ ) κ°μ²΄Β λλ μ€μ¬μ Prototype(νλ‘ν νμ )μ΄λΌ νλ€.
Prototype κ°μ²΄λ μμ±μ ν¨μμ μν΄ μμ±λ κ°κ°μ κ°μ²΄μ 곡μ νλ‘νΌν°λ₯Ό μ 곡νκΈ° μν΄ μ¬μ©νλ€.
let student = {
name: 'Lee',
score: 90
};
console.log(student.hasOwnProperty('name')); // true
console.dir(student);
studentμλ hasOwnProperty λ©μλκ° μμ§λ§ λμν μ μλ μ΄μ λ studentμ νλ‘ν νμ
μ΄ Objectμ΄κΈ° λλ¬Έμ΄λ€. Objectμλ hasOwnProperty λ©μλκ° μκΈ° λλ¬Έμ studentκ° μ΄λ₯Ό μ¬μ©ν μ μλ κ²μ΄λ€.

νλ‘ν νμ κ°μ²΄λ constructor νλ‘νΌν°λ₯Ό κ°λλ€. μ΄ constructor νλ‘νΌν°λ κ°μ²΄μ μ μ₯μμ μμ μ μμ±ν κ°μ²΄λ₯Ό κ°λ¦¬ν¨λ€.
μλ₯Ό λ€μ΄ Person() μμ±μ ν¨μμ μν΄ μμ±λ κ°μ²΄λ₯Ό fooλΌ νμ. μ΄ foo κ°μ²΄λ₯Ό μμ±ν κ°μ²΄λ Person()μμ±μ ν¨μμ΄λ€. μ΄λ foo κ°μ²΄ μ
μ₯μμ μμ μ μμ±ν κ°μ²΄λ Person() μμ±μ ν¨μμ΄λ©°, foo κ°μ²΄μ νλ‘ν νμ
κ°μ²΄λ Person.prototypeμ΄λ€. λ°λΌμ νλ‘ν νμ
κ°μ²΄ Person.prototypeμ constructor νλ‘νΌν°λ Person() μμ±μ ν¨μλ₯Ό κ°λ¦¬ν¨λ€.
function Person(name) {
this.name = name;
}
let foo = new Person("Lee");
// Person() μμ±μ ν¨μμ μν΄ μμ±λ κ°μ²΄λ₯Ό μμ±ν κ°μ²΄λ Person() μμ±μ ν¨μμ΄λ€.
console.log(Person.prototype.constructor === Person);
// foo κ°μ²΄λ₯Ό μμ±ν κ°μ²΄λ Person() μμ±μ ν¨μμ΄λ€.
console.log(foo.constructor === Person);
// Person() μμ±μ ν¨μλ₯Ό μμ±ν κ°μ²΄λ Function() μμ±μ ν¨μμ΄λ€.
console.log(Person.constructor === Function);
Person.prototype.constructor === Personμ μλμΌλ‘ μ€μ λμ΄ μλ€.Functionμ μμλ‘ μμ±κ³Ό νλ‘ν νμ
ꡬ쑰μ λν΄ μ΄ν΄λ³΄λ €κ³ νλ€.
μλ°μ€ν¬λ¦½νΈμμ Functionμ ν¨μμ΄λ©΄μλ μμ±μ ν¨μ μν λ ν μ μλ κ°μ²΄μ΄λ€. μλμ μλ κ²λ€μ΄ κ°κ° μ΄λ€ κ²μ μλ―Ένλμ§ μμ보μ.
Function
Function.__proto__
Function.constructor
Function.prototype
Function.prototype.__proto__
Function.prototype.constructor
FunctionFunction μ체λ ν¨μ κ°μ²΄μ΄λ€. (typeof Function === 'function')Functionμ ν¨μ κ°μ²΄κ³ , κ·Έ ν¨μ κ°μ²΄λ₯Ό μμ±ν κ²λ Function μμ±μ ν¨μλκΉ κ²°κ΅ Functionμ Functionμ μΈμ€ν΄μ€κ° λλ κ²μ΄λ€. π€―π€―π€―console.log(typeof Function); // 'function'
console.log(Function instanceof Function); // true
Function.__proto__Function.prototypeμ κ°λ¦¬ν¨λ€.Function μ체λ μΌλ¨ ν¨μλ€. μμμ λ§νλ―μ΄ κ·Έ ν¨μ κ°μ²΄λ₯Ό μμ±ν κ²λ Function μμ±μ ν¨μλκΉ Function.prototypeμ κ°λ¦¬ν€λ κ²μ΄λ€.prototype νλ‘νΌν°λ ν¨μ κ°μ²΄κ° μμ±μλ‘ μ¬μ©λ λ μ΄ ν¨μλ₯Ό ν΅ν΄ μμ±λ κ°μ²΄μ λΆλͺ¨ μν μ νλ κ°μ²΄λ₯Ό μλ―Ένλ€.console.log(Function.__proto__ === Function.prototype); // true
μ 리νμλ©΄,
Functionμ ν¨μμ΄μ μμ±μμ΄κ³ ,Functionμμ μ μμ±νλ μμ±μμ΄λ©΄μ λΆλͺ¨μν λ νλβ¦. κ·Έλ° λ³΅μ‘ν ꡬ쑰λ₯Ό κ°μ§ κ°μ²΄λΌλ κ²μ΄λ€.
Function.constructorFunction κ°μ²΄λ Function μμ±μμ μν΄ μμ±λμκΈ° λλ¬Έμ Functionμ κ°λ¦¬ν¨λ€.console.log(Function.constructor === Function); // true
Function.prototypecall, apply, bind λ±)function foo() {}
console.log(foo.__proto__ === Function.prototype); // true
Function.prototype.__proto__Object.prototype μ κ°λ¦¬ν¨λ€.console.log(Function.prototype.__proto__ === Object.prototype); // true
Function.prototype.constructorFunctionμ κ°λ¦¬ν¨λ€.console.log(Function.prototype.constructor === Function); // true
μλ°μ€ν¬λ¦½νΈλ νΉμ κ°μ²΄μ νλ‘νΌν°λ λ©μλμ μ κ·Όνλ €κ³ ν λ ν΄λΉ κ°μ²΄μ μ κ·Όνλ €λ νλ‘νΌν° λλ λ©μλκ° μλ€λ©΄ [[Prototype]]μ΄ κ°λ¦¬ν€λ λ§ν¬λ₯Ό λ°λΌ μμ μ λΆλͺ¨ μν μ νλ νλ‘ν νμ
κ°μ²΄μ νλ‘νΌν°λ λ©μλλ₯Ό μ°¨λ‘λλ‘ κ²μνλ€. μ΄κ²μ νλ‘ν νμ
체μΈμ΄λΌ νλ€.
κ°μ²΄μ νλ‘νΌν°μ κ°μ ν λΉνλ κ²½μ°, νλ‘ν νμ 체μΈμ λμνμ§ μλλ€. μ΄λ κ°μ²΄μ ν΄λΉ νλ‘νΌν°κ° μλ κ²½μ°, κ°μ μ¬ν λΉνκ³ ν΄λΉ νλ‘νΌν°κ° μλ κ²½μ°λ ν΄λΉ κ°μ²΄μ νλ‘νΌν°λ₯Ό λμ μΌλ‘ μΆκ°νκΈ° λλ¬Έμ΄λ€.
// νλ‘ν νμ
κ°μ²΄ μμ±
const grandParent = {
sayHi: function() {
console.log("Hi from grandparent!");
}
};
const parent = Object.create(grandParent); // grandParentλ₯Ό νλ‘ν νμ
μΌλ‘ μ€μ
const child = Object.create(parent); // parentλ₯Ό νλ‘ν νμ
μΌλ‘ μ€μ
child.sayHi(); // "Hi from grandparent!"
β‘οΈ child κ°μ²΄μλ sayHi λ©μλκ° μμ§λ§, child β parent β grandParent μμλ‘ μ°Ύμκ°λ©° sayHiλ₯Ό μ΅μ’
μ μΌλ‘ grandParentμμ μ°Ύμ νΈμΆν μ μλ€.
Object() μμ±μ ν¨μ λ°©μμΌλ‘ μμ±λ κ°μ²΄μ νλ‘ν νμ
체μΈκ°μ²΄ 리ν°λ΄ λ°©μμΌλ‘ μμ±λ κ°μ²΄λ κ²°κ΅ λ΄μ₯ ν¨μ(Built-in)μΈ Object() μμ±μ ν¨μλ‘ κ°μ²΄λ₯Ό μμ±νλ κ²μ λ¨μνμν¨ κ²μ΄λΌκ³ μμμ μΈκΈν λ° μλ€. Object() μμ±μ ν¨μλ λ¬Όλ‘ ν¨μμ΄λ€. λ°λΌμ ν¨μ κ°μ²΄μΈ Object() μμ±μ ν¨μλ μΌλ° κ°μ²΄μ λ¬λ¦¬ prototype νλ‘νΌν°κ° μλ€.
μλ μΆλ ₯ κ²°κ³Όλ₯Ό 보면, κ°μ²΄ 리ν°λ΄μ μ¬μ©νμ¬ κ°μ²΄λ₯Ό μμ±ν κ²½μ° κ·Έ κ°μ²΄μ νλ‘ν νμ κ°μ²΄λ Object.prototypeμ΄λ€.
let person = {
name: 'Lee',
gender: 'male',
sayHello: function(){
console.log('Hi! my name is ' + this.name);
}
};
console.log(person.__proto__ === Object.prototype); // β true
console.log(Object.prototype.constructor === Object); // β‘ true
// Object() μμ±μ ν¨μλ Function κ°μ²΄λ‘λΆν° μμλ°κΈ° λλ¬Έμ
console.log(Object.__proto__ === Function.prototype); // β’ true
// Function.prototypeμ Object.prototypeμ μμνκ³ μκΈ° λλ¬Έμ
console.log(Function.prototype.__proto__ === Object.prototype); // β£ true

μ¬κΈ°μ μ μΌ ν·κ°λ¦¬λ κ°λ μ΄ Objectλ Function κ°μ²΄λ‘λΆν° μμλ°κ³ , Function. prototypeμ Object.prototypeμΌλ‘λΆν° μμλ°λλ€λ κ²μ΄λ€. π€
μ‘°κΈ ν·κ°λ¦΄ μ μλλ°, μ°μ Objectκ° Function κ°μ²΄λ‘λΆν° μμλ°λ κ²μ μ΄ν΄λ³΄μ.
Objectλ ν¨μ κ°μ²΄μ΄λ―λ‘(Objectμμ²΄κ° μμ±μ ν¨μμ΄κΈ° λλ¬Έ) κΈ°λ³Έμ μΌλ‘Functionκ°μ²΄λ‘λΆν° μμμ λ°λλ€. λ°λΌμObject.__proto__λFunction.prototypeμ κ°λ¦¬ν¨λ€.
Function.prototypeμ ν¨μ κ°μ²΄λ€μ κ³΅ν΅ νλ‘ν νμ μ μ 곡νλ κ°μ²΄μ΄λ€. λͺ¨λ ν¨μ κ°μ²΄λFunction.prototypeμ μμνλλ°,Function.prototypeμ체λObject.prototypeμ μμνλ€. μ¦,Object.prototypeμμ κΈ°λ³Έ λ©μλ(toString(),hasOwnProperty()λ±)λ₯Ό μμλ°μ μ¬μ©ν μ μλ€λ λ»μ΄λ€.μ΄ κ°λ μ 보κ³
ObjectμFunctionμ΄ μλ‘ μμνλ κ²μ΄λΌκ³ ν·κ°λ¦¬λ©΄ μλλ€!!Objectκ°Function.prototypeμ μμνκ³ ,Function.prototypeμObject.prototypeμ μμνλ κ΅¬μ‘°μΈ κ²μ΄λ€.
Functionκ³Ό Objectμμ κ΄κ³ μ 리Function (ν¨μ)
ββ constructor β Function
ββ __proto__ β Function.prototype
Function.prototype
ββ constructor β Function
ββ __proto__ β Object.prototype
Object
ββ constructor β Function (μμ±μ ν¨μλ‘ μμ±νμΌλ―λ‘)
ββ __proto__ β Function.prototype
Object.prototype
ββ __proto__ β null
π€― μ΄κ² κ°λ₯ν μ΄μ λ μλ°μ€ν¬λ¦½νΈ μμ§μ΄ λΆνΈμ€νΈλ© κ³Όμ μμ Functionκ³Ό Objectλ₯Ό λμμ μ μνκ³ μλ‘λ₯Ό μ°κ²°ν΄λκΈ° λλ¬Έμ΄λ€.
Object ν¨μ κ°μ²΄ μμ±Object.prototype μμ±Function ν¨μ κ°μ²΄ μμ±Function.prototype μμ±Object.__proto__ = Function.prototypeFunction.__proto__ = Function.prototypeFunction.prototype.__proto__ = Object.prototypeμμ±μ ν¨μλ‘ κ°μ²΄λ₯Ό μμ±νλ λ°©μμ κ²°κ΅ Function() μμ±μ ν¨μλ₯Ό ν΅ν΄ ν¨μ κ°μ²΄λ₯Ό μμ±νλ€. λ°λΌμ, μ΄λ ν λ°©μμΌλ‘ ν¨μ κ°μ²΄λ₯Ό μμ±νμ¬λ λͺ¨λ ν¨μ κ°μ²΄μ prototype κ°μ²΄λ Function.prototypeμ΄λ€.
function Person(name, gender) {
this.name = name;
this.gender = gender;
this.sayHello = function(){
console.log('Hi! my name is ' + this.name);
};
}
let foo = new Person('Lee', 'male');
console.log(foo.__proto__ === Person.prototype); // β true
console.log(Person.prototype.__proto__ === Object.prototype); // β‘ true
console.log(Person.prototype.constructor === Person); // β’ true
console.log(Person.__proto__ === Function.prototype); // β£ true
console.log(Function.prototype.__proto__ === Object.prototype); // β€ true

foo κ°μ²΄μ νλ‘ν νμ
κ°μ²΄ Person.prototype κ°μ²΄μ Person() μμ±μ ν¨μμ νλ‘ν νμ
κ°μ²΄μΈ Function.prototypeμ νλ‘ν νμ
κ°μ²΄λ Object.prototypeκ°μ²΄μ΄λ€.
μ΄λ κ°μ²΄ 리ν°λ΄ λ°©μμ΄λ μμ±μ ν¨μ λ°©μμ΄λ κ²°κ΅μ λͺ¨λ κ°μ²΄μ λΆλͺ¨ κ°μ²΄μΈ Object.prototype κ°μ²΄μμ νλ‘ν νμ
체μΈμ΄ λλκΈ° λλ¬Έμ΄λ€. μ΄λ Object.prototypeκ°μ²΄λ₯ΌΒ νλ‘ν νμ
체μΈμ μ’
μ (End of prototype chain)μ΄λΌ νλ€. λ°λΌμ, λͺ¨λ κ°μ²΄λ νλ‘ν νμ
체μΈμ μν΄ Object.prototype κ°μ²΄μ λ©μλλ₯Ό μ¬μ©ν μ μλ€.