티스토리 뷰

728x90
SMALL

객체 리터럴

객체는 변경 가능(mutable)한 값이다.

객체는 프로퍼티(프로퍼티 키, 프로퍼티 값)와 메서드로 구성된다.

자바스크립트는 프로토타입 기반 객체지향 언어다. 따라서 다양한 객체 생성 방법을 가진다.

1. 객체 리터럴

2. Object 생성자 함수

3. 생성자 함수

4. Object.creeate 메서드

5. 클래스

 

프로퍼티 키에는 네이밍 규칙을 따르거나 ''를 사용해야 한다.

프로퍼티에 접근할 때는 마침표 표기법과 대괄호 표기법이 있다.

대괄호 프로퍼티 접근 연산자 내부에 지정하는 프로퍼티 키는 반드시 따옴표로 감싼 문자열이어야 한다.

네이밍 규칙을 따르지 않았다면 반드시 대괄호 표기법으로 접근해야 한다.

추가 수정 삭제 가능(삭제는 delete person.age)

 

ES6 객체 리터럴 확장 기능

프로퍼티 축약 (const obj={x,y};)

메서드 축약(sayHi(){})

 

원시값과 객체의 비교

객체와 원시 값의 차이점

1. 원시 값은 immutable value, 객체는 mutable value

2. 원시 값을 변수에 할당하면 변수에는 실제 값이 저장, 객체를 변수에 할당하면 변수에는 참조 값이 저장

3. 원시 값을 갖는 변수를 다른 변수에 할당하면 원시 값이 복사되어 전달(pass by value)(실제로는 주소)

   객체를 가리키는 변수를 다른 변수에 할당하면 원본의 참조 값이 복사되어 전달(pass by reference)

 

string은 유사 배열 객체이면서 이터러블이므로 배열과 유사하게 각 문자에 접근할 수 있다.

하지만 원시 값이므로 str[0]='S' 같은 방법으로 변경할 수 없다.

 

객체를 할당한 변수에는 생성된 객체가 실제로 저장된 메모리 공간의 주소가 저장되어 있다. (참조값)

변수는 이 참조 값을 토해 객체에 접근할 수 있다.

객체는 이러한 구조때문에 여러 개의 식별자가 하나의 객체를 공유할 수 있다.(얕은복사) (vs깊은복사)

=> pass by reference(참조에 의한 전달)

함수

함수 : 일련의 과정을 문(statement)으로 구성하고 코드 블록으로 감싸서 하나의 실행 단위로 정의한 것

매개변수(parameter) : 함수 내부로 입력을 전달받는 변수    function add(x,y)

입력, 인자(argument) : 입력                                         add(2,5)

반환값(return value) : 출력                                          return x+y

 

함수를 사용하는 이유 : 유지보수의 편의성 높이기, 코드의 신뢰성 높이기, 코드의 가독성 향상

가독성이 좋은 코드(함수)가 좋은 코드(함수)다.

함수 리터럴

var f=function add(x,y){
  return x+y;
}

 

일반 객체는 호출할 수 없지만 함수는 호출할 수 있다. 함수는 객체다.(다른 언어와 달라)

 

함수 정의

1. 함수 선언문 (일반 함수) 

2. 함수 표현식 (위 함수 리터럴)

3. Function 생성자 함수 (var add=new Function('x','y','return x+y');)

4. 화살표 함수 (var add=(x,y)=>x+y;)

함수 선언문은 표현식이 아닌 문이다.

함수 표현식으로 정의한 함수는 함수 표현식 이전에 호출할 수 없다.(변수 호이스팅)

화살표 함수는 생성자 함수로 사용할 수 없으며, 기존 함수와 this 바인딩 방식이 다르고, prototype 프로퍼티가 없으며 arguments 객체를 생성하지 않는다.

 

함수를 호출할 때 인자가 적거나 많으면 어떻게 작동하나요??

적으면 인자(argument) 수 다음부터의 매개변수(parameter)값은 undefined

많으면 매개변수를 넘어가는 인자는 무시된다. 단 arguments 객체의 프로퍼티로 보관

 

매개변수 기본값 적용하기(ES6)

function add(a=0,b=0,c=0){
  return a+b+c;
}

매개변수는 가급적 작게 만들어야 한다. 3개가 넘어간다면 객체로 지정하자

 

함수의 형태

1. 즉시 실행 함수

(function(){
  //...
}());

2. 재귀 함수 : 재귀사용

3. 중첩 함수 : 함수 내부에 정의된 함수

4. 콜백 함수 : 함수의 매개변수를 통해 다른 함수의 내부로 전달되는 함수

  고차 함수 : 매개 변수를 통해 함수의 외부에서 콜백 함수를 전달받은 함수

5. 순수 함수와 비순수 함수

  순수 함수 : 부수 효과가 없는함수(어떤 외부 상태에 의존하지도 않고 변경하지도 않는)

  비순수 함수 : 부수 효과가 있는 함수(외부 상태에 의존하거나 외부 상태를 변경)

 

함수형 프로그래밍 : 순수 함수와 보조 함수의 조합을 통해 외부 상태를 변경하는 부수 효과를 최소화해서 불변성(immutable)을 지향하는 프로그래밍 패러다임

 

스코프

스코프(범위) : 식별자가 유효한 범위(변수 이름, 함수 이름, 클래스 이름 등)

스코프의 종류 : 전역, 지역

스코프는 함수의 중첩에 의해 계층적 구조를 갖는다.

스코프 체인 : 스코프가 계층적으로 연결된 것

변수를 참조할 때 자바스크립트 엔진은 스코프 체인을 통해 변수를 참조하는 코드의 스코프에서 시작하여 상위 스코프 방향으로 이동하며 선언된 변수를 검색한다.

상위 스코프에서 유효한 변수는 하위 스코프에서 자유롭게 참조할 수 있지만 하위 스코프에서 유효한 변수를 상위 스코프에서 참조할 수 없다.

var 키워드로 선언된 변수는 오로지 함수의 코드 블록만을 지역 스코프로 인정한다. 함수 레벨 스코프

let, const 키워드는 블록 레벨 스코프 지원

동적 스코프 : 함수를 어디서 호출했는지에 따라 함수의 스코프를 결정

렉시컬 스코프 : 함수를 어디서 정의했는지에 따라 함수의 상위 스코프를 결정 (자바스크립트 포함 대부분 언어들)

var x=1;
function foo(){
    var x=10;
    bar();
}
function bar(){
    console.log(x);
}
foo(); //1
bar(); //1

 

호이스팅은 스코프를 단위로 동작한다.

 

전역 변수의 문제점

전역 변수의 문제점

1. 암묵적 결합(변수의 유효 범위가 클수록 코드의 가독성은 나빠지고 위험성도 높아진다.)

2. 긴 생명주기

3. 스코프 체인 상에서 종점에 존재(전역 변수의 검색 속도가 가장 느리다.)

4. 네임스페이스 오염(파일이 분리되어 있다 해도 자스는 하나의 전역 스코프를 공유한다.)

 

전역 변수의 사용을 억제하는 방법

1. 즉시 실행 함수

2. 네임스페이스 객체

3. 모듈 패턴 : 클래스를 모방해서 관련이 있는 변수와 함수를 모아 즉시 실행 함수로 감싸 하나의 모듈을 만든다. 모듈 패턴은 클로저를 기반으로 동작한다. 모듈 패턴의 특징은 전역 변수의 억제는 물론 캡슐화까지 구현할 수 있다는 것이다.

 *캡슐화 : 객체의 상태를 나타내는 프로퍼티

var Counter = (function () {
  // private 변수
  var num = 0;

  // 외부로 공개할 데이터나 메서드를 프로퍼티로 추가한 객체를 반환한다.
  return {
    increase() {
      return ++num;
    },
    decrease() {
      return --num;
    },
  };
})();

// private 변수는 외부로 노출되지 않는다.
console.log(Counter.num); // undefined

console.log(Counter.increase()); // 1
console.log(Counter.increase()); // 2
console.log(Counter.decrease()); // 1
console.log(Counter.decrease()); // 0

4. ES6 모듈

<script type="module" src="lib.mjs"></script>

<script type="module" src="app.mjs"></script>

아직까지는 ES6 모듈보다는 Webpack 등의 모듈 번들러를 사용하는 것이 일반적

 

let, consts 키워드와 블록 레벨 스코프

var 키워드로 선언한 변수의 문제점

1. 변수 중복 선언 허용

2. 함수 레벨 스코프

3. 변수 호이스팅

 

let 키워드

1. 변수 중복 선언 금지

2. 블록 레벨 스코프

3. 변수 호이스팅 : 변수 호이스팅이 발생하지 않는 것처럼 동작한다.

let 키워드로 선언한 변수는 선언 단계와 초기화 단계가 분리되어 진행된다.

let 키워드로 선언한 전역 변수는 전역 객체의 프로퍼티가 아니다.(window.x)

let 전역 변수는 보이지 않는 개념적인 블록 내에 존재하게 된다.

 

const 키워드

const 키워드는 상수를 선언하기 위해 사용한다. 하지만 반드시 상수만을 위해 사용하지는 않는다.

선언과 동시에 초기화

원시 값 재할당 금지

객체를 할당한 경우 값 변경 가능(재할당을 금지할 뿐 '불변'을 의미하지는 않는다.)

 

*객체를 선언할 때는 일단 const 키워드를 사용. 만약 재할당이 필요하다면 그때 바꿔

 

프로퍼티 어트리뷰트

내부 슬롯과 내부 메서드는 자바스크립트 엔진의 구현 알고리즘을 설명하기 위해 ECMAScript 사용에서 사용하는 의사 프로퍼티와 의사 메서드다. 예를들어 [[Prototype]] 내부 슬롯의 경우 __proto__를 통해 간접적으로 접근 가능

 

자바스크립트 엔진은 프로퍼티를 생성할 때 프로퍼티의 상태를 나타내는 프로퍼티 어트리뷰트를 기본값으로 자동 정의

프로퍼티의 상태 : 프로퍼티의 값value, 값의 갱신 가능 여부writable, 열거 가능 여부enumerable, 재정의 가능 여부configurable

writable : false이면 value 값을 변경할 수 없는 읽기 전용 프로퍼티

enumerable : false이면 해당 프로퍼티는 for ... in 이나 Object.keys 메서드 등으로 열거 불가능

configurable이 false면 삭제, 변경 불가능(단, writable이 true인 경우 value의 변경과 writable을 false로 변경 가능(

 

프로퍼티 어트리뷰트는 내부 상태 값인 내부 슬롯 [[Value]], [[Writable]], [[Enumerable]], [[Configurable]]

Object.getOwnPropertyDescriptor 메서드로 간접 확인.   매개변수(객체의 참조, 프로퍼티 키)

Object.getOwnPropertyDescriptors(객체)로 모든 프로퍼티 디스크립터 객체 반환

 

프로퍼티는 데이터 프로퍼티와 접근자 프로퍼티로 구분할 수 있다.

데이터 프로퍼티 : 키와 값으로 구성된 일반적인 프로퍼티

 프로퍼티 어트리뷰트 : value, writable, enumerable, configurable

접근자 프로퍼티 : 자체적으로는 값을 갖지 않고 다른 데이터 프로퍼티의 값을 읽거나 저장할 때 호출되는 접근자 함수로 구성된 프로퍼티다.

 프로퍼티 어트리뷰트 : get, set, enumerable, configurable

const person = {
  // 데이터 프로퍼티
  firstName: 'Ungmo',
  lastName: 'Lee',

  // fullName은 접근자 함수로 구성된 접근자 프로퍼티다.
  // getter 함수
  get fullName() {
    return `${this.firstName} ${this.lastName}`;
  },
  // setter 함수
  set fullName(name) {
    // 배열 디스트럭처링 할당: "31.1 배열 디스트럭처링 할당" 참고
    [this.firstName, this.lastName] = name.split(' ');
  },
};

// 데이터 프로퍼티를 통한 프로퍼티 값의 참조.
console.log(person.firstName + ' ' + person.lastName); // Ungmo Lee

// 접근자 프로퍼티를 통한 프로퍼티 값의 저장
// 접근자 프로퍼티 fullName에 값을 저장하면 setter 함수가 호출된다.
person.fullName = 'Heegun Lee';
console.log(person); // {firstName: "Heegun", lastName: "Lee"}

// 접근자 프로퍼티를 통한 프로퍼티 값의 참조
// 접근자 프로퍼티 fullName에 접근하면 getter 함수가 호출된다.
console.log(person.fullName); // Heegun Lee

// firstName은 데이터 프로퍼티다.
// 데이터 프로퍼티는 [[Value]], [[Writable]], [[Enumerable]], [[Configurable]] 프로퍼티 어트리뷰트를 갖는다.
let descriptor = Object.getOwnPropertyDescriptor(person, 'firstName');
console.log(descriptor);
// {value: "Heegun", writable: true, enumerable: true, configurable: true}

// fullName은 접근자 프로퍼티다.
// 접근자 프로퍼티는 [[Get]], [[Set]], [[Enumerable]], [[Configurable]] 프로퍼티 어트리뷰트를 갖는다.
descriptor = Object.getOwnPropertyDescriptor(person, 'fullName');
console.log(descriptor);
// {get: ƒ, set: ƒ, enumerable: true, configurable: true}

 

내부 동작 [[Get]]

1. 프로퍼티 키가 유효한지 확인한다. 프로퍼티 키는 문자열 또는 심벌이어야 한다. 프로퍼티 키 'fullName'은 문자열이므로 유효한 프로퍼티 키다.

2. 프로토타입 체인에서 프로퍼티를 검색한다. person 객체에 fullName 프로퍼티가 존재한다.

3. 검색된 fullName 프로퍼티가 데이터 프로퍼티인지 접근자 프로퍼티인지 확인한다. fullName 프로퍼티는 접근자 프로퍼티다.

4. 접근자 프로퍼티 fullName의 프로퍼티 어트리뷰트 [[Get]]의 값, 즉 getter 함수를 호출하여 그 결과를 반환한다. 프로퍼티 fullName의 프로퍼티 어트리뷰트 [[Get]]의 값은 Object.getOwnPropertyDescriptor 메서드가 반환하는 프로퍼티 디스크립터 객체의 get 프로퍼티 값과 같다.

 

// 일반 객체의 __proto__는 접근자 프로퍼티다.
Object.getOwnPropertyDescriptor(Object.prototype, '__proto__');
// {get: ƒ, set: ƒ, enumerable: false, configurable: true}

// 함수 객체의 prototype은 데이터 프로퍼티다.
Object.getOwnPropertyDescriptor(function() {}, 'prototype');
// {value: {...}, writable: true, enumerable: false, configurable: false}

 

Object.defineProperty 메서드로 프로퍼티의 어트리뷰트를 정의 가능

object.defineProperties 메서드로 여러 개의 프로퍼티 한 번에 정의 가능

const person = {};

// 데이터 프로퍼티 정의
Object.defineProperty(person, 'firstName', {
  value: 'Ungmo',
  writable: true,
  enumerable: true,
  configurable: true
});

Object.defineProperty(person, 'lastName', {
  value: 'Lee'
});

let descriptor = Object.getOwnPropertyDescriptor(person, 'firstName');
console.log('firstName', descriptor);
// firstName {value: "Ungmo", writable: true, enumerable: true, configurable: true}

// 디스크립터 객체의 프로퍼티를 누락시키면 undefined, false가 기본값이다.
descriptor = Object.getOwnPropertyDescriptor(person, 'lastName');
console.log('lastName', descriptor);
// lastName {value: "Lee", writable: false, enumerable: false, configurable: false}

// [[Enumerable]]의 값이 false인 경우
// 해당 프로퍼티는 for...in 문이나 Object.keys 등으로 열거할 수 없다.
// lastName 프로퍼티는 [[Enumerable]]의 값이 false이므로 열거되지 않는다.
console.log(Object.keys(person)); // ["firstName"]

// [[Writable]]의 값이 false인 경우 해당 프로퍼티의 [[Value]]의 값을 변경할 수 없다.
// lastName 프로퍼티는 [[Writable]]의 값이 false이므로 값을 변경할 수 없다.
// 이때 값을 변경하면 에러는 발생하지 않고 무시된다.
person.lastName = 'Kim';

// [[Configurable]]의 값이 false인 경우 해당 프로퍼티를 삭제할 수 없다.
// lastName 프로퍼티는 [[Configurable]]의 값이 false이므로 삭제할 수 없다.
// 이때 프로퍼티를 삭제하면 에러는 발생하지 않고 무시된다.
delete person.lastName;

// [[Configurable]]의 값이 false인 경우 해당 프로퍼티를 재정의할 수 없다.
// Object.defineProperty(person, 'lastName', { enumerable: true });
// Uncaught TypeError: Cannot redefine property: lastName

descriptor = Object.getOwnPropertyDescriptor(person, 'lastName');
console.log('lastName', descriptor);
// lastName {value: "Lee", writable: false, enumerable: false, configurable: false}

// 접근자 프로퍼티 정의
Object.defineProperty(person, 'fullName', {
  // getter 함수
  get() {
    return `${this.firstName} ${this.lastName}`;
  },
  // setter 함수
  set(name) {
    [this.firstName, this.lastName] = name.split(' ');
  },
  enumerable: true,
  configurable: true
});

descriptor = Object.getOwnPropertyDescriptor(person, 'fullName');
console.log('fullName', descriptor);
// fullName {get: ƒ, set: ƒ, enumerable: true, configurable: true}

person.fullName = 'Heegun Lee';
console.log(person); // {firstName: "Heegun", lastName: "Lee"}

객체 변경 방지

Object.is~~(Seal) 함수로 확인 가능

이 함수들은 얕은 변경 방지를 하기 때문에 중첩 객체의 변경을 막으려면 모든 프로퍼티에 대해 적용해야 한다.

 

생성자 함수에 의한 객체 생성

동일한 프로퍼티를 갖는 객체를 여러 개 생성해야 하는 경우 객체 리터럴을 사용하는 것은 비효율적이다. 따라서 생성자 함수를 이용한다.

// 생성자 함수
function Circle(radius) {
  // 생성자 함수 내부의 this는 생성자 함수가 생성할 인스턴스를 가리킨다.
  this.radius = radius;
  this.getDiameter = function () {
    return 2 * this.radius;
  };
}

 

this

함수 호출 방식 -this가 가리키는 값(this 바인딩)

일반 함수로서 호출 - 전역 객체

메서드로서 호출 - 메서드를 호출한 객체

생성자 함수로서 호출 - 생성자 함수가 생성할 인스턴스

 

자바스크립트에서는 일반 함수와 동일한 방법으로 생성자 함수를 정의하고 new 연산자와 함께 호출하면 해당 함수는 생성자 함수로 동작한다.

 

생성자 함수의 역할은 프로퍼티 구조가 동일한 인스턴스를 생성하기 위한 템플릿(클래스)으로서 동작할 인스턴스를 생성하는 것과 생성된 인스턴스를 초기화(인스턴스 프로퍼티 추가 및 초기값 할당)하는 것이다.

function Circle(radius) {
  // 1. 암묵적으로 인스턴스가 생성되고 this에 바인딩된다.

  // 2. this에 바인딩되어 있는 인스턴스를 초기화한다.
  this.radius = radius;
  this.getDiameter = function () {
    return 2 * this.radius;
  };

  // 3. 암묵적으로 this를 반환한다.
  // 명시적으로 원시값을 반환하면 원시값 반환은 무시되고 암묵적으로 this가 반환된다.
  return 100;
}

* 객체 지향 프로그래밍(OOP)에서 인스턴스(instance)는 해당 클래스의 구조로 컴퓨터 저장공간에서 할당된 실체를 의미한다. 여기서 클래스는 속성과 행위로 구성된 일종의 설계도이다. OOP에서 객체는 클래스와 인스턴스를 포함한 개념이다. (출처 - 위키백과)

*바인딩 : 식별자와 값을 연결하는 과정

 

내부 메서드 [[Call]]과 [[Construct]]

함수는 객체이지만 일반 객체와는 다르다. 일반 객체는 호출할 수 없지만 함수는 호출할 수 있다.

함수는 [[Environment]], [[FormalParameters]] 등의 내부 슬롯과 [[Call]], [[Construct]] 같은 내부 메서드를 가지고 있다.

함수가 일반 함수로서 호출되면 함수 객체의 내부 메서드 [[Call]]이 호출되고 new 연산자와 함께 생성자 함수로서 호출되면 내부 메서드 [[Construct]]가 호출된다.

[[Call]]을 갖는 함수 객체를 callable이라 하며, [[Construct]]를 갖는 함수 객체를 constructor, 없으면 non-constructor

모든 함수 객체는 callable이지만 모든 함수 객체가 constructor인 것은 아니다.

constructor : 함수 선언문, 함수 표현식, 클래스

non-constructor : 메서드(ES6 메서드 축약 표현), 화살표 함수

(함수를 프로퍼티 값으로 사용하면 일반적으로 메서드로 통칭하지만, ECMAScript 에서는 ES6의 메서드 축약 표현만을 의미)

new 연산자로 함수를 호출하면 construct가 호출된다. 단, 함수가 constructor 이어야 한다.

 

생성자 함수가 new 연산자 없이 호출되는 것을 방지하기 위해 파스칼 케이스 컨벤션을 사용한다 하더라도 실수는 발생할 수 있다. 따라서 ES6에서 new.target을 지원한다.(ie 제외)

function Circle(radius) {
  // 이 함수가 new 연산자와 함께 호출되지 않았다면 new.target은 undefined다.
  // new.target사용(ie 적용x)
  if (!new.target) {
    // new 연산자와 함께 생성자 함수를 재귀 호출하여 생성된 인스턴스를 반환한다.
    return new Circle(radius);
  }
  // ie적용
  if (!(this instanceof Circle)) {
    // new 연산자와 함께 호출하여 생성된 인스턴스를 반환한다.
    return new Circle(radius);
  }

  this.radius = radius;
  this.getDiameter = function () {
    return 2 * this.radius;
  };
}

 

함수와 일급 객체

일급 객체 조건

1. 무명의 리터럴로 생성할 수 있다. 즉, 런타임에 생성이 가능하다.

2. 변수나 자료구조(객체, 배열 등)에 저장할 수 있다.

3. 함수의 매개변수에 전달할 수 있다.

4. 함수의 반환값으로 사용할 수 있다.

 

함수 객체의 프로퍼티

1. arguments 프로퍼티

arguments 프로퍼티 값은 arguments 객체다. arguments 객체는 함수 호출 시 전다된 인수(argument)들의 정보를 담고 있는 순회 가능한(iterale) 유사 배열 객체(+이터러블)이며, 함수 내부에서 지역 변수처럼 사용된다.

arguments 객체는 매개변수 개수를 확정할 수 없는 가변 인자 함수를 구현할 때 유용하다.

function sum(...args){
  return args.reduce((acc,cur)=>acc+cur,0);
}
function sum(){
  const arr=[...arguments];
  return arr.reduce((acc,cur)=>acc+cur,0);
}
function sum() {
  // arguments 객체를 배열로 변환
  const array = Array.prototype.slice.call(arguments);
  return array.reduce(function (pre, cur) {
    return pre + cur;
  }, 0);
}
console.log(sum(1,2,3,4,5));

 

2. caller 프로퍼티

ECMAScript 사양에 포함x 비표준 프로퍼티

함수 객체의 caller 프로퍼티는 함수 자신을 호출한 함수를 가리킨다.

function foo(func) {
  return func();
}

function bar() {
  return 'caller : ' + bar.caller;
}

// 브라우저에서의 실행한 결과
console.log(foo(bar)); // caller : function foo(func) {...}
console.log(bar());    // caller : null

 

3. length 프로퍼티

함수를 정의할 때 선언한 매개변수의 개수를 가리킨다. (arguments 객체의 length와 객체의 length는 다를수도 

function baz(x, y) {
  return x * y;
}
console.log(baz.length); // 2

 

4. name 프로퍼티

함수 이름을 나타낸다. (함수를 호출할 때는 함수 이름이 아닌 함수 객체를 가리키는 식별자로 호출한다.)

// 기명 함수 표현식
var namedFunc = function foo() {};
console.log(namedFunc.name); // foo

// 익명 함수 표현식
var anonymousFunc = function() {};
// ES5: name 프로퍼티는 빈 문자열을 값으로 갖는다.
// ES6: name 프로퍼티는 함수 객체를 가리키는 변수 이름을 값으로 갖는다.
console.log(anonymousFunc.name); // anonymousFunc

// 함수 선언문(Function declaration)
function bar() {}
console.log(bar.name); // bar

 

5. __proto__ 접근자 프로퍼티

모든 객체는 [[Prototype]]이라는 내부 슬롯을 갖는다. 이 내부 슬롯은 객체지향 프로그래밍의 상속을 구현하는 프로토타입 객체를 가리킨다. __proto__ 프로퍼티는 이 내부 슬롯이 가리키는 프로토타입 객체에 접근하기 위해 사용하는 접근자 프로퍼티다.

const obj = { a: 1 };

// 객체 리터럴 방식으로 생성한 객체의 프로토타입 객체는 Object.prototype이다.
console.log(obj.__proto__ === Object.prototype); // true

// 객체 리터럴 방식으로 생성한 객체는 프로토타입 객체인 Object.prototype의 프로퍼티를 상속받는다.
// hasOwnProperty 메서드는 Object.prototype의 메서드다.
console.log(obj.hasOwnProperty('a'));         // true
console.log(obj.hasOwnProperty('__proto__')); // false

 

6. prototype 프로퍼티

prototype 프로퍼티는 생성자 함수로 호출할 수 있는 함수 객체, 즉 constructor만이 소유하는 프로퍼티다.

728x90
LIST
댓글
공지사항