Front-end/Javascript

[Javascript] 객체와 프로퍼티 (1)

Kamea 2022. 4. 25. 15:53

출처 :  "Javascript: The Definitive Guide, by David Flanagan(O'Reilly). Copyright 2011 David Flanagan, 978-0-596-80552-4"


♦️  객체란

객체 : 자바스크립트의 기본 데이터 타입으로 이름과 값으로 구성된 프로퍼티들의 정렬되지 않은 집합

자바스크립트에서는 문자열(string), 숫자(number), true/false, null/undefined를 제외한 나머지는 객체이다. 자바스크립트의 객체는 객체가 가진 고유 프로퍼티를 유지하는 것 외에 '프로토타입'이라고 하는 다른 객체의 프로퍼티를 상속받는다.

객체로 가장 많이 하는 작업은 객체 생성, 프로퍼티 추가, 질의, 삭제, 테스트, 열거이다. 자바스크립트에서 맨날 하는 거...

👇🏻 프로토타입은 아래 포스트에서 자세히 확인할 수 있다. 아마 먼저 보고 오는게 좋을지도...ㅎ

2022.04.14 - [CS Knowledge] - Prototype, 프로토타입

 

Prototype, 프로토타입

👇🏻 참조 수준이 아니라 그대로 갖다가 글로 옮긴 거기 때문에 꼭 영상보기를 강추한돠 더보기 https://www.youtube.com/watch?v=wUgmzvExL_E 설명의 신... Prototype 프로토타입 | 제품이 출시되기 전의 원래

sennieworld.tistory.com

 

 

♦️ 프로퍼티란

프로퍼티는 [이름+값] 으로 구성된다.

이름은 고유한 값이므로 중복이 불가능하지만 값은 가능하다. 각 프로퍼티는 프로퍼티 속성(property attribute)를 갖는다.

 

 

♦️ 프로퍼티 속성 

 

쓰기 속성 (writable) 프로퍼티 값의 수정 가능 여부를 결정
열거 속성 (enumerable) 프로퍼티의 이름을 for/in 루프에서 읽을 수 있는지 여부를 결정
설정 속성 (configurable) 프로퍼티의 삭제 가능 여부 & 변경 가능 여부를 결정

 

프로퍼티 속성은 defineProperty() 메서드를 이용해 설정할 수 있다. 

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty

 

Object.defineProperty() - JavaScript | MDN

The static method Object.defineProperty() defines a new property directly on an object, or modifies an existing property on an object, and returns the object.

developer.mozilla.org

 

 

♦️ 객체와 프로퍼티의 종류

 

네이티브 객체 (native object) ECMAScript 명세에 정의된 객체 (Array, Function, Date, 정규 표현식들)
호스트 객체 (host object) https://sennieworld.tistory.com/16 에서 확인 가능
사용자 정의 객체 (user-defined object) 자바스크립트 코드로 만든 객체
고유 프로퍼티 (own property) 객체에 직접 정의된 프로퍼티
상속받은 프로퍼티(inherited property) 객체의 프로토타입 객체가 정의한 프로퍼티

 

 

♦️ 객체 생성하기

 

⓵ 객체 리터럴 : {} 안에 이름과 값을 : 으로 구분한 순서 쌍을 , 로 연결한 리스트

 

// 프로퍼티가 없는 빈 객체
var empty={}

// 두 개의 프로퍼티 x, y를 정의
var point={x:0, y:0}

 

프로퍼티의 이름은 공백과 하이픈(-)을 포함할 수 있으며 예약어인 for도 인용부호를 둘러싸서 문자열 리터럴로 사용할 수 있다. 

또한 프로퍼티의 값이 객체 그 자체로 사용될 수 있는데 이 때, 프로퍼티의 이름은 인용부호로 감싸지 않을 수도 있다. (아래에 다 나와있음)

 

var book={
	"main title" : "해리포터",
    "sub-title" : "불사조 기사단",
    "for" : "전세계 독자들",
    author:{
    	fullname: "Joanne Kathleen Rowling",
        nickname: "Jo Rowling"
    }
}

 

 

⓶ new 를 이용한 객체 생성

new 연산자는 객체 생성 & 초기화를 한다. new 키워드 다음에는 반드시 함수 호출문이 와야하며 이 때 호출되는 함수를 생성자(constructor)이라고 하고 생성된 객체를 초기화하는 역할을 한다. 

var d = new Date();

 

 

⓷ 프로토타입 

위의 첨부 링크를 확인해주셍

 

 

⓸ Object.create() 메서드

메서드의 첫 번째 인자가 프로토타입 객체, 두 번째 인자는 새 객체의 프로퍼티 정보로 이는 생략할 수 있다.

 

var o1 = Object.create({x:1, y:2}) // o1는 x,y의 프로퍼티를 상속받음
var o2 = Object.create(null) // 프로토타입을 갖지 않는 새 객체 생성
var o3 = Object.create(Object.prototype) // {}, new Object()와 같은 일반적인 빈 객체 생성

 

 

♦️ 프로퍼티 접근 및 설정

프로퍼티의 값을 가져오기 위해서는 . 또는 [] 를 사용한다.

 

var author = book.author;
var name = author.nickname;
var title = book["main title"]

 

프로퍼티를 만들거나 설정하는 것도 같은 방법을 사용한다.

 

book.edition = 6;
book["main title"] = "Maze Runner";

 

 

💎 .(마침표) 와 [](대괄호) 의 차이점

더보기

자바스크립트에서는 객체 안에 수많은 프로퍼티들을 만들 수 있다. 

 

하지만, .(마침표)를 사용해 객체의 프로퍼티에 접근할 때는 프로퍼티의 이름을 반드시 식별자(구분이 가능한 이름)로 표현해야 한다. 식별자는 직접 타이핑을 한 이름이며 자료형이 없으므로 변경이 불가능하다.

 

반면에 []를 사용해 접근할 때는 프로퍼티의 이름을 문자열로 표현하기 때문에 생성하고 조작할 수 있다. 따라서 for/in 루프와 함께 쓰기에 더 좋다. 아래 코드에 나와있다.

 

var addr=""
for(i=0;i<4;i++){
	addr += customer["address"+1]+'\n';
}

 

 

💎 프로퍼티 접근 에러

더보기

존재하지 않는 프로퍼티에 접근할 때에는 에러가 발생하지 않고 undefined를 반환한다. 하지만 undefined 반환값을 가지고 무언가 조작을 하려는 순간 에러가 발생...

 

존재하지 않는 객체의 프로퍼티에 접근할 때에는 TypeError가 발생한다. 이러한 예외를 막기 위해서는 두 가지 방법이 있다.

 

⓵ 구체적이고 확실한 방법

var len = undefined;
if(book){
	if(book.subtitle){
    	len = book.subtitle.length;
    }
}

 

⓶ 간단하고 관용적인 방법

var len = book && book.subtitle && book.subtitle.length;

 

 

♦️ 프로퍼티 삭제

delete 연산자를 사용하면, 프로퍼티의 값이 아니라 고유 프로퍼티를 지운다. 

상속받은 프로퍼티를 지우기 위해서는 해당 프로퍼티가 정의된 프로토타입 객체에서 지워주어야 한다. 

 

// 삭제에 성공하거나, 프로퍼티가 존재하지 않을 경우 true를 반환한다.
delete book.author;
delete book["main title"];

 

 

♦️ 프로퍼티 검사

자바스크립트 객체에 프로퍼티가 있는지를 검사하기 위해서는 다음과 같은 방법을 사용할 수 있다.

 

 

⓵ in 연산자 : 존재하면 true가 반환됨

 

var o = {x:1};
"x" in o;

 

+ undefined는 아니지만 확인할 때에는 o.x !== undefined; 가 훨씬 효과적이다. 하지만, 다음과 같은 경우는 예외이다.

 

var o = {x: undefined};

o.x !== undefined //false : 프로퍼티 값이 존재하지만, undefined
o.y !== undefined //false : 프로퍼티 값이 존재하지 않음

"x" in o; // true: 프로퍼티 존재
"y" in o; // false: 프로퍼티 존재하지 않음

delete o.x;
"x" in o; // false

 

 

⓶ hasOwnProperty() 메서드 

주어진 이름의 프로퍼티가 객체에 존재하는지를 검사하고 상속받은 프로퍼티의 경우에는 false를 반환한다.

 

var o = {x:1};
o.hasOwnProperty("x"); // true
o.hasOwnProperty("y"); // false : 없으니깐
o.hasOwnProperty("toString"); // false : 상속된 프로퍼티이기 때문

 

 

⓷ propertyIsEnumerable()  메서드

이는 hasOwnProperty()보다 상세한 검사를 한다. 

객체에 주어진 이름의 고유 프로퍼티가 존재 && 열거할 수 있는(enumerable 속성이 true) => true 반환

 

var o = inherit({y:2});
o.x = 1;
o.propertyIsEnumerable("x"); // true
o.propertyIsEnumerable("y"); // false : 상속받은 프로퍼티
o.propertyIsEnumerable("toString"); // false : 내장 프로퍼티 && 열거할 수 없기 때문

 

 

♦️ 프로퍼티 열거(순회)

 

⓵ for/in 루프

상속받은 내장 메서드는 열거할 수 없지만, 그냥 만든건 가능

 

💎 자바스크립트 유틸리티 라이브러리에 가장 많이 포함되어 있는 함수들

더보기

⓵ extend() : 같은 이름의 프로퍼티가 있을 경우는 객체 o의 프로퍼티를 재정의함

function extend(o,p){
	 //p의 열거 가능한 모든 prop을 o에 추가한다.
	for(prop in p){
    	o[prop] = p[prop];
    }
    return o;
}

 

⓶ merge() : 같은 이름의 프로퍼티가 있을 경우는 객체 o의 프로퍼티를 그대로 사용함

function merge(o,p){
	for (prop in p){
    	if (o.hasOwnProperty[prop]) continue; //열거 가능한 프로퍼티 중, 같은 이름의 프로퍼티는 제외
        o[prop] = p[prop];
    }
    return o;
}

 

⓷ restrict() : 객체 o의 프로퍼티 중에 p에 없는 프로퍼티를 제거하고 o를 반환

function restrict(o,p){
	for (prop in p){
    	if (!(prop in p)) delete o[prop]; //o의 프로퍼티 중 p의 프로퍼티 제거
    }
    return o;
}

 

 

⓶ Object.keys() 함수

객체가 가진 고유 프로퍼티 중에 열거할 수 있는 프로퍼티 이름을 배열에 담아 반환한다.

 

 

⓷ Object.getOwnPropertyNames() 함수

프로퍼티를 열거하는 함수

 

다음 포스트 👉🏻