본문 바로가기

개발(차근차근 기초)/Javascript

[Javascript] JSON

JSON

Javascript Object Notation (자바스크립트 객체 표기법)

자바스크립트에서 복합적인 데이터 구조를 속성이름(key)과 값(value)의 쌍으로 구성하는 표현 방법.

다른 프로그래밍 언어의 Map 혹은 Dictionary 구조와 대응된다.

#01. 단순히 정보만을 표현하는 경우

key 이름을 지정하고 콜론(;)으로 구분지은 후 값을 명시한다.

두 개 이상의 데이터는 콤마(,)로 구분한다.

원칙적으로 key 이름은 따옴표로 감싸는 것이 맞지만 key 이름에 띄어쓰기나 대시(-)가 없는 경우는 따옴표 처리를 생략해도 무관하다.

1) JSON 정의

하나의 변수에 하위 정보들이 포함되어 있는 변수들의 그룹으로 이해할 수 있다.

이를 객체라고 한다.

객체 라는 형태가 갖는 다양한 패턴 중 하나.

var student = {
    "studno" : 10101,
    "grade": 1,
    "name": "학생1",
    "phoneno": "010-1231-2342"
};

정의한 데이터에 접근하기

객체이름과 속성(key)이름을 점(.)으로 구분하여 명시
console.log("학번: %d", student.studno);
console.log("학년: %d", student.grade);
console.log("이름: %s", student.name);
console.log("연락처: %s", student.phoneno);
학번: 10101
학년: 1
이름: 학생1
연락처: 010-1231-2342
이름표를 갖는 배열처럼 접근하기
console.log("학번: %d", student['studno']);
console.log("학년: %d", student['grade']);
console.log("이름: %s", student['name']);
console.log("연락처: %s", student['phoneno']);
학번: 10101
학년: 1
이름: 학생1
연락처: 010-1231-2342

2) 배열을 포함하는 JSON

key에 대응되는 값이 배열로 구성된 복합적 정보 구조 형태

var company = {
    name : "(주)굿모닝컴페니",
    since : 2013,
    department : ["기획팀", "디자인팀", "개발팀"]
};

// JSON 데이터에 접근하는 방법(점으로 연결 혹은 배열처럼 접근)
// 점을 통한 접근을 권장.
console.log(company.name);             // 점으로 접근
console.log(company['since']);         // 배열처럼 접근
console.log(company.department[0]);    // 점으로 접근
console.log(company.department[1]);    // 점으로 접근
console.log(company['department'][2]); // 배열처럼 접근
(주)굿모닝컴페니
2013
기획팀
디자인팀
개발팀

3) 계층 구조

JSON 표기법의 장점은 복잡한 정보 구조를 계층화 하여 표현할 수 있다는 것이다.

다른 JSON 객체를 value로 포함하는 경우

/** 단일 형태의 JSON */

var centerPoint = {
    x: 5, // x좌표
    y:10 // y좌표
};

var circle = {
    center: centerPoint, // 중심의 좌표
    radius:5.10 // 반지름
}

console.log("원의 중점: (%d, %d)", circle.center.x, circle.center.y);
console.log("원의 반지름: %d", circle.radius);
원의 중점: (5, 10)
원의 반지름: 5.1

계층적으로 정의된 경우

단일 형태의 JSON 구조를 별도로 참조하는 것이 아니라 직접 정의하는 패턴

/** 계층형 JSON */
var circle = {
    center: {
    x: 5, // x좌표
    y:10 // y좌표
}, // 중심의 좌표
    radius:5.10 // 반지름
}

console.log("원의 중점: (%d, %d)", circle.center.x, circle.center.y);
console.log("원의 반지름: %d", circle.radius);
원의 중점: (5, 10)
원의 반지름: 5.1

4) 목록 구조

JSON의 value가 배열로 정의되어 있으면서, 각 배열의 원소가 또 다른 JSON 형식인 경우

자료구조 정의

var student1 = {
    studno: 10101,
    grade:1,
    name:"학생1"
};

var student2 = {
    studno : 20202,
    grade: 2,
    name: "학생2"
};

var classRoom = {
    student:[student1, student2]
}

console.log(classRoom);
{
  student: [
    { studno: 10101, grade: 1, name: '학생1' },
    { studno: 20202, grade: 2, name: '학생2' }
  ]
}

데이터 접근

배열의 기본 특성을 활용하여 반복문으로 데이터에 접근할 수 있다.

for(var i = 0; i< classRoom.student.length ; i++){
    console.log("[%d번째 학생]", i+1);
    console.log(" >> 학번 : %d", classRoom.student[i].studno);
    console.log(" >> 학년 : %d", classRoom.student[i].grade);
    console.log(" >> 이름 : %s", classRoom.student[i].name);    
}
[1번째 학생]
 >> 학번 : 10101
 >> 학년 : 1
 >> 이름 : 학생1
[2번째 학생]
 >> 학번 : 20202
 >> 학년 : 2
 >> 이름 : 학생2

배열의 원소로서 JSON 구조를 직접 명시하기

var classRoom = {
    student: [{
        studno:10101,
        grade:1,
        name:"학생1"        
    }, {
        studno:20202,
        grade:2,
        name:"학생2"
    }]
};
for(var i = 0; i< classRoom.student.length ; i++){
    console.log("[%d번째 학생]", i+1);
    console.log(" >> 학번 : %d", classRoom.student[i].studno);
    console.log(" >> 학년 : %d", classRoom.student[i].grade);
    console.log(" >> 이름 : %s", classRoom.student[i].name);    
}
[1번째 학생]
 >> 학번 : 10101
 >> 학년 : 1
 >> 이름 : 학생1
[2번째 학생]
 >> 학번 : 20202
 >> 학년 : 2
 >> 이름 : 학생2

5) 복합적 구조

가장 일반적인 형태의 JSON 구조

var bbs = {
    title: "게시판",
    count: 4,
    item: [
        {id: 1, subject: '첫번째 게시물 제목'},
        {id: 2, subject: '두번째 게시물 제목'},
        {id: 3, subject: '세번째 게시물 제목'},
        {id: 4, subject: '네번째 게시물 제목'}
    ]
};

console.log("[%s]", bbs.title);
console.log("총 게시물 수: %d", bbs.count);

for(var i=0; i<bbs.item.length;i++){
    console.log("[%d] %s", bbs.item[i].id, bbs.item[i].subject);
}
[게시판]
총 게시물 수: 4
[1] 첫번째 게시물 제목
[2] 두번째 게시물 제목
[3] 세번째 게시물 제목
[4] 네번째 게시물 제목

6) JSON 구조의 확장

존재하지 않는 key를 사용하는 경우

JSON은 존재하지 않는 key에 대해 출력하거나 다른 변수에 대입 혹은 연산에 활용할 경우 undefined로 처리된다.

var foo = {
    name : "자바스크립트",
    age : 19
}

//존재하지 않는 값에 대한 출력 --> undefined
console.log(foo.email);

//존재하지 않는 값을 활용한 연산 (age를 aga로 오타가 났다고 가정)
// --> undefined +1 --> 숫자가 아님
var nextAge = foo.aga +1;

//연산을 수행할 수 없으므로 연산 결과는 NaN(Not a Number)라는 특수값이 도니다.
console.log(nextAge);
undefined
NaN

존재하지 않는 key에 대한 대입

그 즉시 객체가 확장된다.

var bar = {
    name:"자바스크립트",
    age:19    
};

bar.email = "javascript@helloworld.com";
console.log(bar);
{ name: '자바스크립트', age: 19, email: 'javascript@helloworld.com' }

빈 객체에 대한 확장

점으로 접근하는 경우 key 이름을 변수로 처리할 수 없지만, 배열처럼 접근하는 경우 key 이름을 변수로 처리하는 것이 가능하다.

var myJson = {};

for(var i=0; i<10;i++){
    var key = "value" +i;
    myJson[key] = i+100;
}
console.log(myJson);
{
  value0: 100,
  value1: 101,
  value2: 102,
  value3: 103,
  value4: 104,
  value5: 105,
  value6: 106,
  value7: 107,
  value8: 108,
  value9: 109
}

#02. 기능적인 부분을 포함하는 경우

프로그래밍에서 말하는 객체를 쉽게 이해하기 위해서는 같은 목적 혹은 같은 대상을 위한 변수와 함수들을 그룹화 한 형태로 정의할 수 있다.

JSON의 value는 일반 변수와 같은 개념이므로 값 대신 익명 함수를 배치하여 객체의 기능적인 부분을 담당하는 함수를 포함할 수 있다.

이렇게 정의된 객체는 프로그램 전역에서 독립적으로 유일한 존재가 되는데 이를 싱글톤 객체라고 부른다.

1) 함수들로만 구성된 JSON

익명 함수 구성 패턴

var calcObj1 = {
    plus: function(x,y){
        return x+y;
    },
    minus: function(x,y){
        return x-y;
    },
    times: function(x,y){
        return x*y;
    },
    div:function(x,y){
        return x/y;
    }
}

console.log(calcObj.plus(10,20));
console.log(calcObj.minus(50,30));
console.log(calcObj.times(10,20));
console.log(calcObj.div(4,2));
30
20
200
2

화살표 함수 구성 패턴

function 키워드가 제거되고 소괄호 ()와 중괄호 {} 사이에 화살표가 표시된다.

프로그램 구문이 리턴을 위한 한 라인만 존재할 경우 중괄호와 return 키워드는 생략할 수 있다.

var calcObj2 = {
    plus: (x,y)=>x+y,
    minus: (x,y)=>x-y,
    times: (x,y)=> x*y,
    div:(x,y)=> x/y
};

console.log(calcObj.plus(10,20));
console.log(calcObj.minus(50,30));
console.log(calcObj.times(10,20));
console.log(calcObj.div(4,2));
30
20
200
2

2) 변수와 함수가 공존하는 패턴

객체에 포함되어 있는 변수들을 속성(property) 혹은 멤버변수라고 부른다.

익명함수를 메서드로 포함하는 경우

같은 객체에 포함되어 있는 자원(변수,함수)에 서로 접근하기 위해서는 예약어 this를 통해야 한다.

var calcObj3 = {
    x:0,
    y:0,
    plus: function(){return this.x + this.y},
    minus: function(){return this.x - this.y},
    foo: function(){return this.plus() + this.minus()}
}
calcObj3.x = 100;
calcObj3.y = 30;
console.log(calcObj3.plus());
console.log(calcObj3.minus());
console.log(calcObj3.foo());
130
70
200

화살표 함수를 메서드로 포함하는 경우

같은 객체에 포함되어 있는 자원(변수, 함수)에 서로 접근하기 위해서는 객체 이름을 통해야 한다.

var calcObj4 = {
    x:0,
    y:0,
    plus:() => calcObj3.x+calcObj3.y,
    minus:() => calcObj3.x-calcObj3.y,
    foo:() => calcObj3.plus()*calcObj3.minus()
}
calcObj3.x = 100;
calcObj3.y = 30;
console.log(calcObj4.plus());
console.log(calcObj4.minus());
console.log(calcObj4.foo());
130
70
9100

3) getter, setter

객체에 포함된 멤버변수에 직접적으로 접근하는 것은 프로그래밍 보안에 취약점을 갖고 있기 때문에 멤버변수에 간접적으로 접근할 수 있는 함수를 정의하는 형식

  • getter : 파라미터로 전달받은 값을 멤버변수에 복사한다. 이 과정에서 필요한 경우 값을 가공하거나 값의 유효성을 검사할 수 있다.
  • setter : 멤버변수를 리턴한다. 이 과정에서 필요한 경우 값을 가공하여 리턴할 수 있다.
var user = {
     _id:null, // 임의로 값을 비워둔 형식(null)의 멤버변수 정의
    get id(){ // 멤버변수 _id에 대한 getter 함수 정의
        return this._id;
    },
    set id(value){ // 멤버변수 _id에 대한 setter 함수 정의
        if(!value){
            console.log("아이디를 입력하세요.");
            return
        }

        this._id = value;
    },
    login: function(){
        console.log("안녕하세요. " +this.id + "님");
    }

}

user.id=""; // setter 호출
console.log(user.id); // getter를 호출하여 리턴값을 화면에 출력

user.id = "helloworld"; // setter 호출
console.log(user.id); // getter를 호출하여 리턴값을 화면에 출력

user.login();
아이디를 입력하세요.
null
helloworld
안녕하세요. helloworld님
var user = {
     _id:null, // 임의로 값을 비워둔 형식(null)의 멤버변수 정의
    get id(){ // 멤버변수 _id에 대한 getter 함수 정의
        return this._id;
    },
    set id(value){ // 멤버변수 _id에 대한 setter 함수 정의
        if(!value){
            console.log("아이디를 입력하세요.");
            return
        }

        this._id = value;
    },
    login: function(){
        console.log("안녕하세요. " +this.id + "님");
    }

}

user.id=""; // setter 호출
console.log(user.id); // getter를 호출하여 리턴값을 화면에 출력

user.id = "helloworld"; // setter 호출
console.log(user.id); // getter를 호출하여 리턴값을 화면에 출력

user.login();
아이디를 입력하세요.
null
helloworld
안녕하세요. helloworld님