-
[node.js] 프로토 타입(prototype)node.js(노드) 2020. 8. 11. 14:05
이번 시간에는 프로토타입에 대해 알아보자.
자바 개발자로 취업했던 나에게는 JAVA에서의 class와 비슷한 기능처럼 사용하기 때문에(물론 자세히 보면 다름)
이해하는데 어렵지는 않았다 다만 변수 안에 생성자를 넣고 함수를 넣고 밖에서 선언하는 것은 정말 신세계였다.
마치 한국말처럼?
와 진짜 이거 어렵다.진짜 와 이거 어렵다.이거 와 진짜 어렵다.와 이거 진짜 어렵다.이번 글에는 프로토타입을 클래스의 상속처럼 사용하는 것과 실제 현업에서 사용한 방식을 쓰겠다.
1. 프로토 타입 상속
function Animal(name) { this.name = name; } Animal.prototype.lag = '4'; Animal.prototype.gender = "male"; var cat = new Animal('고양이'); var dog = new Animal('강아지'); console.log(cat.gender); //'male' console.log(dog.gender); //'male' cat.gender = 'female'; console.log(cat.gender); // 'female' console.log(dog.gender); // 'male'
간단하게 보면 Animal이라는 생성자를 만들고 그 후 프로토 타입으로 lag와 gender를 프로토타입으로 생성
그리고 생성자 Animal을 불러오면 프로토 타입으로 설정된 gender도 같이 불러옵니다.
그 후 cat의 gender을 female로 바꿔주고 불러오면 끝~
이라고 생각하셨겠지만 그렇게 생각하면 큰 오산이다.
안에 있는 값들을 살펴보자
dog 변수
dog 안에 있는 값들 cat 변수
cat 안에 있는 값들 우선 dog를 살펴보자
생성자로 선언했던 name말고 프로토 타입으로 넣은 __proto__의 값 안에 lag와 gender가 들어있다.
dog 객체가 gender를 직접적으로 가지고 있지 않기 때문에 gender속성을 찾을 때까지 상위 프로토타입을 탐색한다. 그리고 최상위 프로토타입까지 찾았는데도 없을 경우 undefined를 리턴한다.
이렇게 __proto__속성을 통해 상위 프로토타입과 연결되어있는 형태를 프로토타입 체인(Chain)이라고 한다.
chain관계 생성자를 가진 객체는 체인관계로 묶여있지만 cat객체처럼 직접적으로 해당 객체가 gender를 가지고 있으면 그 gender값을 먼저 내보내게 된다.
가장 중요한건 __proto__의 프로토타입들은 "공유" 된다는 것이다.
만약에 생성자 선언 후에 prototype을 바꾸면 어떻게 될까?
function Animal(name) { this.name = name; } Animal.prototype.lag = '4'; Animal.prototype.gender = "male"; var cat = new Animal('고양이'); var dog = new Animal('강아지'); console.log(cat.gender); //'male' console.log(dog.gender); //'male' Animal.prototype.gender = "Unknown" console.log(cat.gender); //'Unknown' console.log(dog.gender); //'Unknown' cat.gender = 'female'; console.log(cat.gender); // 'female' console.log(dog.gender); // 'Unknown'
생성자 후에 프로토 타입을 바꾸더라도 체인(Chain)으로 연결되어있기 때문에 객체들도 변하게 된다.
그렇기 때문에 프로토타입은 최초로 설정 후에 다른 곳에서라도 해당 프로토타입의 값을 바꾸게 되면 해당 프로토타입을 사용하는 객체들은 모두 영향을 받게 된다.
그러니 바꿀 때에는 조심히 바꿔야 한다.
2. 실제 현업에서 사용하는 방법
프로토타입을 객체로 사용하는 방법도 있지만 미리 선언하는 방법도 있다.
추후에 글을 쓰겠지만 예를 들면 mysql이 여러 개인 경우 미리 선언하거나 소켓통신을 미리 선언하는 방법이 있다.
자바스크립트의 가장 큰 특징이 변수에 함수를 넣는다는 것 기억나는가? 프로토타입도 동일하다 프로토타입에 값이 아닌 함수도 넣을 수 있다. 그래서 함수를 선언하고 추후에 해당 프로토타입을 불러오면 해당 함수를 사용할 수 있게 된다.
한꺼번에 여러 가지 세팅을 프로토타입으로 선언
(mysql.js)
const mysql = require('mysql'); function CMysql(){ this.W_DB = null; this.R_DB = null; } CMysql.prototype.create = function(){ this.W_DB = mysql.createPool(config.MYSQL_W_DB); this.R_DB = mysql.createPool(config.MYSQL_R_DB); } CMysql.prototype.on_error = function(){ this.W_DB.on('error',(err)=>{ console.log('W_DB..error >> '+err); }); this.R_DB.on('error',(err)=>{ console.log('R_DB..error >> '+err); }); } CMysql.prototype.connection = function(){ this.W_DB.on('connection',(err)=>{ console.log('W_DB..error >> '+err); }); this.R_DB.on('connection',(err)=>{ console.log('R_DB..error >> '+err); }); } CMysql.prototype.enqueue = function(){ this.W_DB.on('enqueue',(err)=>{ console.log('mysql_log_w..enqueue..error : '+err); }); this.R_DB.on('enqueue',(err)=>{ console.log('mysql_log_r..enqueue..error : '+err); }); } CMysql.prototype.getLogWrite = function(){ return this.W_DB; } CMysql.prototype.getLogRead = function(){ return this.R_DB; } let g_mysql = new CMysql(); module.exports = g_mysql;
선언된 프로토타입을 필요한 곳에 사용
const mysql = require('../src/mysql'); var start = function (){ mysql.create(); mysql.connection(); mysql.enqueue(); mysql.error(); mysql.getLogRead().getConnection((err,con)=>{ } }
이런 식으로 해당 선언이 필요할 때 프로토타입을 불러서 사용할 수 있고 객체로도 사용할 수 있게 된다.
출처 및 참조 : https://medium.com/@bluesh55/javascript-prototype-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0-f8e67c286b67
'node.js(노드)' 카테고리의 다른 글
[Node.js] NULL, undefined가 나왔을때 의심해볼만한곳 정리(계속 업데이트) (0) 2020.08.18 [Node.js] 이벤트처리 'EventEmitter' 사용방법 (0) 2020.08.11 [node.js] 동기와 비동기(2) Callback과 async의Waterfall (0) 2020.08.10 [node.js] 동기와 비동기 (1) 기본 이해 (0) 2020.08.07 [node.js] 콜백(callback)함수(2) (0) 2020.08.01