-
자바스크립트 프로토타입 PrototypeProgramming/Javascript 2020. 3. 22. 18:42반응형
Prototype
정재남 님의 인프런 강좌, JS FLOW를 참고하였습니다.
prototype,constructor,__proto__prototype,constructor,__proto__Constructor.prototype 과 instance.proto가 같은 객체를 바라본다.
생성자 함수를 new 연산자를 이용해 instance를 만들면, 그 인스턴스에는 Constructor의 prototype이라는 프로퍼티의 내용이,
instance.__proto__로 참조되어 전달된다.근데 이때
__proto__는 생략이 가능해서, instance가 Constructor의 내용 뿐만 아니라 Constructor.prototype의 내용(메소드 등)을 사용할 수 있다.console.dir([1, 2, 3].constructor); console.dir([1, 2, 3].__proto__.constructor);위의 결과는 Array로 같다.
function Person(n, a) { this.name = n; this.age = a; } var gomu = new Person("고무곰", 30); var gomuC1 = new gomu.__proto__.constructor("고무곰_클론1", 10); var gomuC2 = new gomu.constructor("고무곰_클론2", 25); var gomuProto = Object.getPrototypeOf(gomu); var gomuC3 = new gomuProto.constructor("고무곰_클론3", 20); var gomuC4 = new Person.prototype.constructor("고무곰_클론4", 15);Constructor.prototypeinstance.__proto__instanceObject.getPrototypeOf(instance)위 네 가지로 생성자 함수의 prototype에 접근이 가능하다.
ConstructorConstructor.prototype.constructorinstance.__proto__.constructorinstance.constructorObject.getPrototypeOf(instance).constructor으로 생성자 함수에 접근 가능하다.
instance에서 생성자 함수로 직접 접근은 불가하다. prototype을 거쳐서 갈 수 있다.
function Person(n, a) { this.name = n; this.age = a; } var liam = new Person("리암", 50); var noel = new Person("노엘", 54); liam.setOlder = () => { this.age += 1; }; liam.getAge = function () { return this.age; }; noel.setOlder = function () { this.age += 1; } noel.getAge = function () { return this.age; };위 함수에서 setOlder와 getAge가 반복된다.
function Person(n, a) { this.name = n; this.age = a; } Person.prototype.setOlder = function () { this.age += 1; } Person.prototype.getAge = function () { console.log(this); return this.age; } var liam = new Person("리암", 50); var noel = new Person("노엘", 54);이렇게 바꿔주면 instance는 constructor의 prototype에 접근할 수 있으므로 sm, noel 모두 사용 가능해진다.
인스턴스가 직접 달고 있을 필요가 없는 메소드들을 prototype에 올려버린 것
function Person(n, a) { this.name = n; this.age = a; } Person.prototype.setOlder = function () { this.age += 1; } Person.prototype.getAge = function () { return this.age; } var liam = new Person("리암", 50); var noel = new Person("노엘", 54); Person.prototype.age = 100; liam.setOlder(); // this === liam. (Person의 인스턴스) liam.getAge(); // 51 liam.__proto__.setOlder(); // this === liam.__proto__ (Person.prototype의 인스턴스) liam.__proto__.getAge(); // 101하지만 Person의 인스턴스가 prototype의 프로퍼티들을 사용할 수 있다고 해서 this까지 같아지는 것은 아니다.
__proto__가 엄연히 살아있기 때문이다.6-3) Prototype Chaining
console.dir([1,2,3]);해보면
Array안에__proto__안에 또__proto__가 있는 것을 확인할 수 있다. 첫번째는 Array.prototype이고 두 번째는 Object.prototype 이다.Array든 Number든 String이든 Boolean이든
__proto__를 두 번만 거치면Object.prototype과 만난다. 즉, 자바스크립트 내 모든 데이터 타입은 Object.prototype의 프로퍼티를 사용할 수 있다.또한 각자의 prototype, 즉 Array.prototype이나 String.prototype에 별도의 메소드를 지정하여 Array만 사용 가능한 메소드, String만 사용 가능한 메소드를 만들 수 있다.
그런데,
{a:1, b:2}와 같은 객체는 중간에 prototype이 존재하지 않는다.__proto__오직 한 번만 사용할 수 있고 Object.prototype에 프로퍼티를 추가하면 객체만 사용 가능한 것이 아니라 모든 타입의 데이터들이 사용 가능해진다.그래서
Object.create()와 같이 생성자 함수에 속한 메소드가 많다.var arr = [1, 2, 3]; console.log(arr.toString()); // 1,2,3toString()는Object.prototype의 메소드이지만array도 사용할 수 있다.var arr = [1, 2, 3]; var num = 123; arr.toString = function () { return this.join("_"); } console.log(arr.toString()); // 1_2_3 console.log(arr.__proto__.toString.call(arr)); // 1,2,3 console.log(num.toString()); // "123" console.log(arr.__proto__.__proto__.toString.call(arr)); // [Object Array]인스턴스에 새로운 메소드를 직접 만들어버리면
__proto__체이닝을 하지 않고 직접 만든 메소드를 사용한다.그래서
arr.__proto__와num에는 새로 만든 메소드가 적용되지 않는다.var arr = [1, 2, 3]; var num = 123; Array.prototype.toString = function () { return this.join("_"); } console.log(arr.toString()); // 1_2_3 this console.log(arr.__proto__.toString.call(arr)); // 1_2_3 console.log(num.toString()); // "123" console.log(arr.__proto__.__proto__.toString.call(arr)); // [Object Array]배열에는 모두 적용이 되지만 여전히 num에는 적용되지 않는다.
Array.prototype에 속한 메소드로 Array만 사용 가능하다.
반응형'Programming > Javascript' 카테고리의 다른 글
자바스크립트 string, number 간단하게 형변환하기 (0) 2020.04.01 자바스크립트 프로토 타입으로 클래스 구현하기 (0) 2020.03.22 자바스크립트 클로저. Closure (0) 2020.03.22 자바스크립트 콜백함수 Callback Function (0) 2020.03.22 자바스크립트 THIS 일반 함수와 화살표 함수의 차이 (0) 2020.03.22