다진 Javascript (7)

Kyle·2022년 6월 13일
0

Javascript

목록 보기
7/11
post-thumbnail

✔모던 자바스크립트 10장

참고 - https://poiemaweb.com/

객체

1. 객체(object)란?

https://velog.io/@imjkim49/자바스크립트-데이터-타입-정리

자바스크립트는 객체 기반의 스크립트 언어이며, 자바스크립트를 이루고 있는 거의 “모든 것”이 객체

자바스크립트의 함수는 일급 객체이므로 값으로 취급 = 메소드

객체는 데이터를 의미하는 프로퍼티(키 + 값) + 메소드(method)로 구성된 집합

자바스크립트의 객체는 객체지향의 상속을 구현하기 위해 프로토타입(객체의 프로퍼티와 메소드) 상속 가능

1-1. 프로퍼티

프로퍼티 = 프로퍼티 키 + 프로퍼티 값

  • 프로퍼티 키 : 빈 문자열을 포함하는 모든 문자열 또는 symbol 값

                     👉 프로퍼티는 프로퍼티 키로 유일하게 식별할 수 있기 때문에 
    
                         프로퍼티 키는 프로퍼티를 식별하기 위한 식별자(identifier)이다.
  • 프로퍼티 값 : 모든 값

1-2. 메소드

메소드는 객체에 제한되어 있는 함수 (프로퍼티 값이 함수일 경우, 일반 함수와 구분하기 위해 메소드라 부름)

2. 객체 생성 방법

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

2-1. 객체 리터럴

중괄호 {} 를 사용하여 객체를 생성하는 방법

  • {} 내에 1개 이상의 프로퍼티를 기술하면 해당 프로퍼티가 추가된 객체를 생성 가능
  • {} 내에 아무것도 기술하지 않으면 빈 객체가 생성
var emptyObject = {};
console.log(typeof emptyObject); // object

var person = {
  name: 'Lee',
  gender: 'male',
  sayHello: function () {
    console.log('Hi! My name is ' + this.name);
  }
};

console.log(typeof person); // object
console.log(person); // {name: "Lee", gender: "male", sayHello: ƒ}

person.sayHello(); // Hi! My name is Lee

2-2. Object 생성자 함수

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

  • 생성자(constructor) 함수 : new 키워드와 함께 객체를 생성하고 초기화하는 함수
  • 인스턴스(instance) : 생성자 함수를 통해 생성된 객체
// 빈 객체의 생성
var person = new Object();

// 프로퍼티 추가
person.name = 'Lee';
person.gender = 'male';
person.sayHello = function () {
  console.log('Hi! My name is ' + this.name);
};

console.log(typeof person); // object
console.log(person); // {name: "Lee", gender: "male", sayHello: ƒ}

person.sayHello(); // Hi! My name is Lee

객체가 소유하고 있지 않은 프로퍼티 키에 값을 할당 👉 해당 객체에 프로퍼티를 추가하고 값을 할당

이미 존재하는 프로퍼티 키에 새로운 값을 할당 👉 프로퍼티 값은 할당한 값으로 변경

💡 객체 생성은 객체 리터럴 방법이 더 간단하지만, 객체 리터럴 방식도 결국 빌트인 함수인 object 생성자 함수로 객체 생성하는 것을 단순화한 축약표현이라 객체 리터럴 방법 사용시 내부적으로는 object 생성자 함수로 객체 생성

2-3. 생성자 함수

객체 리터럴 방식, Object 생성자 함수 방식 👉 프로퍼티 값만 다른 여러 개의 객체를 생성할 때 불편

생성자 함수 사용 👉 프로퍼티가 동일한 객체 여러 개를 간편하게 생성 가능

// 생성자 함수
function Person(name, gender) {
  this.name = name;
  this.gender = gender;
  this.sayHello = function(){
    console.log('Hi! My name is ' + this.name);
  };
}

// 인스턴스의 생성
var person1 = new Person('Lee', 'male');
var person2 = new Person('Kim', 'female');

console.log('person1: ', typeof person1);
console.log('person2: ', typeof person2);
console.log('person1: ', person1);
console.log('person2: ', person2);

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

3. 객체 프로퍼티 접근

3-1. 프로퍼티 키

프로퍼티 키는 일반적으로 문자열(빈 문자열 포함)을 지정

  • 프로퍼티 키에 문자열이나 symbol 값 이외의 값을 지정하면 암묵적으로 타입이 변환되어 문자열이 된다.
  • 프로퍼티 키는 문자열이므로 따옴표(‘’ 또는 ““)를 사용하지만 자바스크립트에서 사용 가능한 유효한 이름인 경우, 따옴표를 생략할 수 있다.
  • 표현식을 프로퍼티 키로 사용하려면 키로 사용할 표현식을 대괄호로 묶어야 한다.
  • 예상치 못한 에러가 발생할 수 있으므로 예약어를 프로퍼티 키로 사용해서는 안된다.
var person = {
  'first-name': 'Ung-mo',
  'last-name': 'Lee',
  gender: 'male',
  1: 10,
  function: 1 // OK. 하지만 예약어는 사용하지 말아야 한다.
};

console.log(person);

3-2. 프로퍼티 값 읽기

객체의 프로퍼티 값에 접근하는 방법

  • 마침표 . 표기법

  • 대괄호 [] 표기법 (대괄호 내에 들어가는 프로퍼티 이름은 반드시 문자열)

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

프로퍼티 키가 유효한 자바스크립트 이름이고 예악어가 아닌 경우 👉 마침표 표기법, 대괄호 표기법 모두 사용

프로퍼티 키가 유효한 자바스크립트 이름이 아니거나 예약어인 경우 👉 대괄호 표기법

3-3. 프로퍼티 값 갱신

객체가 소유하고 있는 프로퍼티에 새로운 값을 할당

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

person['first-name'] = 'Kim';
console.log(person['first-name'] ); // 'Kim'

3-4. 프로퍼티의 동적 생성

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

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

person.age = 20;
console.log(person.age); // 20

3-5. 프로퍼티 삭제

delete 연산자 사용

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

delete person.gender;
console.log(person.gender); // undefined

3-6. for-in 문

객체의 프로퍼티를 순회하기 위한 문법

  • for-in 문을 사용하면 객체(배열 포함)에 포함된 모든 프로퍼티에 대해 루프를 수행 가능
var person = {
  'first-name': 'Ung-mo',
  'last-name': 'Lee',
  gender: 'male'
};

// prop에 객체의 프로퍼티 이름이 반환된다. 단, 순서는 보장되지 않는다.
for (var prop in person) {
  console.log(prop + ': ' + person[prop]);
}

/*
first-name: Ung-mo
last-name: Lee
gender: male
*/

for–of 문

배열의 요소를 순회하기 위한 문법

  • 배열에는 사용하기 힘든 for-in 문의 단점 극복을 위해 만들어짐
const array = [1, 2, 3];
array.name = 'my array';

for (const value of array) {
  console.log(value);
}

/*
1
2
3
*/

for (const [index, value] of array.entries()) {
  console.log(index, value);
}

/*
0 1
1 2
2 3
*/

4. Pass-by-reference

객체가 참조(Reference) 방식으로 전달되는 것 (복사 X)

object type 👉 객체 타입, 참조 타입(객체의 모든 연산이 실제값이 아닌 참조값으로 처리)

객체는 프로퍼티를 변경, 추가, 삭제가 가능하므로 변경 가능(mutable)한 값

객체 타입은 동적으로 변화할 수 있으므로 어느 정도의 메모리 공간을 확보해야 하는지 예측할 수 없기 때문에 런타임에 메모리 공간을 확보하고 메모리의 힙 영역(Heap Segment)에 저장

var foo = {
  val: 10
}

var bar = foo;
console.log(foo.val, bar.val); // 10 10
console.log(foo === bar);      // true

bar.val = 20;
console.log(foo.val, bar.val); // 20 20
console.log(foo === bar);      // true

  1. foo 객체를 객체 리터럴 방식으로 생성

    👉 변수 foo는 객체 자체를 저장하고 있는 것이 아니라 생성된 객체의 참조값(address)를 저장

  2. 변수 bar에 변수 foo의 값을 할당

    👉 변수 foo의 값은 생성된 객체를 가리키는 참조값이므로 변수 bar에도 같은 참조값이 저장

    👉 변수 foo, bar 모두 동일한 객체를 참조

    👉 참조하고 있는 객체의 val 값이 변경되면 두 변수 모두 변경된 객체의 프로퍼티 값을 참조

5. Pass-by-value

원시타입이 값으로 전달 되는 것 (복사 O)

원시 타입은 값이 한번 정해지면 변경 불가(객체와 변경불가성)하고 이들 값은 런타임(변수 할당 시점)에 메모리의 스택 영역(Stack Segment)에 고정된 메모리 영역을 점유하고 저장

var a = 1;
var b = a;

console.log(a, b);    // 1  1
console.log(a === b); // true

a = 10;
console.log(a, b);    // 1  10
console.log(a === b); // false
  1. 변수 a에 원시 타입인 숫자 타입 1을 저장

    👉 원시 타입의 경우 값이 복사되어 변수에 저장되기 때문에 참조 타입이 아니라 값 자체가 저장

  2. 변수 b에 변수 a를 할당

    👉 변수 a의 값 1은 복사되어 변수 b에 저장

6. 객체의 분류

Built-in Object(내장 객체) :

웹페이지 등을 표현하기 위한 공통의 기능을 제공

웹페이지가 브라우저에 의해 로드되자마자 별다른 행위없이 바로 사용이 가능

Host Object(사용자 정의 객체) :

사용자가 생성한 객체들

constructor 혹은 객체리터럴을 통해 사용자가 객체를 정의하고 확장시킨 것들이기 때문에 Built-in Object 와 Native Object가 구성된 이후에 구성

profile
불편함을 고민하는 프론트엔드 개발자, 박민철입니다.

0개의 댓글