드디어 나름 기획했던 javascript 기초 시리즈의 마지막 객체편이다.
1편부터 함께 build-up하신 분이 있다면 우선 진심으로 감사드리고🙇♂️ 또 너무너무 고생하셨다는👍👍 말씀을 꼭 드리고 싶다.
객체는 {} 안에 key와 value가 한쌍으로 이루어진
property(속성)라는 것이 담긴 형태로 구성되어 있다.
객체는 두가지 방법에 의해 생성할 수 있다.
객체의 선언은 주로 리터럴(literal) 문법을 쓰고
생성자(constructor) 문법은 추가적인 기능이 필요한 경우에 사용한다.
우선 리터럴(literal) 문법과 함께 구조를 알아보며 객체를 완성시켜보자.
✔️ 객체는 {}(중괄호) 안에 key:value가 담긴 형태로 구성된다.
✔️ 객체 또한 다른 자료형들과 마찬가지로 변수에 할당하여 사용한다.
let 객체담은변수 = { key:value };
✔️ 객체 안에 내용이 많으면 코드를 구분하여 가독성을 높여주자.
let 객체담은변수 = {
key:value,
key2:value,
key3:value
};
✔️ key는 자신의 짝인 value를 가리키고 있는 이름과 같은 것이다.
✔️ 데이터를 변수에 할당할때 넣는 변수이름을 짓는것과 유사하다.
✔️ key는 변수처럼 몇몇 규칙 내에서 마음대로 이름을 지어줄 수 있다.
// "객체담은변수"에 객체를 할당
let 객체담은변수 = {
// key이름은 변수이름짓기처럼 자유롭다
key이름은내맘대로: "value"
};
💡 property key는 변수이름과 다르게 예약어(let, for 등)가 사용 가능하다.
숫자도 가능하며 문자형이 아닌 경우 자동으로 문자형으로 변환된다.let 자유로운객체 = { let: "'s go", 918: "구여미 생일" }; console.log(자유로운객체.let); // 's go console.log(자유로운객체[918]); // 구여미 생일 console.log(자유로운객체["918"]); // 구여미 생일❗️0918처럼 key가 0부터 시작하고 뒤에 정수가 쓰이는 경우에는 문자열로 자동변환 되지 않는다.(또한 0.918은 되고 09.18은 안된다.)
✔️ key의 다음으로 :(콜론, 식별자)을 넣고 그 다음에 value를 넣는다.
✔️ value는 객체이름.key 혹은 객체이름["key"]를 통해 불러올 수 있다.
let 객체담은변수 = {
// "key이름은내맘대로" key의 value로 "할수있다!🙆♀️"를 넣었다.
key이름은내맘대로: "할수있다!🙆♀️"
};
console.log(객체담은변수.key이름은내맘대로); // 할수있다!🙆♀️
✔️ key:value 한 쌍을 가리켜 property라고 부른다.
// property
key이름은내맘대로: "할수있다!🙆♀️"
✔️ property와 property는 ,로 구분해줘야 한다.
let 객체담은변수 = {
key이름은내맘대로: "할수있다!🙆♀️",
객체뒤에는: "콤마를!!",
마지막property에는: "콤마 안써도 됩니당!"
}
이제부터는 관련 자료를 찾아보다가 "어떤 것의 property의
key" 혹은
"property의value"라고 말한다면 지금 언급하고 있는 것이 객체라는 것을
자동으로 인지할 수 있다.
생성자 문법은 객체를 처음 배운다면 이해하기 어렵기 때문에
객체가 이렇게 생성될수도 있구나 하는 정도만 알고 다음으로 넘어가자.

✔️ 변수에 new Object()를 할당하여 변수명을 통해 객체를 생성할 수 있다.
let 객체소환술사 = new Object();
// 빈 객체를 소환했다.
console.log(객체소환술사); // {}
✔️ 생성자 문법으로 빵틀처럼 재사용 할 수 있는 객체 생성 코드를 만들 수 있다.
function 몬스터(name, hp, ability) {
this.name = name,
this.hp = hp,
this.ability = ability
}
// new 몬스터()를 생성자 함수라고 한다.
// 객체를 생성함과 동시에 함수에 argument를 전달한다.
let 소환술사 = new 몬스터("비둘기", 1, "정수리에 물똥");
let 악당소환술사 = new 몬스터("병아리", 0.3, "귀여미");
// 생성자 함수를 거쳐 key는 같지만 value는 다른 property를 가진 객체를 돌려줬다.
console.log(소환술사); // 몬스터 { name: '비둘기', hp: 1, ability: '정수리에 똥' }
console.log(악당소환술사); // 몬스터 { name: '병아리', hp: 0.3, ability: '귀여미' }
💡 객체 생성자 문법은 유사한 객체를 만들어야 할 때 사용된다.
재사용할 형태를 정해둔 후 객체를 생성할 때 넣은 입력값에 따라서
지정해둔 일정한 틀 안에서 그때그때 다른 값이 리턴되는 코드를 만들 수 있다.
🤗 지금은 생성자 함수에 대해 알지 못해서 이해하기 어렵겠지만
지금까지 해왔듯 차근히 배워간다면 모두 이해할 수 있는 내용이다.
객체 기본편에서 깊게 다루기에는 맞지 않고 지금 배우는 객체의 기능이
앞으로 어떻게 확장되어가는지, 그리고 어떻게 쓰이는지 예시로 넣어보았다.

객체는 왜 객체형이라는 자료형으로 따로 분류되어있을까?
원시형과는 다른 특성이 있으니 구분지었을 것이다 라고 선을 긋고
원시형과 비교하며 객체만의 새로운 개념들을 받아들여보자.
우선 객체의 형태와 특성을 가볍게 훑어보겠다.
✔️ 말이 웃기지만 객체는 객체형이다. 마치 인간을 인간형이라고 하는 것처럼.
✔️ 중요한건 그렇기 때문에 자신의 자료형만 가질 수 있는 원시형과는 다르다.
// 원시형인 문자형에 undefined를 담았다.
let 나는무엇인가 = "undefined";
// undefined는 문자형이 되어버린다.
console.log(typeof 나는무엇인가); // string
undefined자료형은 문자형을 의미하는""안에 들어가면 문자열이 된다.
문자열은undefined라는 자료형을 담을 수 없는 것이다.
// 객체에 undefined를 담았다.
let 나는무엇인가 = {
언디파인드type: undefined,
}
// 객체는 undefined 자료형 그대로를 보존한다.
console.log(typeof 나는무엇인가.언디파인드type); // undefined
하지만 객체에는 데이터 본래의 자료형 그대로 저장된다.
✔️ 배열에 index가 있다면 객체에는 key라는 이름표가 있다.
✔️ 배열에서 index로 데이터(element)를 불러오듯 객체는 key를 통해 데이터(value)를 불러온다.
let 당신은누구인가 = {
박효신: "둘도 없는 킹왕짱 가수",
원빈: "방부제로 샤워하는 배우",
정우성: "존재가 멋 그 자체인 휴먼"
}
console.log(당신은누구인가.박효신); // 둘도 없는 킹왕짱 가수
박효신(key)이라는 상자(property)에"둘도 없는 킹왕짱 가수"라는 문자열(value)이 저장되어있다.
🤗 이 부분은 약간어려울 수도 있기 때문에 건너뛰고 다른 내용부터 학습하고
객체에 어느정도 익숙해진 후 돌아와서 다시 읽어봐도 좋다.
✔️ 원시형 데이터를 할당한 원본변수를 새로운변수의 값으로 할당한 경우, 새로운변수는 원시형 데이터를 복사해서 원본변수와 같은 값을 가진다.
✔️ 그렇다면 그 새로운변수에 다시 할당된 값을 수정하면 어떻게 될까?
// 원시형을 할당한 원본변수
let 사람이되고싶은_곰 = "곰";
// 새로운 변수에 "사람이되고싶은_곰" 변수를 할당했다.
let 마늘을열심히먹은_곰 = 사람이되고싶은_곰;
// 둘은 같은 값을 갖는다.
console.log(사람이되고싶은_곰); // 곰
console.log(마늘을열심히먹은_곰); // 곰
// "사람이되고싶은_곰" 변수를 할당한 새로운변수에 할당된 값을 수정해보자.
마늘을열심히먹은_곰 = "웅녀";
// 사람이되고싶은_곰 변수는 값이 바뀌지 않았다!
console.log(사람이되고싶은_곰); // 곰
console.log(마늘을열심히먹은_곰); // 웅녀
새로운변수에 같은 원시형 데이터를 할당했을 경우, 기존변수에 할당된 원시형 데이터는 변함이 없고 서로 다른 값을 가지게 된다.
❗️복사된 원시형 데이터는 원본 원시형 데이터와 상관 없는 새로운 데이터다.
❗️원시형 데이터는 변경 불가능한 값(immutable value)이기 때문에 값을 수정할 수 없다.
✔️ 반면 객체를 할당한 변수는 완전히 다르게 동작한다.
// 객체를 할당한 원본변수
let 사람이되고싶은_호랑이 = {
호랑이: "마늘은 싫어"
}
// 새로운 변수에 "사람이되고싶은_호랑이" 변수를 할당했다.
let 마늘을안먹은_호랑이 = 사람이되고싶은_호랑이;
// 둘은 같은 값을 갖는다.
console.log(사람이되고싶은_호랑이); // 마늘은 싫어
console.log(마늘을안먹은_호랑이); // 마늘은 싫어
// "사람이되고싶은_호랑이" 변수를 할당한 변수에 새로운 값을 할당해보자.
마늘을안먹은_호랑이.호랑이 = "아몰라! 마늘안먹어 나 사람안할래!!";
// "사람이되고싶은_호랑이" 변수도 값이 바껴버렸다!
console.log(사람이되고싶은_호랑이); // 아몰라! 마늘안먹어 나 사람안할래!!
console.log(마늘을안먹은_호랑이); // 아몰라! 마늘안먹어 나 사람안할래!!
💡 객체와 참조(reference)
새로운변수에 할당된 객체의 내용을 수정했더니 원본변수의 객체 내용까지 변경되어 버렸다.
❗️어떤 변수에 할당된 객체는 그 변수 자체에 귀속되는 것이 아니라 자신을 할당한 변수에게 객체 자신을 열수있는 열쇠를 준다고 생각해보자.
그래서 객체를 담고있는 원본변수를 새로운변수에 할당하는 것은 원본변수가 객체에게 받은 열쇠만 복사해간다고 기억하자.
❗️하지만 새로운 변수에 원시값을 할당하면 둘의 관계는 끊기고 원본변수의 객체의 값은 변하지 않는다.
🤗 정확히는 객체는 별도의 메모리에 저장되고 객체를 할당한 변수에는 그 객체에 대한 참조값(메모리 주소)이 저장되어 있는 것이다.
원시형 데이터는 자신이 할당된 변수에 값이 저장된다.
✔️ 객체는 동일한 데이터라는 기준이 원시형과는 다르다.
✔️ 원시형은 데이터의 값이 같으면 JavaScrip는 동일한 데이터라고 판단하지만 객체는 참조값(메모리 주소)이 같아야 동일한 데이터라고 판단한다.
// 동일한 값을 가진 원시형
let 문자열1 = "나는 고구마";
let 문자열2 = "나는 고구마";
console.log(문자열1 === 문자열2); // true
// 동일한 값을 가진 객체
let 객체1 = { 나는: "고구마" };
let 객체2 = { 나는: "고구마" };
console.log(객체1 === 객체2); // false
// 동일한 참조값을 가진 객체
let 객체3 = { 나는: "고구마" };
let 객체4 = 객체3;
console.log(객체3 === 객체4); // true
객체는 여러가지 모든 자료형의 데이터를 모아놓을 수 있는 상자와 같은 존재다.
그런데 어디서 많이 들어본 특징이다.
맞다. 배열 역시 데이터를 모아놓을 수 있고 가져와 쓸 수 있는데..
그렇다면 객체는 왜 만들어졌고 존재하는지 궁금해질 수 밖에 없다.
✔️ 배열의 index는 0, 1, 2...와 같은 숫자가 내 의지와 상관 없이 element에 지정된다.
✔️ 하지만 객체는 내가 원하는대로 value에 key를 붙여줄 수 있다.
let 컴퓨터꺼 = ["memory", "cpu", "ssd"];
console.log(컴퓨터꺼[0]); // memory
let 내꺼 = {
맛난: "아이스크림",
예쁜: "여자친구",
자꾸감기는: "눈"
};
console.log(내꺼.맛난); // 아이스크림
💡 연결하려는 value에 따라 연상하기 쉬운 이름으로 지어줄 수 있기 때문에
데이터를 사용할 때 기억하기도 편리하고 각각의 데이터가 의도하는 것이
무엇인지 알려주기도, 파악하기도 쉽다!
✔️ 배열의 index는 element의 추가, 삭제에 따라 컴퓨터 마음대로 변화된다.
✔️ 따라서 내가 너무 똑똑해서 index와 연결되는 element들을 외웠다 해도
element 추가/삭제가 빈번히 발생한다면.. 점점 미쳐가며 의도치 않은
element를 가져올 확률이 높아진다.
🤗 실재로 index를 기억해서 element를 다룬다는 것이 아니라
index로 특정 데이터를 지목하여 사용하는 것이 지속적으로는 거의
불가능하고 의미없다는 말이다.
✔️ 반면 객체의 key는 임의로 누가 조작하거나 삭제하지 않는 이상 변하지 않으며
(value를 임의로 변경하지 않는 이상) 항상 동일한 value를 지목하고 있다.
// 배열
let 컴퓨터꺼 = ["memory", "cpu", "ssd"];
console.log(컴퓨터꺼[0]); // memory
// "memory"가 삭제되었다.
컴퓨터꺼.shift(컴퓨터꺼[0]);
// 똑같은 index를 불러왔지만 삭제된 "memory" 대신 "cpu"를 꺼내왔다.
console.log(컴퓨터꺼[0]); // cpu
// 객체
let 내꺼 = {
맛난: "아이스크림",
예쁜: "여자친구",
자꾸감기는: "눈"
};
console.log(내꺼.맛난); // 아이스크림
// "맛난"이 삭제되었다.
delete 내꺼.맛난;
// "맛난"이라는 것은 없다고 말해준다.
console.log(내꺼.맛난); // undefined
💡 반복문과 배열에서 알아봤듯 배열은 배열만의 장점들이 있다.
배열은 배열 전체의 길이를 간단하게 파악할 수 있고 전체 element들에 대한
특정 연산을 쉽고 빠르게 수행할 수도 있는 특수성이 있다.
객체보다 후진게 아닌 목적이 다른 도구라고 생각하자.
🤗 개인적으로 배열은 데이터 묶음 전체에 대한 처리와 관련하여 활용도가 높고 변화되는 데이터에 대한 대응 또한 유연한 것이 특징이고, 객체는 관련된 데이터/연산을 목적에 따라 묶어음으로써 규모적 관리의 용의성이 높고 그 안에서 개별적으로 이름을 붙여줄 수 있어서 각각의 데이터/연산 단위로도 관리하고 사용하기 편리하다고 정리하고 있다.
✔️ 배열도 분명 모든 자료형을 담을 수 있고 함수도 마찬가지다.
let 배열이 = [function 여긴어디인가(a, b) { return a+b }, "이야 나 함수도 담는다야"]
console.log(배열이[0]); // [function: 여긴어디인가]
✔️ 심지어 연산도 된다.
// 변수이름 짓다가 하루가 다 가서.. 이해 부탁드리겠습니다.
let 배열이네집 = [function 여긴어디인가(a, b) { return a+b }, "이야 나 함수도 담는다야"];
console.log(배열이네집[0](9, 18)); // 27
🤗 배열에 함수를 넣어서 사용할 일은 없으니 참고만 하고 넘어가도록 하자.
✔️ but 앞서 확인했듯 배열의 index는 불안정하고 기억하기 어려우며 또한
우리가 아는 배열의 사용법과는 추구하는 결이 다르다는 것이 직감적으로 느껴진다.
indexOf()method를 이용해 index를 찾을 수 있겠지만 번거롭다.
✔️ 반면에 객체는 함수를 담기에 참 좋은 주머니다. 언제든 key로 함수를 부를 수 있다.
let 김객체네집 = {
여긴또어딘가: function(a, b) { return a+b }
};
console.log(김객체네집.여긴또어딘가(9, 18)); // 27
💡 이렇게 객체 안에 있는 함수를 method(메소드)라고 부른다.
✔️ 단축구문까지 만들어진걸 보면 그만큼 method는 자주 사용된다는걸 눈치챌수있다.
let 김객체네집 = {
여긴또어딘가(a, b) { return a+b }
};
console.log(김객체네집.여긴또어딘가(9, 18)); // 27
객체에 함수를 넣음으로써 기능을 가진 객체가 되었으며 이제는 단순히 데이터만 담아 모아놓는 주머니가 아니게 되었다.
이러한 특성들을 바탕으로 객체는 다양한 일을 할 수 있게 된다.(=배워야할게많다)
JavaScript는 다 계획이 있었다.🤤
객체의 property에 접근하는 방법에는 두가지가 있다.
왜 굳이 두가지 방법으로 나누어놨는지 이유를 알아보도록 하자!
✔️ property의 value는 객체이름.key와 같은 형태로 객체에서 가져오려는 key 앞에 .(dot)을 넣어서 불러올 수 있다.
let 미국양꼬치 = {
야_몇$있냐: "1센트에 한대다 솔직히 말해라"
};
console.log(미국양꼬치.야_몇$있냐); // 1센트에 한대다 솔직히 말해라
✔️ 하지만 key에 띄어쓰기가 있거나 숫자로 시작하거나 특수문자($, _ 제외)가 있는 경우 dot notation을 쓸 수 없다.
let 미국양꼬치 = {
"야 몇$있냐": "1센트에 한대다 솔직히 말해라"
};
console.log(미국양꼬치.야 몇$있냐); // SyntaxError: missing ) after argument list
❗️key에 띄어쓰기나 특수문자가 있는 경우
""로 감싸 문자열로 만들어야 한다.
✔️ property 호출시 key를 [](bracket notation)에 넣으면 key가 어떤 형태의 문자열이라도 읽을수 있다.
let 미국양꼬치 = {
"야 몇$있냐": "1센트에 한대다 솔직히 말해라",
"🕺 이눔시끼!!": "어디가!!"
};
// 특수문자나 띄어쓰기가 있어도 읽어온다.
console.log(미국양꼬치["야 몇$있냐"]); // 1센트에 한대다 솔직히 말해라
console.log(미국양꼬치["🕺 이눔시끼!!"]); // 어디가!!
❗️
[]안에 key는 꼭 따옴표로 묶어줘야 동작한다.
따옴표는'',"",``중에 아무거나 사용해도 된다.
✔️ property의 key를 변수에 할당할 수도 있으며 경우도 [""]로 가져올 수 있다.
let 미국양꼬치 = {
"야 몇$있냐": "1센트에 한대다 솔직히 말해라",
"🕺 이눔시끼!!": "어디가!!"
};
// 변수에 key를 할당
let 나쁜사람 = "야 몇$있냐";
// bracket notation -> success
console.log(미국양꼬치[나쁜사람]); // 1센트에 한대다 솔직히 말해라
// dot notation -> fail
console.log(미국양꼬치.나쁜사람); // undefined

객체는 앞서 말했다시피 모든 자료형을 property로 가질 수 있다.
따라서 property에 배열과 객체가 섞인 value가 있을 수도 있다.
우리는 이미 열쇠를 쥐고 있는 것이다.

✔️ 객체에 접근하기 위해서는 .key나 ["key"]가 필요하고 배열에 접근하려면 [index]가 필요하다는 것을 우리는 배웠다.
✔️ 접근법만 알면 우리는 복잡해 보이는 객체와 배열이 섞인 value에 쉽게 닿을 수 있다.
✔️ 아래 예문을 통해 우리는 잠시 심마니가 되어 300년산 산삼🥕을 찾아볼 것이다.
let 심마니 = {
잡초: "안녕 나는 잡초야",
사과숲: ["뭐야", "나한테", "사과해"],
숲속: ["가시덤불", ["반짝임", {
홍삼:["나로 만족할텐가", "🤔", 1, 2, 3, "에잇!!", {
휘적휘적:["음?!!", {
무언가빛난다:["흙", "300년산 산삼🥕", "흙"]
}
]}]
}]]
};
✔️ 객체를 만나면 .객체이름을, 그 객체의 value가 배열이면 [index]로 접근하면 끝.
console.log(심마니.숲속[1][1].홍삼[6].휘적휘적[1].무언가빛난다[1]);
// 300년산 산삼🥕
✔️ undefined로 확인하기.
객체이름.key === undefined 조합으로 property의 존재를 확인할 수 있다.let 빈깡통 = {};
console.log(빈깡통.내용물 === undefined) // true
let 새로사온깡통 = { 내용물: "찰랑찰랑" };
console.log(새로사온깡통.내용물 === undefined) // false
✔️ in연산자
"key" in 객체이름으로 property 존재 여부를 확인할 수 있다.
찾는 property가 있으면 true 없으면 false를 반환한다.
let 서랍장 = {
첫번째: "양말",
두번째: "플링글스"
}
console.log("두번째" in 서랍장); // true
✔️ ❗️그러나 객체이름.key === undefined는 찾는 property가 없어도 true를 반환한다.
✔️ 반면 in연산자는 property가 없으면 false 반환하기 때문에 되도록 정확도가 더 높은 in 연산자를 쓰자.
let 서랍장 = {
첫번째: "양말",
두번째: "플링글스",
}
console.log(서랍장.세번째 === undefined); // true
console.log("세번째" in 서랍장); // false
✔️ 객체이름.추가할key = 추가할value로 객체에 property를 추가할 수 있다.
let 서랍장 = {
첫번째: "양말",
두번째: "플링글스",
}
//
서랍장.세번째 = "비상금 50만원";
console.log(서랍장);
/* { '첫번째': '양말',
'두번째': '플링글스',
'세번째': '비상금 50만원' } */
✔️ 수정하고 싶은 property에 대해 객체이름.수정할 property의 key = 새로운 value로 property의 value를 수정할 수 있다.
let 서랍장 = {
첫번째: "양말",
두번째: "플링글스",
세번째: "비상금 50만원"
}
서랍장.두번째 = "반만 남은 플링글스"
console.log(서랍장.두번째);
/* { '첫번째': '양말',
'두번째': '반만 남은 플링글스',
'세번째': '비상금 50만원' } */
✔️ delete 연산자를 객체이름.key 앞에 써주면 property는 삭제된다.
let 서랍장 = {
첫번째: "양말",
두번째: "반만 남은 플링글스",
세번째: "비상금 50만원"
}
delete 서랍장.세번째
console.log(서랍장);
/* { '첫번째': '양말',
'두번째': '반만 남은 플링글스' } */
✔️ const로 선언된 객체는 수정되기 때문에 주의해야 한다.
✔️ 객체 전체를 대상으로 수정하려 할 경우에는 수정되지 않는다.
const 불변의사랑 = {
나는당신뿐이에요: "수지"
}
// 기존 property를 재할당 할 수 있다.
불변의사랑.나는당신뿐이에요 = "수지, 블랙핑크, 트와이스";
console.log(불변의사랑.나는당신뿐이에요); // 수지, 블랙핑크, 트와이스
// 새로운 property도 추가로 할당 가능하다.
불변의사랑.어제까지는 = "한가인";
console.log(불변의사랑);
/* {
'나는당신뿐이에요': '수지, 블랙핑크, 트와이스',
'어제까지는': '한가인'
} */
// 객체 전체는 재할당 할 수 없다!!
불변의사랑 = { 두사랑: "이혜리, 강민경"}; // TypeError: Assignment to constant variable.
배열과 반복문에서 참고로 다룬 그대로의 내용이다.
약속대로 다시 가져왔으니 그때 이해가 어려웠다면 이제는 좀 더 쉬울거라 믿고
그냥 skip했었다 해도 상관없으니 이제부터 알아보자.
✔️ 객체 역시 배열과 마찬가지로 반복문을 쓸 수 있다.
✔️ for..in문으로 객체의 key를 순회할 수 있으며 모든 property를 다룰 수 있다.
✔️ 기본 형태는 for (let key in object) {...}로 ()는 각각
let key는 property들의 key를 나타내는 변수로 변수명은 아무렇게나 지어도 상관 없으며 이것을 통해서 property를 불러올 수 있다.in은 for과 마찬가지로 for..in문을 구성하는 기본 뼈대로 그대로 작성한다.object에는 가져올 객체를 담고있는 변수명을 넣고 key를 가리키는 변수명과 함께 object[key]의 형태로 property의 value를 불러올 수 있다.let 게임평가 = {
서머너즈워: "즐거웠다",
라그나로크: "음머~~",
리니지: "nc주식을 샀어야해"
}
for (let 너의정보는 in 게임평가) {
console.log(`게임 ${너의정보는}는 내 기억에 ${게임평가[너의정보는]}이다.`);
}
/* 게임 서머너즈워는 한마디로 "즐거웠다"다.
게임 라그나로크는 한마디로 "음머~~"다.
게임 리니지는 한마디로 "nc주식을 샀어야해"다.*/
❗️객체는 배열처럼 index로 정렬되지 않고 객체만의 방식으로 정렬된다.
정수 프로퍼티(integer property)는 key가 "1"과 가까운 부터 순서대로 정렬되고 나머지는 객체에 추가한 순서대로 출력된다.
결론부터 말하자면 배열은 객체형의 모든 특성을 가지고 있다.
참조값으로 접근되며 모든 자료형을 수용하고 값을 수정할 수 있다.
✔️ 객체는 변수에 저장되는 것이 아니라 메모리에 저장되어 참조값으로 접근된다.
✔️ 배열 또한 참조값에 의해 접근되며 값이 같으면 동일한 값이라고 판단하는 원시형과 다르게 값이 같아도 동일한 배열로 보지 않고 다른 배열로 판단된다.
let 배열1 = [ "고구마" ];
let 배열2 = 배열1;
let 배열3 = [ "고구마" ];
console.log(배열1 === 배열2); // true
console.log(배열1 === 배열3); // false
let 원시형1 = "고구마";
let 원시형2 = 원시형1;
let 원시형3 = "고구마";
console.log(원시형1 === 원시형2); // true
console.log(원시형1 === 원시형3); // true
✔️ 객체형의 특성대로 모든 자료형을 가질 수 있다.
let 객체 = {
문자형: "고구마",
숫자형: 123,
불린형: true,
undefined형: undefined,
null형: null,
배열: ["array"],
객체: { key: "value" }
};
let 배열 = [ "고구마", 123, true, undefined, null, ["array"], { key: "value" }];
// 모든 내용이 이상 없이 출력된다. 생략하겠다.
console.log(객체);
console.log(배열);
✔️ 객체를 제외한 모든 값은 변경 불가능한 값(immutable value)이다.
✔️ 문자형을 할당한 변수의 문자를 약간 수정하면 그건 변경이 아닌 새로운 문자형이다.
✔️ 하지만 객체는 값을 수정할 수 있고 배열 또한 그렇다.
let 구황작물 = "고구마";
구황작물 = "고구마, 감자";
console.log(구황작물); // 고구마, 감자
let 텃밭 = ["고구마", "감자"];
텃밭.pop();
console.log(텃밭); // ['고구마']
문자열은 "고구마"에서 "고구마, 감자"라는 새로운 문자열로 대체되었지만,
배열은 "감자"라는 값을 제거하고 "고구마"라는 값만 가지게 수정된 것이다.
구글에 js자료형이라고 검색하면 가장 첫번째에 나오는 MDN의 링크를 클릭하면
"배열(Arrays)는 정수키를 가지는 일련의 값들을 표현하기 위한 오브젝트이다." 라고
명시되어있다.
https://developer.mozilla.org/ko/docs/Web/JavaScript/Data_structures#arrays
드디어 끝났다 나의 자바스크립트 기초편이.🥲
처음 기초편을 기획했을 때는 최대한 친절하게 세심한 부연설명과
가장 쉬운 방법으로 설명해보자 하는 목표로 시작했다.
그 결과는 굉장히 고통스러웠다..ㅋㅋ

처음 출연하는 기호가 나오면 괄호를 넣거나 해서 꼭 그 이름을 명시했고
가장 친숙한 단어들로 설명하려 하면서도 문장을 간결하게 표현하려니 죽을 맛이었다.
글이 읽히지 않는 가장 큰 원인이 낯선 어휘가 섞인 긴 문장 때문이라고
생각하기 때문에 전달력을 위해 외면하지 못하고 신경썼던 부분이다.
그렇게 평생 영양제라고는 딱히 챙겨먹어본적 없었던 나는
오메가3와 칼슘&마그네슘 보충제에 몸과 마음을 기대는 지경이 됐다.🤤
그래서 점점 "기초 시리즈만 끝나면 누가 잘 못알아볼것같아도 그냥 편하게 쓰자"하는
마음이 커져갔었는데 막상 마무리가 되다보니 생각이 조금 바꼈다.
.gif)
우선 설명하려는 계속된 시도 그 자체는 스스로를 이해시키는데도 좋은 영향을 끼쳤다.
기존에 알고 있던 부분이 틀렸다던가 정리되어 새롭게 다가오기도 했고
여러번 곱씹어 생각하다보니 그 내용들이 머릿속에 많이 남아있었다.
그런가보다 하고 넘어갔던 부분들을 말과 코드로 명확히 해야하기 때문에
그 과정에서 막상 하나의 문장도 완성하기 힘들었던 영역들이 있었고
배웠지만 뜬구름같던 지식들이 점점 구체화 되기도 했다.
마치 내가 무엇을 잘 모르고 있는지 확실히 구분해주는 판독기 같았다.
개발자들의 특수한 문화인 코드리뷰도 아마 이런 면에서 하는건가 싶다.
이렇게 돌이켜보니 지난 3주간 치뤘던 기술블로그와의 전투에서
큰 가르침을 얻었기에 이 과정을 어느정도는 계속 가져가보려 한다.
전에 겪어보지 못한 경험이라 더 특별하고 소중하다.

요 기여미 햄스터마냥 새로운 지식들에 계속 도전해보자 🏃