JSON.stringify( )란 무엇인가?
JSON.stringify( )는 자바스크립트의 값을 JSON 문자열로 변환한다.
JSON이란?
JSON은 JavaScript Object Notation의 약자로, 브라우저와 서버사이에서 오고가는 데이터의 형식이다.
JSON.stringify(value, replacer, space)
value(필수): JSON 문자열로 변환할 값이다.(배열, 객체, 또는 숫자, 문자 등이 될 수 있다.)
replacer(선택): 함수 또는 배열이 될 수 있다. 이 값이 null 이거나 제공되지 않으면, 객체의 모든 속성들이 JSON 문자열 결과에 포함된다.
[함수일 때]
문자열화 프로세스의 작동을 변경하는 함수로 사용할 수 있다.
문자열화 될 key와 value, 2개의 매개변수를 받는다.
<예제>
function replacer(key, value) {
if (typeof value === ‘string’) {
return undefined;
}
return value;
}
var foo = {name: ‘jason’, nickname: ‘ball’, weight: 75};
var useJson = JSON.stringify(foo, replacer);
console.log(useJson) // {"weight":75}
JSON.stringify()에서 replacer를 함수로 사용하게 되면,
위와 같이, value(이 경우, foo)가 replacer 함수를 한번 거치고, 문자열화 된다.
[배열일 때]
배열의 값과 일치하는 값만 문자열화 된다.
<예제>
var foo = {name: ‘jason’, nickname: ‘ball’, weight: 75};
var useJson = JSON.stringify(foo, [‘nickname’, ‘weight’]);
console.log(useJson); // {“nickname”:”ball”,”weight”:75}
space(선택): 가독성을 목적으로 JSON 문자열 출력에 공백을 삽입하는 데 사용되는데,
string이나 number 객체가 될 수 있다.
이 값이 null 이거나, 제공되지 않으면 공백이 사용되지 않는다.
[string일 때]
입력한 string이 공백으로 사용된다.
var space = JSON.stringify({a: 2}, null, ‘string’);
console.log(space);
// {
// string”a”: 2
// }
[number일 때]
입력한 숫자만큼 공백이 생긴다.
var space = JSON.stringify({a: 2}, null, 5);
console.log(space);
// 5칸의 공백
// {
// “a”: 2
// }
JSON.stringify() 특성
value의 데이터 타입이 number 또는 boolean일 경우, 그 값 자체를 그대로 가져오고, 데이터타입은 string(문자열)이 된다.
JSON.stringify(7) // 7
JSON.stringify(true) // ‘true’
JSON.stringify(null) // null
value의 데이터 타입이 string일 경우, 그 값 자체가 string이 된다.
JSON.stringify(‘foo’) // “‘foo’”
value가 배열일 경우, 그 배열 자체가 string이 된다.
JSON.stringify([1, 'true', true]); // '[1,"true",true]'
value가 배열인데, 배열안에 undefined, 함수, 또는 심볼(symbol)이 있을 경우, 이런 값들은 null로 변환된다.
JSON.stringify([“a”, 7, undefined, function(){return 8}, Symbol(‘’)])
// “[“a”,7,null,null,null]”
value가 객체일 경우, 그 객체 자체가 string이 된다.
이때, 객체의 속성(property)들은 꼭 순서대로 문자열화 되지 않는다.
JSON.stringify({ x: 1, y: 2});
// '{"x":1,"y":2}' 또는 '{"y":2,"x":1}'
value가 객체인데, 객체안에 undefined, 함수, 또는 심볼(symbol)이 있을 경우, 이런 값들은 생략된다.
JSON.stringify({ a: 8, x: undefined, y: function(){return 8}, z: Symbol(‘’) });
// “{“a”:8}”
<구현해야할 문제>
JSON.stringify()와 같은 동작을 하는 함수를 구현하라.
JSON.stringify()에 들어갈 값이 숫자, 문자, boolean, 또는 null 값이 될 수도 있고,배열, 혹은 객체가 값이 될수도 있다.
단, 값이 함수이거나 undefined일 경우에는 해당이 안된다.
<알고리즘>
- 우선, 값에 들어갈 타입에 따라 나눈다.
- 값의 타입이 숫자이거나, boolean 이거나, 값 자체가 null 일 경우, 그 값 자체를 문자열화시킨다.(string의 특성 이용)
- 값이 원래 문자열일 때, 원래 문자에 있는 “ “ 값 또한 유지시킨다.
- 값이 배열일 때, 빈 배열일 경우, ‘[ ]’ 을 리턴한다.
- 빈 배열이 아니라면, for문을 사용해서 배열의 각 element(요소)의 타입을 확인후, 최종 값을 새로운 빈 배열에 추가한다.(재귀함수 사용)
- 최종 값 양쪽에 배열 괄호를 추가한다.
- 값이 객체일 때, 빈 객체일 경우, ‘{}’을 리턴한다.
- 빈 객체가 아니라면, for in문을 사용해서, 객체의 각 value의 타입을 확인후, 최종 값을 새로운 빈 배열에 추가한다.(재귀함수 사용)
- 최종 값 양쪽에 객체 괄호를 추가한다.
- 이때, 객체의 value가 함수이거나, undefined일 경우, 그 값을 제거한다.
<구현>
이제, JSON.stringify( )를 직접 구현해보자.
<1> stringifyJSON 함수에 들어갈 값의 타입이 숫자 또는 boolean, 혹은 값 자체가 null일 경우, 그 값을 문자열화 시킨다.
var stringifyJSON = function(obj) {
// typeof null 을 하게되면, object가 된다.
if(typeof obj === ‘number’ || obj === null || typeof obj === ‘boolean’) {
return ‘’ + obj;
어떤 값을 문자열화 시키기 위해서, 어떤 값에 ‘ ’를 더해주면 된다.(string의 특성)
<2> 값의 타입이 문자열일 경우, 원래 문자에 있는 “ ”를 더한다.
} else if(typeof obj === ‘string’) {
return ‘“‘ + obj + ‘“‘;
}
JSON.stringify( )에 문자열 값을 넣을 경우, 문자열 값 자체가 문자열이 되기 때문이다.
var str = “foo”;
JSON.stringify(str) // ““foo””
<3> 값이 배열일때, 배열이 빈 배열일 경우, ‘[ ]’를 리턴한다.
var bin = [];
if(Array.isArray(obj)) {
if(obj.length === 0) {
return ‘[]’;
<4> 배열이 빈 배열이 아닐 경우, for문을 사용해서 배열의 각 element(요소)의 타입을 확인후, 최종 값을 새로운 빈 배열에 추가한다.(재귀함수 사용)
} else {
for(var i = 0; i < obj.length; i++) {
if(typeof obj[i] === ‘string’) {
// obj[i]가 문자열이면, stringifyJSON 함수를 다시 돌려, 원래 문자에 ""를 더한다.
var str = stringifyJSON(obj[i]);
bin.push(str);
} else if(Array.isArray(obj[i])) {
var arr = stringifyJSON(obj[i]);
bin.push(arr);
} else if(typeof obj[i] === ‘number’) {
bin.push(obj[i]);
} else {
var ifObj = stringifyJSON(obj[i]);
bin.push(ifObj);
}
}
// 최종 값 양쪽에 배열 괄호를 추가한다.
// bin 자체는 배열이기 때문에, 그 배열을 문자열화 시키기 위해,
// 양쪽에 배열 괄호를 더해서, 모양은 배열 모양이지만, 타입은 문자열이 된다.
return ‘[‘ + bin + ‘]’;
}
<5> 값이 객체일때, 객체가 빈 객체일 경우, ‘{}’을 리턴한다.
var createdArr = [];
// object의 length를 확인하기 위해, Object.keys(obj).length를 사용한다.
if(Object.keys(obj).length === 0) {
return ‘{}’;
<6> 객체가 빈 객체가 아닐경우, for in문을 사용해서, 객체의 각 value의 타입을 확인후, 최종 값을 새로운 빈 배열에 추가한다.(재귀함수 사용)
} else {
for(var key in obj) {
if(typeof obj[key] === ‘string’ || typeof obj[key] === ‘boolean’ || obj[key] === null) {
var strKey = stringifyJSON(key);
var strVal = stringifyJSON(obj[key]);
// key와 value(=obj[key])를 재귀함수로 돌려, 문자열화 시킨다.
// 그 후, 원래 객체 안의 내용들(':' 같은 것들)또한 추가시킨다.
var strArr = strKey + ‘:’ + strVal;
createdArr.push(strArr);
} else if(Array.isArray(obj[key])) {
var arrKey = stringifyJSON(key);
var arrVal = stringifyJSON(obj[key]);
var arrArr = arrKey + ‘:’ + arrVal;
createdArr.push(arrArr);
// 객체의 값이 함수이거나, undefined일 경우, 그 객체의 값을 제거한다.
} else if(typeof obj[key] === ‘function’ || obj[key] === undefined) {
delete obj[key];
stringifyJSON(obj);
} else {
var objKey = stringifyJSON(key);
var objVal = stringifyJSON(obj[key]);
var objObj = objKey + ‘:’ + objVal;
createdArr.push(objObj);
}
}
}
// 최종 값 양쪽에 객체 괄호를 추가한다.
// createdArr 자체는 배열이기 때문에, 그 배열을 문자열화 시키고,
// 모양은 객체로 만들어야 하기 때문에,
// 양쪽에 객체 괄호를 더해서, 모양은 객체 모양이지만, 타입은 문자열이 된다.
return ‘{‘ + createdArr + ‘}’;
}
};
<소스코드>
var stringifyJSON = function(obj) {
// 재귀함수로 사용하기 위해 반복되는 데이터 타입 확인
if(typeof obj === ‘number’ || obj === null || typeof obj === ‘boolean’) {
return ‘’ + obj;
} else if(typeof obj === ‘string’) {
return ‘“‘ + obj + ‘“‘;
}
var bin = [];
if(Array.isArray(obj)) {
if(obj.length === 0) {
return ‘[]’;
} else {
for(var i = 0; i < obj.length; i++) {
if(typeof obj[i] === ‘string’) {
var str = stringifyJSON(obj[i]);
bin.push(str);
} else if(Array.isArray(obj[i])) {
var arr = stringifyJSON(obj[i]);
bin.push(arr);
} else if(typeof obj[i] === ‘number’) {
bin.push(obj[i]);
} else {
var ifObj = stringifyJSON(obj[i]);
bin.push(ifObj);
}
}
return ‘[‘ + bin + ‘]’;
}
} else {
var createdArr = [];
if(Object.keys(obj).length === 0) {
return ‘{}’;
} else {
for(var key in obj) {
if(typeof obj[key] === ‘string’ || typeof obj[key] === ‘boolean’ || obj[key] === null) {
var strKey = stringifyJSON(key);
var strVal = stringifyJSON(obj[key]);
var strArr = strKey + ‘:’ + strVal;
createdArr.push(strArr);
} else if(Array.isArray(obj[key])) {
var arrKey = stringifyJSON(key);
var arrVal = stringifyJSON(obj[key]);
var arrArr = arrKey + ‘:’ + arrVal;
createdArr.push(arrArr);
} else if(typeof obj[key] === ‘function’ || obj[key] === undefined) {
delete obj[key];
stringifyJSON(obj);
} else {
var objKey = stringifyJSON(key);
var objVal = stringifyJSON(obj[key]);
var objObj = objKey + ‘:’ + objVal;
createdArr.push(objObj);
}
}
}
return ‘{‘ + createdArr + ‘}’;
}
};
// 위 'stringifyJSON' 함수를 아래와 같은 값으로 확인해 볼 수 있다.
// console.log(stringifyJSON([8, “hi”]));
// console.log(stringifyJSON({“a”:[],”c”: {}, “b”: true}));
// console.log(stringifyJSON([{“a”:”b”}, {“c”:”d”}]));
// console.log(stringifyJSON({‘functions’: function(){},’undefined’: undefined}));
위 소스코드는 배열 또는 객체 안에 element들의 데이터 타입을 반복적으로 확인하기 위해 재귀함수를 사용했다.
어떤 데이터 타입이든 문자열화 시키기 위해, 어떤 값에 ‘ ’를 더해줘 문자열화 시켰다.
이를 바탕으로 재귀함수를 활용하여, 반복적으로 데이터 타입을 확인후, 최종적으로 원래 값 자체에 데이터 타입만 문자열화 시킨 값을 리턴할 수 있는, 즉 JSON.stringify()와 같은 함수를 구현했다.
무의식적으로 사용하는 api인데 이런 시도와 과정은 흥미롭네요. javascript의 api들이 브라우저별로 구현이 다른게 있던데 json api도 이런식인지 궁금해지네요? ㅎㅎ
안녕하세요! 리스팀 감사드립니다! 현재 javascript를 기본으로 개발 공부를 이제 막 시작했고, 개발자로 준비하는 과정인데, 제가 공부한 것을 기억하고, 다른 개발자분들한테도 도움이 되었으면 생각하기 때문에, 하나씩 포스팅 하고 있습니다! 아직 공부할 게 많지만, 스팀잇을 통해 서로 소통하고, 배웠으면 합니다! 이건 recursion을 공부하다가, json.stringify()를 공부하면서, 이것을 recursion을 이용해서 직접 구현을 해본 것입니다 ㅎㅎ
오.. @nhj12311 님 링크따라서 왔는데..
제목만 봤을땐.. 이거 글양이 얼마나 되겠나 싶었는데
엄청난 내용들이군요 ㅎㅎ 지금은 대충 봤지만 나중에 좀더 자세히 봐야겠습니다~
감사합니다! 공부하다가 조금 더 자세히 알고 싶어서, 정리해 보았습니다. 팔로우 하겠습니다!
오 정리 잘해놓으셨네요 잘 보고 갑니다.
감사합니다! 해외에 계신가요? 팔로우하겠습니다!
JSON.stringify() 이렇게 자세하게는 본적이 없는데 포스팅 잘 봤습니다
감사합니다! 혹시 개발자이신가요? 팔로우 하겠습니다!
Congratulations @cheonmr! You have completed some achievement on Steemit and have been rewarded with new badge(s) :
Award for the number of comments
Click on any badge to view your own Board of Honor on SteemitBoard.
For more information about SteemitBoard, click here
If you no longer want to receive notifications, reply to this comment with the word
STOP