객체 리터럴

Jin Baek·2021년 12월 24일
1

javaScript

목록 보기
1/2
post-thumbnail

잘못된 부분이 있으면 지적 부탁드립니다.


객체

자바스크립트에서 객체키와 값으로 구성된 관련있는 자료의 집합이다
여기서 는 특정 데이터를 인식하기위한 이름의 역할을 하는 데이터이며,
해당 이름에 할당된 값을 의미한다 (11장 메모리 할당편에서 자세히 다룬다)

const book = {
  title: 'smartChange',
  author: 'artMarkman',
  read: function() {}, // 일급 함수여서 '값'자리에 함수가 올수 있다
  write() {}, // ES6 shorhand , es6에 추가된것으로 간단하게 함수 정의가 가능하다
}

위 코드에에서 book 이라는 변수는 titleauthor라는 키를 갖고있는 객체이고
각각 smartChangeartMarkman 을 값으로 갖고 있다
이처럼 객체 내부에서 키와 값으로 이루어진 한쌍을 프로퍼티라고 칭한다

자바스크립트는 함수도 객체의 프로퍼티로 사용이 가능한데 그 이유는 다른 언어와 다르게
자바스크립트의 함수는 일급 함수이기 때문이다

일급 함수

A programming language is said to have First-class functions when functions in that language are treated like any other variable. For example, in such a language, a function can be passed as an argument to other functions, can be returned by another function and can be assigned as a value to a variable.
-MDN-

프로그래밍 언어는 해당 언어에서 함수가 변수처럼 사용될때 일급 함수를 갖는다고 말한다 예를 들면 함수를 다른 함수의 인수로 전달 할수 있고 다른 함수의 리턴값에 사용할수도 있으며 변수에서 으로 할당이 될수도 있다

const foo = function () {} // 변수의 값으로도 할당이 되고
function bar(foo) {  // 인수자리에도 올수 있으며
  return foo; // 리턴값 자리에도 올수있다
}

리터럴

리터럴이란 특정 데이터의 모양을 직접 구현해 만든 데이터를 뜻한다

let yes = 24; // 24라는 numeric성격의 데이터르 만든것이므로 numeric literal이라 표현하고
yes = 'twenty four'; // string성격의 데이터를 만든것으로 string literal 표현하고
yes = [24]; // array성격의 데이터를 만든것이므로 array literal이라 표현하고
yes = true; // boolean성격의 데이터로 boolean literal이라 표현한다
yes = {};	// object성격의 데이터로 object literal이라 표현한다.
yes = {24: 'yes', yes: 24} // objgect litral은 빈 객체나 프로퍼티들이 있는 객체 모두 가능하다

객체 리터럴은 자바스크립트에서 객체를 쉽게 생성하기 위한 표기법이다
다른 클래스 기반 언어인 c++이나 java에서는 객체를 활용하기 위해서
해당 객체가 어떤 모양(데이터 타입)일지 사전에 미리 틀을 작성해야 하는데
자바스크립트는 객체내의 프로퍼티들에 타입 제한이 없기 때문에 쉽게 생성이 가능하다

publie class Cat {
  private String name; // 클래스기반 언어는 이렇게 어떤 타입인지 틀을 작성해야한다
  private int age;
  ...
}

자바스크립트도 생성자 함수를 사용해서 인스턴스를 만드는 과정을 통해
객체를 만들수도 있지만 리터럴로 더 간단하고 쉽게 생성할수 있다
(프로토타입을 배울때 더 자세히 다룬다)

프로퍼티

const book = {
  title: 'smartChange',
  author: 'artMarkman',
}

객체는 프로퍼티의 집합이며, 프로퍼티는 으로 구성된다
프로퍼티를 나열할때는 쉼표 , 로 구분을 하고 보통 마지막 프로퍼티 뒤에는 쉼표를 사용하지않지만 깃에서의 버전 차이를 조금 깔끔하게 하고싶다면 사용하기도 한다. 큰 차이는 없다

키와 값으로 사용할 수 있는 값들은 다음과 같다

  • 키: 빈 문자열을 포함하는 모든 문자열 또는 심볼
  • 값: 자바스크립트에서 사용할수 있는 모든 값

따라서 프로퍼티의 키 값은 숫자로 시작할 수 없으며, 연산자등도 활용할수 없다

const person = {
  firstName: 'myeong', // 식별자 규칙에 따른값
  'last-name': 'baek', // 문자열 활용하기엔 규칙에 어긋나지만 ''로 감싸서 가능하다
   last-name: 'baek', // 에러 발생: -는 중간에 사용할 수 없다
   123jin: '', // 에러 발생: 숫자로 시작 할 수 없다.
   -jin: '', // 에러 발생: 연산자등으로 시작 할 수 없다.
  

프로퍼티의 키값은 해당 프로퍼티의 데이터에 접근하기 위한 식별자로서의 역할을 한다
그렇기때문에 네이밍 규칙을 따르는게 안전 하다. 규칙을 따르고 싶지 않아도 사용은 가능하다

프로퍼티 접근

프로퍼티 접근에는 2가지 방법이 있다
점 표기법dot noation 하고 괄호 표기법Bracket notation 이다

Property names that are not valid identifiers cannot be accessed as a dot (.) property, but can be accessed and set with the array-like notation("[]").
-MDN-

유효한 식별자는 dot noation으로 접근하고 유효하지 않은 식별자를 쓰는 프로퍼티 이름은 dot noation으로 접근할 수 없고 Bracket notation으로 접근할 수 있다

const unusualPropertyNames = {
  '': 'empty',
  '!': '!',
  'usualPropertyNames': 'jin'
}
console.log(unusualPropertyNames.'');   // 에러 발생: 유효 하지 않는 식별자를 .으로 접근
console.log(unusualPropertyNames['']);  // empty
console.log(unusualPropertyNames.!);    // 에러 발생: 유효 하지 않는 식별자token !
console.log(unusualPropertyNames['!']); // !
console.log(unusualPropertyNames.usualPropertyNames); // jin

계산된 프로퍼티 이름

프로퍼티를 동적으로 할당 해야 하는 경우, Bracket notation을 활용한다
직접 접근해서 할당하는게 아니라, 객체 리터럴이 선언되는 곳에서 자동적으로 연산하여
프로퍼티를 생성시키는 방법을 계산된 프로퍼티 이름이라 한다
Bracket 내부에 [ ] 자바스크립 표현식이 들어와 계산된 이후 프로퍼티 이름으로 사용된다

const names = ['jin', 'baek'];
const origin = {}; // 객체 리터럴이 선언된 곳

/*
origin[names[0]] = `computedName's value`; // 이렇게 직접 접근해서 할당 하는게 아니라
*/

names.forEach((name, i) => {	
  // 객체 리터럴로 선언된 origin에 자동적으로 연산하여 프로퍼티를 생성 하는 방법이다
  origin[name + i ] = name + i;  // {jin0: "jin0", baek1: "baek1"}
});
              

프로퍼티 삭제

객체에 존재하는 프로퍼티를 제거하려면 delete 연산자를 사용해야 한다
none-configurable한 프로퍼티를 삭제할때에만 false를 반환하고
그외에는 다 true를 반환한다.
none-configurable옵션은 Object.defineProperty()메소드에
옵션으로 세부사항을 주어서 수정 할수 있다. 그리고 프로퍼티 삭제는
메모리 해제와 관련이 없는데 메모리 해제는 참조되는곳이 없을때 가비지 컬렉터가
해주는 것이고 프로퍼티 삭제는 참조를 삭제하는게 아니기 때문이다
(다음장에서 메모리와 데이터타입을 다룰때 자세히 다룬다)

const book = {
  deleteMe: 'are you sure',
}
delete book.deleteMe // true (존재하는 프로퍼티를 삭제하면 true가 나온다)
delete book.addMe // true (존재하지 않는 프로퍼티를 삭제해도 true가 나온다)

마무리


객체와 리터럴,
평소 그냥 당연시 하며 사용했던것을 설명으로 풀어 쓰는게 쉽지 않았다.
알고 있다고 해도 말이나 글로 설명을 못하면 제대로 알고 있는게 아닐수도 있고
또 설명이 된다고 해도 잘못 이해한 내용이 바탕이 된 설명일 수도 있다.
갈 길이 멀어 보이지만 한 걸음씩 제대로 걷는게 중요하단 생각이 든다.

참고


팀 러버덕 리더 훈님 자료
모던 자바스크립트 deep dive 10장
https://developer.mozilla.org/en-US/docs/Glossary/First-class_Function
https://developer.mozilla.org/en-US/docs/Glossary/Literal
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Grammar_and_types#object_literals
https://stackoverflow.com/questions/61370583/trailing-comma-after-last-line-in-object
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/delete

0개의 댓글