TIL 9 Javascript - 객체(Object)

Leo·2021년 3월 6일
0

Javascript

목록 보기
6/17
post-thumbnail

객체(Object)란?

자바스크립트는 객체 기반의 스크립트 언어이며 자바스크립트를 이루고 있는 거의 모든 것이 객체라고 생각하면 된다. 또한 원시 타입을 제외한 나머지 값들(함수, 배열, 정규표현식 등)은 모두 객체이다. 그리고 객체는 키(key)값(value)으로 구성된 프로퍼티(Property)들의 집합이다.

var person = {
  name: 'juyoung',
  age: 27,
  sayHi: function() {
    console.log('Hi! I''m ' + this.name);
  }
};

person이라는 객체를 만들고 name이라는 key값에 juyoung이라는 value를 넣었다. 그리고 sayHi에는 함수를 value로 넣었다. 여기서 name, age프로퍼티(속성)가 되고 sayHi의 함수는 메소드가 된다.

그렇다면 프로퍼티와 메소드는 무엇이고, 무엇을 기준으로 프로퍼티와 메소드를 분류할까?

아래에서 프로퍼티와 메소드에 대해 더 자세히 알아보겠다.

프로퍼티

프로퍼티는 객체의 속성을 나타내는 접근 가능한 이름(key)과 활용 가능한 값(value)을 가지는 형태이다. 특정 객체가 가지고 있는 정보를 품고 있어 그 객체가 가진 정보에 직접적으로 접근할 수 있게 해준다. 배열과는 달리 객체는 프로퍼티를 열거할 때 순서를 보장하지 않는다.

  • key :빈 문자열을 포함한 모든 문자열 또는 symbol 값
  • value : 모든 값

메소드

메소드는 프로퍼티 값이 함수일 경우 일반 함수와 구분하기 위해 메소드라고 부른다. 즉 메소드는 객체에 value로 제한되어 있는 함수를 의미한다.

다른 언어에서는 메소드를 함수라고 부르거나 함수를 메소드라고 부르는 경우가 있다. 하지만 자바스크립트에서는 둘의 의미가 다르니 정확하게 알고 넘어가야 한다.

  • 함수 : 함수는 특정 작업을 수행하는 코드조각. 전역,지역에서 독립된 기능을 수행하는 단위
  • 메소드 : 클래스, 구조체, 열거형에 포함되어있는 함수가 메소드이다, 클래스 함수라고도 한다.
function a() {
  console.log("this is function");
};
a();

var b = {
  content : 'this is method',
  print : function () {
    console.log(this.content);
  }
};
console.log(b.print());

쉽게 이해하려면 호출을 할 때 앞에 .이 있으면 메소드, 없으면 함수라고 생각하면 된다.

객체 생성 방법

자바같은 클래스 기반 객체 지향 언어는 클래스를 사전에 정의하고 필요한 시점에 new연산자를 이용해 객체를 생성한다.

// java에서의 객체 생성
class Student{
  int age;
  String name;
}

public class Stuent_Test {
  public static void main(String[] args) {
      Student s = new Student(); // 객체 생성
      s.age = 27;
      s.name = "주영";
      System.out.println(s.age, s.name);
  }
}

하지만 자바스크립트는 프로토타입 기반 객체 지향 언어로서 클래스라는 개념이 없고 별도의 객체 생성 방법이 존재한다.

1. 객체 리터럴

가장 일반적인 자바스크립트의 객체 생성 방식이다.

var person = {
  name : 'son',
  age : 27,
  sayHello : function () {
    console.log('Hi my name is ' + this.name);
  }
};
console.log(typeof person);
console.log(person);
person.sayHello();

2. Object 생성자 함수

new 연산자와 Object 생성자 함수를 호출하여 빈 객체를 생성할 수 있다. 빈 객체 생성 이후 프로퍼티 또는 메소드를 추가하여 객체를 완성하는 방법이다.

var person = new Object();
person.name = 'son';
person.age = 27;
person.sayHello = function () {
  console.log('Hi my name is ' + this.name);
};
console.log(typeof person);
console.log(person);
person.sayHello();

3. 생성자 함수

생성자 함수를 사용하면 객체를 생성하기 위한 템플릿(클래스)처럼 사용하여 동일 프로퍼티를 갖는 객체를 만들 때 유용하다.

예를 들어서 Object 생성자 함수를 통해 동일한 프로퍼티를 같는 person2를 생성하려면 같은 코드를 2번을 반복해야한다.

var person = new Object();
person.name = 'son';
person.age = 27;
person.sayHello = function () {
  console.log('Hi my name is ' + this.name);
};

var person2 = new Object();
person2.name = 'jung';
person2.age = 31;
person2.sayHello = function () {
  console.log('Hi my name is ' + this.name);
};

하지만 생성자 함수를 사용하면 위와 같은 코드가 아래와 같이 바뀔 수 있다.

function Person(name, age) {
  var job = true;              //private
  this.name = name;            //public
  this.age = age;              //public
  this.sayHello =function () { //public
    console.log('Hi my name is ' + this.name);
  };
}

let person1 = new Person('son',27);
let person2 = new Person('jung', 31);

console.log('person1: ', person1); // person1:  Person {name: "son", age: 27, sayHello: ƒ (), constructor: Object}
console.log('person2: ', person2); // person2:  Person {name: "jung", age: 31, sayHello: ƒ (), constructor: Object}

person1.sayHello(); // Hi my name is son 
person2.sayHello(); // Hi my name is jung

console.log(person1.job); // undefined

그리고 생성자 함수의 특징이 있는데 이에 대해 조금 더 알아보자.

  • 생성자 함수 이름은 일반적으로 대문자로 시작한다. 특별한 기능때문이라기 보다 이것은 생성자 함수임을 인식하도록 도움을 준다.
  • 프로퍼티 또는 메소드명 앞에 기술한 this는 생성자 함수가 생성할 인스턴스(instance)를 가리킨다.
  • this에 연결(바인딩)되어 있는 프로퍼티와 메소드는 public(외부에서 참조 가능)하다.
  • 생성자 함수 내에서 선언된 일반 변수는 private(외부에서 참조 불가능)하다. 즉, 생성자 함수 내부에서는 자유롭게 접근이 가능하나 외부에서 접근할 수 없다.

여기서 4번째 특징private은 코드 맨 밑에 있는 console.log(person1.job); 부분인데, 이해가 되지 않는다면 closure에 대해 이해해야 한다.

객체 프로퍼티 접근

객체를 생성하는 방법에 대해 알아봤으니 이제 객체 안에 있는 프로퍼티 값을 가지고 놀아보자.

1. 프로퍼티 키

프로퍼티 키는 일반적으로 문자열로 지정한다. 프로퍼티 키에 문자열이나 symbol 값 이외의 값을 지정하면 암묵적으로 문자열로 타입이 변환된다. 프로퍼티 키는 문자열임으로 따옴표('' 또는 "")를 사용한다. 하지만 자바스크립트에서 사용 가능한 유효한 이름일 경우 따옴표를 생략할 수 있다.

var person1 = {
  'first-name' : 'son',
  gender : 'male'
}
var person2 = {
  second_name : 'jung'
}

여기서 -는 연산자이기 때문에 사용 가능한 유효한 이름이 아니다. 그래서 first-name은 ''를 이용해 문자열로 바꿨지만, second_name은 감싸주지 않았다.

예약어를 프로퍼티 키로 사용하여도 에러는 발생하지 않는다. 하지만 예상하지 못할 에러가 발생할 수 있으므로 예약어를 프로퍼티의 키로 사용하면 안된다.

abstract  arguments boolean break byte
case  catch char  class*  const
continue  debugger  default delete  do
double  else  enum* eval  export*
extends*  false final finally float
for function  goto  if  implements
import* in  instanceof  int interface
let long  native  new null
package private protected public  return
short static  super*  switch  synchronized
this  throw throws  transient true
try typeof  var void  volatile
while with  yield
// *는 ES6에서 추가된 예약어

2. 프로퍼티 삭제

delete 연산자를 사용하면 객체의 프로퍼티를 삭제할 수 있다. 하지만 javaScript의 프로퍼티는 undefined나 null을 할당한다고 삭제되지 않기 때문에 반드시 delete를 사용하여 프로퍼티를 삭제해주어야 한다.

var person = {
  'first-name' : undefined, 
  gender : 'male',
};
console.log(person['first-name']); // undefined
delete person['first-name'];
console.log(person); // {gender: "male"}

3. 프로퍼티 값 읽기

객체의 프로퍼티 값에 접근하는 방법은 점(.)표기법과 대괄호([])표기법이 있다.

var person = {
  'first-name': 'Ung-mo',
  'last-name': 'Lee',
  gender: 'male',
  1: 10
};

console.log(person);

console.log(person.first-name);    // NaN: undefined-undefined
console.log(person[first-name]);   // ReferenceError: first is not defined
console.log(person['first-name']); // 'Ung-mo'

console.log(person.gender);    // 'male'
console.log(person[gender]);   // ReferenceError: gender is not defined
console.log(person['gender']); // 'male'

console.log(person['1']); // 10
console.log(person[1]);   // 10 : person[1] -> person['1']
console.log(person.1);    // SyntaxError

프로퍼티 키가 유효한 자바스크립트 이름이고 예약어가 아닌 경우 프로퍼티 값은 점, 대괄호 표기법 둘 다 사용할 수 있다.

반대의 경우 프로퍼티 값은 대괄호 표기법으로 읽어야 한다. 그리고 대괄호 표기법을 사용하는 경우 대괄호 내에 들어가는 프로퍼티 이름은 반드시 문자열이어야 한다.

4. 프로퍼티 값 갱신

객체가 소유하고 있는 프로퍼티에 새로운 값을 할당하면 프로퍼티 값은 갱신된다.

var person = {
  name: 'son'
};

person.name = 'jung';
console.log(person.name ); // 'jung'

5. 프로퍼티 동적 생성

객체가 소유하고 있지 않은 프로퍼티의 키에 값을 할당하면 주어진 키와 값으로 프로퍼티를 생성하여 객체에 추가한다.

var person = {
  name: 'son'
};

person.age = 27;
console.log(person); // name: "son", age: 27}

Reference

profile
느리지만 확실하게

0개의 댓글