4. ν¨μμ νλ‘ν νμ 체μ΄λ - 3
μ΄ κΈμ κ³ νμ€, μ‘νμ£Ό λμ μΈμ¬μ΄λ μλ°μ€ν¬λ¦½νΈλ₯Όμ°Έμ‘°νμ¬ μμ±ν κΈμ λλ€.
#
νλ‘ν νμ 체μ΄λ#
νλ‘ν νμ μ λ κ°μ§ μλ―ΈJSλ C++μ΄λ Java κ°μ κ°μ²΄μ§ν₯ μΈμ΄μ λ€λ₯Έ νλ‘ν νμ κΈ°λ°μ κ°μ²΄μ§ν₯ νλ‘κ·Έλλ°μ μ§μνλ€.
JSκ° μ΄λ»κ² OOP κΈ°λ₯μ μ 곡νλμ§ μ΄ν΄νλ €λ©΄, νλ‘ν νμ κ³Ό νλ‘ν νμ 체μ΄λμ λν΄ μ λλ‘ μ΄ν΄ν΄μΌ νλ€.
Javaμ κ°μ κ°μ²΄μ§ν₯ νλ‘κ·Έλλ°μμλ ν΄λμ€λ₯Ό μ μνκ³ μ΄λ₯Ό ν΅ν΄ κ°μ²΄λ₯Ό μμ±νμ§λ§ JSμλ ν΄λμ€ κ°λ
μ΄ μλ€. λμ μ κ°μ²΄ 리ν°λ΄μ΄λ, μμ±μ ν¨μλ‘ κ°μ²΄λ₯Ό μμ±νλλ°, μ΄λ κ² μμ±λ κ°μ²΄μ λΆλͺ¨ κ°μ²΄κ° λ°λ‘ Prototype
κ°μ²΄λ€. μμ κ°μ²΄λ λΆλͺ¨ κ°μ²΄κ° κ°μ§ νλ‘νΌν° μ κ·Όμ΄λ λ©μλ νΈμΆμ΄ κ°λ₯νλ€.
βοΈ μ°Έκ³ λ‘ μ΅κ·Όμ ES6 λ¬Έλ²μμλ
Class
λ¬Έλ²μ΄ μΆκ°λμμΌλ μλ°μ€ν¬λ¦½νΈκ° ν΄λμ€ κΈ°λ°μΌλ‘ λ°λμλ€λ κ²μ μλλ€.
JSμ λͺ¨λ κ°μ²΄λ μμ μ λΆλͺ¨μΈ Prototype
κ°μ²΄λ₯Ό κ°λ¦¬ν€λ μ¨κ²¨μ§ νλ‘νΌν°κ° μλλ° ECMAScriptμμλ μ΄λ₯Ό μ묡μ νλ‘ν νμ
λ§ν¬(Implicit prototype link)λΌκ³ λΆλ₯΄λ©° [[Prototype]]
λΌλ μ¨κ²¨μ§ νλ‘νΌν°μ μ μ₯λλ€. (ν¬λ‘¬μ΄λ νμ΄μ΄νμ€ κ°μ λΈλΌμ°μ μμλ μ΄λ₯Ό __proto__
νλ‘νΌν°λ‘ λͺ
μμ μΌλ‘ μ 곡νκ³ μλ€.)
κ·Έλ°λ° ν¨μ κ°μ²΄κ° κ°μ§λ prototype
νλ‘νΌν°μ κ°μ²΄μ μ¨μ νλ‘νΌν° [[Prototype]]
λ§ν¬λ₯Ό ꡬλΆν΄μΌ νλ€. μ΄κ²μ΄ λ°λ‘ ν·κ°λ¦¬κΈ° μ¬μ΄ νλ‘ν νμ
μ λ κ°μ§ μλ―Έμ΄λ€.
prototype
νλ‘νΌν°#
JSμμ ν¨μλ₯Ό μ μνλ©΄, ν¨μ μμ±κ³Ό λμμ Prototype
κ°μ²΄ κ° μμ±λλ€. κ·Έλ¦¬κ³ μμ±λ ν¨μλ prototype
νλ‘νΌν°λ₯Ό ν΅ν΄ Prototype
κ°μ²΄λ₯Ό κ°λ¦¬ν€κ² λλ€.
Prototype
κ°μ²΄λ μΌλ°μ μΈ κ°μ²΄μ κ°μΌλ©°, κΈ°λ³Έ μμ±μΌλ‘ constructor
μ __proto__
λ₯Ό κ°μ§κ³ μλ€. κ·Έλ¦¬κ³ constructor
μμ±μ Prototype
κ°μ²΄μ ν¨κ»μμ±λμλ ν¨μλ₯Ό κ°λ¦¬ν¨λ€.
function myFunc() {}console.dir(myFunc);
[μΆλ ₯ κ²°κ³Ό]
[[Prototype]]
λ§ν¬( __proto__
)#
μ΄ [[Prototype]]
λ§ν¬ μμ±μ λͺ¨λ κ°μ²΄κ° κ°μ§κ³ μλ μμ±μ΄λ€. μ΄ μμ±μμ΄ κ°μ²΄λ₯Ό μμ±ν μμ±μ ν¨μμ prototype
νλ‘νΌν°κ° κ°λ¦¬ν€λ Prototype
κ°μ²΄λ₯Ό κ°λ¦¬ν€κ³ , λ§ν¬λ‘ μ°κ²°ν΄ μμ μ λΆλͺ¨ κ°μ²΄λ‘ μ€μ νλ€.
// Person μμ±μ ν¨μfunction Person(name) { this.name = name;}
// foo κ°μ²΄ μμ±var foo = new Person('foo');
console.dir(Person);console.dir(foo);
[μΆλ ₯ κ²°κ³Ό]
κ²°κ³Όλ₯Ό 보면 Person()
μμ±μ ν¨μμ prototype
νλ‘νΌν°μ foo
κ°μ²΄μ __proto__
νλ‘νΌν°κ° κ°μ Prototype
κ°μ²΄λ₯Ό κ°λ¦¬ν€κ³ μλ€.
λν ν΄λΉ Prototype
κ°μ²΄λ constructor()
νλ‘νΌν°κ° Person()
μμ±μ ν¨μλ₯Όκ°λ¦¬ν€κ³ μλ€.
JSμ κ°μ²΄ μμ± λ°©μμ λ€μ νλ² μ 리νλ©΄ μ΄λ λ€.
μμ±μ ν¨μ(
Person()
)λ₯Ό μ μνλ©΄, ν¨μμ λμμPrototype
κ°μ²΄(Person.prototype
)μ΄ μμ±λλ€.Person
ν¨μμprototype
νλ‘νΌν°λPerson.prototype
μ κ°λ¦¬ν€κ³ ,Person.prototype.constructor
κ°Person()
ν¨μλ₯Ό κ°λ¦¬ν¨λ€.Person()
ν¨μλ‘ μμ±λ κ°μ²΄(foo
)λPerson()
ν¨μμprototype
νλ‘νΌν°κ° κ°λ¦¬ν€λPrototype
κ°μ²΄λ₯Ό[[Prototype]]
λ§ν¬λ‘ μ°κ²°νλ€. (__proto__
)
#
κ°μ²΄ 리ν°λ΄ λ°©μμΌλ‘ μμ±λ νλ‘ν νμ 체μ΄λκ°μ²΄ 리ν°λ΄ λ°©μμΌλ‘ κ°μ²΄λ₯Ό μμ±νλ κ²λ κ²°κ΅ λ΄λΆμμλ μμ±μ ν¨μ Object()
λ₯Ό μ¬μ©νλ κ²μμ κΈ°μ΅νμ.
κ·Έλ¦¬κ³ JSμμ κ°μ²΄λ μκΈ° μμ μ νλ‘νΌν°λΏλ§ μλλΌ, μμ μ λΆλͺ¨ μν μ νλ Prototype
κ°μ²΄μ νλ‘νΌν°λ₯Ό μμ μ κ²μΌλ‘ μ κ·Όνλ κ²μ΄ κ°λ₯νλ€. μ΄λ₯Ό νλ‘ν νμ
체μ΄λμ΄λΌκ³ νλ€.
var myObject = { name: 'foo', sayName: function () { console.log('My Name is ' + this.name); },};
myObject.sayName(); // My Name is fooconsole.log(myObject.hasOwnProperty('name')); // trueconsole.log(myObject.hasOwnProperty('nickName')); // falsemyObject.sayNickName(); // Uncaught TypeError: Object #<Object> has no method 'sayNickName'
myObject
λ name
νλ‘νΌν°μ sayName()
λ©μλλ₯Ό κ°μ§ κ°μ²΄μ΄λ€. sayName()
λ©μλλ μ λλ‘ μΆλ ₯λμ§λ§, sayNickName()
λ©μλλ myObject
μ λ©μλκ° μλλ―λ‘ μλ¬κ° λ°μνλ€.
κ·Έλ°λ° myObject
μλ hasOwnProperty()
λΌλ λ©μλκ° μμμλ κ²°κ³Όκ° μ μμ μΌλ‘ μΆλ ₯λλ€.
μ΄μ λ λ€μκ³Ό κ°λ€.
κ°μ²΄ 리ν°λ΄λ‘ μμ±λ κ°μ²΄λ λ΄μ₯ μμ±μ ν¨μ
Object()
λ₯Ό ν΅ν΄ μμ±λ κ²μ΄λ€ .μμ±μ ν¨μ
Object()
μμ ν¨μ κ°μ²΄μ΄λ―λ‘prototype
νλ‘νΌν°λ₯Ό κ°κ³ μκ³ ,Object.prototype
κ°μ²΄λ₯Ό κ°λ¦¬ν€κ³ μλ€.μμ±μ ν¨μ
Object()
λ₯Ό ν΅ν΄ μμ±λmyObject
κ°μ²΄λObject()
ν¨μμprototype
νλ‘νΌν°κ° κ°λ¦¬ν€λObject.prototype
κ°μ²΄λ₯Ό[[Prototype]]
λ§ν¬λ‘ μ°κ²°νλ€.JSμμ νΉμ κ°μ²΄μ νλ‘νΌν°λ λ©μλμ μ κ·Όνλ €κ³ ν λ, μ κ·Όνλ €λ νλ‘νΌν°λλ λ©μλκ° μλ€λ©΄,
[[Prototype]]
λ§ν¬λ₯Ό λ°λΌ μμ μ λΆλͺ¨ μν μ νλPrototype
κ°μ²΄μ νλ‘νΌν° λλ λ©μλλ₯Ό μ°¨λ‘λλ‘ κ²μνλ€. (μ΄λ₯Ό νλ‘ν νμ 체μ΄λμ΄λΌκ³ νλ€.)Object.prototype
κ°μ²΄λ λͺ¨λ κ°μ²΄μ μ‘°μ μν μ νλ κ°μ²΄λ‘μ,toString()
,hasOwnProperty()
λ±μ νμ€ λ©μλλ₯Ό κ°κ³ μμΌλ―λ‘, μ΄λ₯Ό μ¬μ©ν μ μλ€.
#
μμ±μ ν¨μλ‘ μμ±λ κ°μ²΄μ νλ‘ν νμ 체μ΄λκ·Έλ¬λ©΄ κ°μ²΄ 리ν°λ΄ λ°©μμ΄ μλ, μ§μ μ μν μμ±μ ν¨μλ‘ κ°μ²΄λ₯Ό μμ±νλ κ²½μ°μ΄λ»κ² νλ‘ν νμ 체μ΄λμ΄ λμνλμ§ μμ보μ.
// Person() μμ±μ ν¨μfunction Person(name, age, hobby) { this.name = name; this.age = age; this.hobby = hobby;}
// foo κ°μ²΄ μμ±var foo = new Person('foo', 30, 'tennis');
// νλ‘ν νμ
체μ΄λconsole.log(foo.hasOwnProperty('name')); // true
// Person.prototype κ°μ²΄ μΆλ ₯console.dir(Person.prototype);
μμ μμ μμ foo
κ°μ²΄μ μμ±μλ Person()
ν¨μμ΄λ€. λ°λΌμ foo
κ°μ²΄μ Prototype
κ°μ²΄λ μμ μ μμ±ν Person()
ν¨μμ prototype
νλ‘νΌν°κ° κ°λ¦¬ν€λ κ°μ²΄( Person.prototype
)κ° λλ€.
κ·Έλ°λ° μ΄λ»κ² Object.prototype
κ°μ²΄κ° κ°κ³ μλ νμ€ λ©μλμΈ hasOwnProperty()
λ₯Ό μ¬μ©ν μ μμμκΉ?
foo.hasOwnProperty()
λ©μλλ₯Ό νΈμΆνμ λfoo
κ°μ²΄μλfoo.hasOwnProperty()
λ©μλκ° μκΈ° λλ¬Έμ νλ‘ν νμ 체μ΄λμΌλ‘ λΆλͺ¨ κ°μ²΄μΈPerson.prototype
μμhasOwnProperty()
λ©μλλ₯Ό μ°Ύλλ€.νμ§λ§,
Person.prototype
κ°μ²΄λ λν΄νΈλ‘constructor
νλ‘νΌν°λ§μ κ°κ³ μμΌλ―λ‘hasOwnProperty()
λ©μλκ° μλ€.Person.prototype
κ°μ²΄ μμ JS κ°μ²΄λ‘, λͺ¨λ κ°μ²΄μ λΆλͺ¨μΈObject.prototype
μPrototype
κ°μ²΄λ‘ κ°μ§λ€. λ°λΌμ,Object.prototype
μμhasOwnProperty()
λ₯Ό λ€μ κ²μνλ νλ‘ν νμ 체μ΄λμ΄ νλ² λ μΌμ΄λκ³ , νμ€ λ©μλλ€μ μ¬μ©ν μ μλ€.
μ΄λ κ² κ°μ²΄ 리ν°λ΄ λ°©μκ³Ό μ§μ μ μν μμ±μ ν¨μμμμ νλ‘ν νμ 체μ΄λ λ°©λ²μμ μ‘°κΈ μ°¨μ΄κ° μμ§λ§ κ²°κ΅ μμΉμ κ°λ€.
"μλ°μ€ν¬λ¦½νΈμμ λͺ¨λ κ°μ²΄λ μμ μ μμ±ν μμ±μ ν¨μμ
prototype
νλ‘νΌν°κ° κ°λ¦¬ν€λ κ°μ²΄λ₯Ό μμ μPrototype
κ°μ²΄(λΆλͺ¨ κ°μ²΄)λ‘ μ·¨κΈνλ€."
#
νλ‘ν νμ 체μ΄λμ μ’ μ μμ μ΄ν΄λ³Έ κ²μ²λΌ, Object.prototype
κ°μ²΄λ νλ‘ν νμ
체μ΄λμ μ’
μ μ΄λ€. λ°©μμ μκ΄ μμ΄ λͺ¨λ κ°μ²΄λ νλ‘ν νμ
체μ΄λμΌλ‘ Object.prototype
κ°μ²΄κ° κ°μ§ νλ‘νΌν°μ λ©μλμ μ κ·Ό κ°λ₯νκ³ μλ‘ κ³΅μ κ°λ₯νλ€.
#
κΈ°λ³Έ λ°μ΄ν° νμ νμ₯JSμ μ«μ, λ¬Έμμ΄, λ°°μ΄ λ±μμ μ¬μ©νλ νμ€ λ©μλλ€μ κ²½μ° μ΄λ€μ νλ‘ν νμ
μΈ Number.prototype
, String.prototype
, Array.prototype
μ μ μλμ΄ μλ€. λν μ΄λ€ μμ Object.prototype
μ μμ μ νλ‘ν νμ
μΌλ‘ κ°κ³ μμ΄μ Object.prototype
μ λ©μλ μμ μ¬μ©ν μ μλ€.
λν JSλ νμ€ λΉνΈμΈ Prototype
κ°μ²΄μ μ¬μ©μκ° μ§μ λ©μλλ₯Ό μ μν΄ μΆκ°νλκ²μ νμ©νλ€.
String.prototype.testMethod = function () { console.log('This is the String.prototype.testMethod()');};
var str = 'This is test';str.testMethod();
console.dir(String.prototype);
[μΆλ ₯ κ²°κ³Ό]
#
νλ‘ν νμ λ μλ°μ€ν¬λ¦½νΈ κ°μ²΄λ€ν¨μκ° μμ±λ λ, μμ μ prototype
νλ‘νΌν°μ μ°κ²°λλ Prototype
κ°μ²΄λ λν΄νΈλ‘ constructor
νλ‘νΌν°λ§μ κ°μ§ κ°μ²΄λ€. λ€μ λ§ν΄ Prototype
κ°μ²΄ μμ μλ°μ€ν¬λ¦½νΈ κ°μ²΄μ΄λ€.
μ¦, μΌλ° κ°μ²΄μ²λΌ λμ νλ‘νΌν° μΆκ°/μμ κ° κ°λ₯νλ€. μ΄λ κ² λ³κ²½λ νλ‘νΌν°λμ€μκ°μΌλ‘ νλ‘ν νμ 체μ΄λμ λ°μλλ€.
// Person μμ±μ ν¨μfunction Person(name) { this.name = name;}
// foo κ°μ²΄ μμ±var foo = new Person('foo');
// foo.sayHello();// μ΄ μμ μλ sayHello() λ©μλκ° foo κ°μ²΄μ Person.prototype κ°μ²΄ λͺ¨λμ μ μλμ΄ μμ§ μμΌλ―λ‘ μλ¬κ° λ°μνλ€.
// Prototype κ°μ²΄μ sayHello() λ©μλ μ μPerson.prototype.sayHello = function () { console.log('Hello');};
foo.sayHello(); // Hello
foo
κ°μ²΄μ Prototype
κ°μ²΄μΈ Person.prototype
κ°μ²΄μ λμ μΌλ‘ sayHello()
λ©μλλ₯Ό μΆκ°ν μ΄νμλ foo
κ°μ²΄μ sayHello()
λ©μλκ° μμ§λ§ νλ‘ν νμ
체μ΄λμΌλ‘ 'Hello' κ° μΆλ ₯λλ€.
this
λ°μΈλ©#
νλ‘ν νμ
λ©μλμ Prototype
κ°μ²΄λ λ©μλλ₯Ό κ°μ§ μ μλ€. (μ΄λ₯Ό μ§§κ² νλ‘ν νμ
λ©μλλΌκ³ λΆλ₯΄κΈ°λ ν¨.)
λ§μ½ νλ‘ν νμ
λ©μλ λ΄λΆμμ this
λ₯Ό μ¬μ©νλ€λ©΄ μ΄λ μ΄λμ λ°μΈλ©λ κ²μΈκ° ?
μ΄λ μμ μ΄ν΄λ³Έ κ°μ²΄μ λ©μλλ₯Ό νΈμΆν λ this
λ°μΈλ© κ·μΉκ³Ό λμΌνλ€. μ¦ this
κ° λ©μλλ₯Ό νΈμΆν κ°μ²΄μ λ°μΈλ©λλ€.
// Person() μμ±μ ν¨μfunction Person(name) { this.name = name;}
// getName() νλ‘ν νμ
λ©μλPerson.prototype.getName = function () { return this.name;};
// foo κ°μ²΄ μμ±var foo = new Person('foo');
console.log(foo.getName()); // foo
// Person.prototype κ°μ²΄μ name νλ‘νΌν° λμ μΆκ°Person.prototype.name = 'person';
console.log(Person.prototype.getName()); // person
#
λν΄νΈ νλ‘ν νμ μ λ€λ₯Έ κ°μ²΄λ‘ λ³κ²½μ΄ κ°λ₯νλ€μμμ μ΄ν΄λ³Έ κ²μ²λΌ JSμμλ ν¨μλ₯Ό μ μν λ, ν¨μ μμ±κ³Ό λμμ Prototype
κ°μ²΄κ° μμ±λκ³ , μμ±λ ν¨μμ prototype
νλ‘νΌν°κ° Prototype
κ°μ²΄λ₯Ό κ°λ¦¬ν¨λ€.
μ΄ ν¨μ μμ±κ³Ό λμμ μμ±λλ Prototype
κ°μ²΄λ₯Ό λν΄νΈ νλ‘ν νμ
μ΄λΌκ³ νλ€. κ·Έλ°λ°, μ΄ λν΄νΈ νλ‘ν νμ
κ°μ²΄λ₯Ό λ€λ₯Έ μΌλ° κ°μ²΄λ‘ λ³κ²½νλ κ²μ΄ κ°λ₯νλ€.
// Person() μμ±μ ν¨μfunction Person(name) { this.name = name;}console.log(Person.prototype.constructor);
// foo κ°μ²΄ μμ±var foo = new Person('foo');console.log(foo.country);
// λν΄νΈ νλ‘ν νμ
κ°μ²΄ λ³κ²½Person.prototype = { country: 'korea',};console.log(Person.prototype.constructor);
// bar κ°μ²΄ μμ±var bar = new Person('bar');console.log(foo.country);console.log(bar.country);console.log(foo.constructor);console.log(bar.constructor);
[μΆλ ₯ κ²°κ³Ό]
κ·Έλ°λ° μ£Όμν΄μΌν μ μ΄ μλλ°, μμ±μ ν¨μμ prototype
νλ‘νΌν°λ₯Ό λ€λ₯Έ μΌλ° κ°μ²΄λ‘ λ³κ²½νλ©΄, λ³κ²½ν μ΄νμ μμ±λ κ°μ²΄λ€μ λ³κ²½λ Prototype
κ°μ²΄λ‘ [[Prototype]]
λ§ν¬λ₯Ό μ°κ²°νμ§λ§, μ΄μ μ μμ±λ κ°μ²΄λ€μ κΈ°μ‘΄ Prototype
κ°μ²΄λ‘ [[Prototype]]
λ§ν¬λ₯Ό μ μ§νλ€.
#
κ°μ²΄μ νλ‘νΌν° μ½κΈ°λ λ©μλλ₯Ό μ€νν λλ§ νλ‘ν νμ 체μ΄λμ΄ λμνλ€νλ‘ν νμ 체μ΄λμ κ°μ²΄μ νλ‘νΌν°λ₯Ό μ½μΌλ €κ³ ν λ, λ©μλλ₯Ό μ€νν λλ§ λμνκ³ λ°λλ‘ κ°μ²΄μ μλ νΉμ νλ‘νΌν°μ κ°μ μ°λ €κ³ ν λλ νλ‘ν νμ 체μ΄λμ΄ μΌμ΄λμ§ μλλ€. κ°μ²΄μ μλ νλ‘νΌν°μ κ°μ μ°λ €κ³ ν κ²½μ°μλ λμ μΌλ‘ κ°μ²΄μ νλ‘νΌν°λ₯Ό μΆκ°νκΈ° λλ¬Έμ΄λ€.
// Person() μμ±μ ν¨μfunction Person(name) { this.name = name;}
Person.prototype.country = 'Korea';
var foo = new Person('foo');var bar = new Person('bar');console.log(foo.country); // Koreaconsole.log(bar.country); // Korea
foo.country = 'USA';
console.log(foo.country); // USAconsole.log(bar.country); // Korea
foo.country
λ₯Ό 'USA'λ‘ μμ νμμ§λ§, bar.country
λ κ·Έλλ‘ 'Korea'μΈλ°, μ΄λ Person.prototype.country
κ° μμ λμ§ μμκΈ° λλ¬Έμ΄λ€.
#
μ°Έκ³ μλ£π [Javascript ] νλ‘ν νμ μ΄ν΄νκΈ°
π Javascript κΈ°μ΄ - Object prototype μ΄ν΄νκΈ°