호쌤
호쌤 Just For Fun

[JS] JSON

크리에이티브 커먼즈 라이선스 ITPAPER(호쌤,쭈쌤)에 의해 작성된 ≪[JS] JSON≫은(는) 크리에이티브 커먼즈 저작자표시-비영리-동일조건변경허락 4.0 국제 라이선스에 따라 이용할 수 있습니다.
이 라이선스의 범위 이외의 이용허락을 얻기 위해서는 leekh4232@gmail.com으로 문의하십시오.

[JS] JSON

Javascript Object Notation (자바스크립트 객체 표기법)은 자바스크립트에서 복합적인 데이터 구조를 속성이름(key)과 값(value)의 쌍으로 구성하는 표현 방법으로 다른 프로그래밍 언어의 Map 혹은 Dictionary 구조와 대응되는 형태 입니다.

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

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

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

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

1) 변수들의 그룹으로서의 JSON

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

이를 객체라고 한다.

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

JSON 정의하기

1
2
3
4
5
6
7
var student = {
    // key: value, key: value ... 의 형식으로 나열
    "studno": 10101,
    "grade": 1,
    "name": "학생1",
    "phoneno": "010-1231-2342"
};

정의한 데이터에 접근하기

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

2) 배열을 포함하는 JSON

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

1
2
3
4
5
6
7
8
9
10
11
12
13
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]); // 배열처럼 연결
▶ 출력결과
1
2
3
4
5
(주)굿모닝컴페니
2013
기획팀
디자인팀
개발팀

3) 계층 구조

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/** 단일 형태의 JSON */
var centerPoint = {
    x: 5,                    // x좌표
    y: 10                    // y좌표
};

/** 다른 JSON을 포함하는 JSON */
var circle = {
    center: centerPoint,    // 중심의 좌표
    radius: 5.10            // 반지름
};

console.log("원의 중점: (%d, %d)", circle.center.x, circle.center.y);
console.log("원의 반지름: %d", circle.radius);
▶ 출력결과
1
2
원의 중점: (5, 10)
원의 반지름: 5.1

계층적으로 정의된 경우

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

1
2
3
4
5
6
7
8
9
10
11
/** 계층형 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);
▶ 출력결과
1
2
원의 중점: (5, 10)
원의 반지름: 5.1

4) 목록 구조

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

자료구조 정의

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var student1 = {
    studno: 10101,
    grade: 1,
    name: "학생1"
};

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

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

console.log(classRoom);
▶ 출력결과
1
2
3
4
5
6
{
  student: [
    { studno: 10101, grade: 1, name: '학생1' },
    { studno: 20202, grade: 2, name: '학생2' }
  ]
}

데이터 접근

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

1
2
3
4
5
6
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
2
3
4
5
6
7
8
[1번째 학생]
 >> 학번: 10101
 >> 학년: 1
 >> 이름: 학생1
[2번째 학생]
 >> 학번: 20202
 >> 학년: 2
 >> 이름: 학생2

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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
2
3
4
5
6
7
8
[1번째 학생]
 >> 학번: 10101
 >> 학년: 1
 >> 이름: 학생1
[2번째 학생]
 >> 학번: 20202
 >> 학년: 2
 >> 이름: 학생2

5) 복합적 구조

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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);
}
▶ 출력결과
1
2
3
4
5
6
[게시판]
총 게시물 수: 4
[1] 첫 번째 게시물 제목
[2] 두 번째 게시물 제목
[3] 세 번째 게시물 제목
[4] 네 번째 게시물 제목

6) JSON 구조의 확장

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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);
▶ 출력결과
1
2
undefined
NaN

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

그 즉시 객체가 확장된다.

1
2
3
4
5
6
var bar = {
    name: "자바스크립트",
    age: 19
};
bar.email = "javascript@helloworld.com";
console.log(bar);
▶ 출력결과
1
{ name: '자바스크립트', age: 19, email: 'javascript@helloworld.com' }

빈 객체에 대한 확장

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

1
2
3
4
5
6
7
var myJson = {}; // 빈 객체

for (var i=0; i<10; i++) {
    var key = "value" + i;
    myJson[key] = i * 100;
}
console.log(myJson);
▶ 출력결과
1
2
3
4
5
6
7
8
9
10
11
12
{
  value0: 0,
  value1: 100,
  value2: 200,
  value3: 300,
  value4: 400,
  value5: 500,
  value6: 600,
  value7: 700,
  value8: 800,
  value9: 900
}

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

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

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

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

1) 함수들로만 구성된 JSON

익명 함수 구성 패턴

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var calcObj = {
    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;
    }
};

// JSON에 포함된 함수들 호출하기
console.log(calcObj.plus(10, 20));
console.log(calcObj.minus(50, 30));
console.log(calcObj.times(10, 20));
console.log(calcObj.div(4, 2));
▶ 출력결과
1
2
3
4
30
20
200
2

화살표 함수 구성 패턴

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

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

1
2
3
4
5
6
7
8
9
10
11
12
var calcObj2 = {
    plus: (x, y) => x + y,
    minus: (x, y) => x - y,
    times: (x, y)  => x * y,
    div: (x, y)  => x / y
};

// JSON에 포함된 함수들 호출하기
console.log(calcObj2.plus(1, 2));
console.log(calcObj2.minus(2, 3));
console.log(calcObj2.times(3, 4));
console.log(calcObj2.div(4, 5));
▶ 출력결과
1
2
3
4
3
-1
12
0.8

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

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

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var calcObj3 = {
    x: 0,
    y: 0,
    plus: function() {
        return this.x + this.y;
    },
    minus: function() {
        return calcObj3.x - calcObj3.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());
▶ 출력결과
1
2
3
130
70
9100

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
var calcObj4 = {
    x: 0,
    y: 0,
    plus: () => calcObj3.x + calcObj3.y,
    minus: () => calcObj3.x - calcObj3.y,
    foo: () => calcObj3.plus() * calcObj3.minus()
}

calcObj4.x = 100;
calcObj4.y = 30;
console.log(calcObj4.plus());
console.log(calcObj4.minus());
console.log(calcObj4.foo());
▶ 출력결과
1
2
3
130
70
9100

3) getter, setter

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

  • getter : 파라미터로 전달받은 값을 멤버변수에 복사한다. 이 과정에서 필요한 경우 값을 가공하거나 값의 유효성을 검사할 수 있다.
  • setter : 멤버변수를 리턴한다. 이 과정에서 필요한 경우 값을 가공하여 리턴할 수 있다.

멤버변수는 객체를 통해 직접 노출되는 것을 피하기 위해 언더바(_)를 명시하여 이름을 정의한다. (은닉성?)

getter, setter는 JSON 구조에 따르지 않고 독립적인 문법 구조를 갖는다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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();
▶ 출력결과
1
2
3
4
아이디를 입력하세요.
null
helloworld
안녕하세요. helloworld님

크리에이티브 커먼즈 라이선스 ITPAPER(호쌤,쭈쌤)에 의해 작성된 ≪[JS] JSON≫은(는) 크리에이티브 커먼즈 저작자표시-비영리-동일조건변경허락 4.0 국제 라이선스에 따라 이용할 수 있습니다.
이 라이선스의 범위 이외의 이용허락을 얻기 위해서는 leekh4232@gmail.com으로 문의하십시오.

comments powered by Disqus