개발자를 했다면 JSON이라는 것은 누구나 다 들어봤을 것이라고 생각한다. JavaScript Object Notation, 즉 자바스크립트 객체 표기법이다. key-value 형식으로 된 객체를 표현한다.
시작은 {}로 시작하며, key를 추가하는 방법은 두 가지가 있다. key는 무조건 문자열 타입이다. Property (속성)라고도 한다.
const obj = {};
로 시작하겠다.
obj.aa = 3;
obj.3 = 5;
과 같이 사용할 수 없다는 것을 의미한다.obj['aa'] = 3;
obj[3]=5;
{'aa': 3, '3':5}
3은 정수로 입력되었지만 객체의 key값으로 들어가면서 문자열로 변환되었다. 모든 key값은 문자열이다.
나는 내부 데이터를 관리할 목적으로 Object를 활용하기 시작했다. 외부 데이터베이스를 쓰자니 네트워크 통신을 해야하고, 또 실시간으로 업데이트되고 삭제되는 데이터다보니 굳이 데이터베이스 체계를 사용하고 싶지 않았다. 프로그램 내 모든 내부 데이터를 Object로 관리하기로 결정했다.
Oject는 데이터베이스로 사용될 수 있다. 다만 빅데이터를 처리하기엔 큰 무리가 있을 것이다. 주 메모리에 적재되기 때문이다. 따라서 나의 경우와 같이 약 10MB~20MB 정도의 데이터만 사용할 것 같으면 Object를 사용하는데 큰 지장이 없을 것이다. 시간 복잡도의 경우 자세한 계산은 해보지 않았으나, 역시 이 부분에도 수지타산이 맞다. 20MB정도의 데이터라고 하면 8바이트 정수가 2,621,440개 밖에 안된다. O(n) 시간복잡도라고 해도 최신의 컴퓨터라면 빠르게 처리가 가능하다. 또 많은 수의 사용자를 예상하고 있지 않으므로, 진행하기로 했다.
데이터베이스에는 CRUD가 필요하다. 다음과 같이 치환된다.
const db = {data:{}};
db.data[key]
db.data[key] = updateval;
delete db.data[key];
일반적인 Object 사용이다. 다만 CREATE에서 Object 최상단에 data를 넣고 그 다음 그 안에서 활동하는 모습을 볼 수가 있다. 문제가 생겼기 때문이다.
현재 나는 Node.js 기반 express 프레임워크로 백엔드 서버 스크립트를 작성 중에 있다. 이 때 많은 사람들이 파일을 나눠서 기능들을 모듈화한다. 나도 마찬가지였다.
모듈화 시 사용되는 문은 다음과 같다.
변수 하나만을 export한 경우, 보통 아래와 같이 import 한다.
const somethingVar = require('asdf.js');
Object를 export한 경우, 구조 분해 할당 문법을 이용하여 각각을 따로 불러올 수 있다.
example:
module.exports = {abc,def,ghi}; // in asdf.js
const {abc,def} = require('asdf.js'); // in 'req.js'
이렇게 export된 변수나 객체는 require로 import되었을 때, reference로 참조가 된다. 즉, 위 예시에서 req.js 에서 abc 변수를 변경한다고 하자. 그러면 asdf.js에서 export했던 변수의 값이 바뀌는 것이다.
문제는 객체를 export했을 경우이다. 아래는 그 예시이다.
asdf.js
var obj = {
'a':3,
'b':5,
'c':6
};
function displayObj(){
console.log(obj);
}
function mergeObj(tobj){
obj = {...obj,...tobj};
}
module.exports = {obj,mergeObj,displayObj};
req.js
var {obj,displayObj} = require('asdf.js');
function clearObj(){
obj = {};
}
clearObj();
displayObj();
mergeObj({'d':9});
displayObj();
console.log(obj);
node로 req.js를 실행시켜 본 결과는 아래와 같다...
require()는 import할 때 reference를 가져온다고 했다. 이 점을 이용해서 해석을 해보자.
파일마다 각자의 메모리 공간이 있는 듯 보인다. 따라서 consistency, 일관성을 유지하기 위해서 다음과 같이 진행했다.
아예 obj 객체를 건들지 말고, obj 객체 내부에 있는 property를 건드는 것이다. 이렇게 하면 모든 모듈이 똑같은 객체를 참조하게 된다. 우리는 각 js 파일에 여러 개의 객체를 만들면 안된다. Singleton하게 객체를 다뤄야 한다. 데이터베이스로 이용할 것이기 때문이다.
{
'data':{}
}
위와 같이 객체를 선언한다면, data property만 바꿔주면 된다. 값을 초기화하고 싶은가? obj.data={};
로 초기화하면 된다. 이는 허용된다. obj={};
는 절대 허용되지 않는다.
Node에 대한 철저한 공부가 부족했기 때문에 이런 일이 발생한 것 같다. 그냥 완전히 전역변수처럼 사용될 줄 알았는 데, 그렇지 않았다. 사실 이제 와서 보니 당연한 것 같기도 하다...
역시 철저한 준비태세가 중요하다.
~完~