본문 바로가기

JavaScript

20210705 JavaSciprt DeepDive 03 : 스코프(전역, 지역, 함수, 블록, 동적, 정적), 변수 생명주기, 멤버, var, let, const, 프로퍼티 어트리뷰트, 생성자 함수, 함수객체, 일급객체, 함수객체 프로퍼티

JavaScript Deep Dive 03


용어 및 중요사항 정리


스코프

  • 스코프 : 식별자가 유효한 범위, 식별자를 검색(식별자 결정)할 때 사용하는 규칙
    • 모든 식별자는 자신이 선언된 위치에 의해 다른 코드가 식별자 자신을 참조할 수 있는 유효 범위가 결정됨
    • 변수의 이름이 동일한 식별자여도, 스코프가 다르면 별개의 변수임
    • 식별자인 변수 이름의 충돌 방지하여 같은 이름의 변수를 사용할 수 있게 함
    • 같은 스코프에서 식별자는 유일해야 하지만 다른 스코프에는 식별자를 동일하게 사용가능함으로 스코프는 네임스페이스임
    • var 키워드의 경우 같은 스코프내 중복 식별자 선언이 허용됨(덮어 씌워짐), let은 중복 식별자 선언 허용하지 않음

  • 전역 : 코드의 가장 바깥 영역, 전역 스코프 : 전역에서 만들어진 스코프
  • 전역 변수 : 전역에서 선언된 변수로 전역 스코프를 갖는 변수 (어디서든지 참조 가능)
  • 지역 : 함수 몸체 내부, 지역 스코프 : 지역에서 만들어진 스코프
  • 지역 변수 : 지역에서 선언된 변수로 지역 스코프를 갖는 변수 (자신의 지역스코프, 하위 지역 스코프에서 참조 가능)
  • 지역변수와 전역변수가 동일한 식별자이고, 지역변수에서 해당 식별자를 참조하는 경우 지역변수를 참조함 (지역변수가 우선됨)

  • 스코프 체인 : 스코프가 함수의 중첩에 의해 계층적 구조를 가져 계층적으로 연결된것을 말함 (전역 스코프 - 외부함수의 지역스코프 - 내부함수의 지역스코프)
    • 실행 컨텍스트의 렉시컬 환경을 단방향으로 연결한것
  • 변수 검색 : 변수 참조시 자바스크립트 엔진이 스코프 체인을 통해 참조 코드 스코프에서 상위 스코프 방향으로 이동하며 해당 스코프의 렉시컬 환경에서 변수를 검색하는 것
    • 상위로 올라가면서 변수를 찾게 되면, 해당 스코프의 검색된 변수를 참조하고 검색은 종료 됨
    • 절대로 하위 스코프로 내려가면서 검색하지 않음 -> 하위 스코프에서는 상위 스코프에서 자유롭게 참조가 가능하지만, 상위 스코프에서는 하위 스코프 참조가 불가함
  • 렉시컬 환경 : 변수 식별자를 key로, 변수에 할당된 값을 value로 갖는 자료구조로 각 스코프 별로 생기는 환경

  • 함수 레벨 스코프 : 코드블록이 아닌 함수(함수 몸체)에 의해서만 지역 스코프가 생성되는 것을 말함
    • var 키워드로 선언된 변수의 경우 함수레벨 스코프를 가지게 됨
  • 블록 레벨 스코프 : 코드블럭에 의해서만 지역 스코프가 생성되는 것을 말함
    • let, const 키워드로 선언된 변수는 블록레벨 스코프를 가지게됨 (대부분의 프로그래밍 언어가 이를 채택하고 있음)

  • 동적 스코프 : 함수를 어디서 호출했는지에 따라 함수의 상위 스코프를 결정하는 방식
    • 함수 호출 위치가 상위 스코프 결정에 영향을 줌
  • 렉시컬 스코프 or 정적 스코프 : 함수를 어디서 정의했는지에 따라 함수의 상위 스코프를 결정하는 방식
    • 자바스크립트는 렉시컬 스코프를 사용함
    • 함수 호출 위치가 상위 스코프 결정에 영향을 주지 않음 -> 언제나 자신이 정의된 스코프가 상위 스코프
var x = 1;
function foo() {
  // 상위 스코프는 전역 스코프
  var x = 10;
  bar(); // 상위 스코프는 전역 스코프
}

function bar() {
  //상위 스코프는 전역 스코프
  console.log(x);
}

foo(); // 1 console.log 부분은 전역 스코프를 참조함으로
bar(); // 1

전역 변수의 문제점


  • 변수의 생명주기 : 메모기 공간 확보 부터 ~ 메모리 공간 해제되어 가용메모리 풀에 반환되는 시점까지

  • 지역변수의 생명주기 : 함수가 호출되어 실행시 유효 ~ 함수 종료시 지역변수 소멸되어 생명주기 종료 , 함수의 생명주기와 일치
    • 단, 해당 변수의 스코프를 누군가 참조하고 있으면, 스코프는 해제되지 않고 생존함
    • 호이스팅은 스코프를 단위로 동작함 (함수 실행시 변수 선언이 호이스팅되어 undefined로 초기화 되고, 할당문이 실행될 때 특정 값이 할당됨)

  • 전역변수의 생명주기 : 코드 로드시 해석실행 ~ 마지막 문 실행후 종료
  • 전역 객체(global object) : 코드가 실행되기 이전 단계에 JS엔진에 의해 어떤 객체 보다도 먼저 생서외는 특수 객체
    • 브라우저 환경에서는 window 객체를 의미
    • NodeJS 환경에서는 global 객체를 의미
    • 전역 객체를 가르키는 식별자 : globalThis (ES11에서 통합됨)
    • 전역 객체의 프로퍼티 : 표준 빌트인 객체(Object, String, Number...), 호스트 객체(web API, nodejs의 호스트 API), var 키워드로 선언한 전역변수와 전역함수
      • 전역 객체 window는 웹페이지를 닫기 전까지 유효(var키워드 선언한 전역 변수의 생명주기 = 전역 객체의 생명주기)

  • 전역 변수의 문제점
    • 암묵적 결합 : 어디서든지 참조 할당 가능하므로, 모든 코드가 전역변수를 참조하고 변경가능함 -> 가독성 하락, 의도치 않는 상태변경으로 인한 위험성 증가
    • 긴 생명주기 : 메모리 소스를 오랜 기간 소비함
    • 스코프 체인 상에서 종점에 존재 : 변수 검색시 가장 마지막에 검색됨으로서 검색 속도가 가장 느리다
    • 네임스페이스 오염 : 파일 분리가 되어 있어도, 하나의 전역 스코프를 공유함

  • 전역변수 사용 억제방법 :
    • 모든 코드를 즉시 실행 함수로 감싸기 (라이브러리에서 자주 사용됨)
    • 네임스페이스 객체 생성하여 사용할 변수를 프로퍼티로 추가하기
    • 모듈 패턴 : 관련 변수와 함수를 모아 즉시 실행 함수로 감싸 하나의 모듈을 만듦 (클로저 기능을 통해 전역 변수 억제)

  • 캡슐화(encapsulation) : 객체의 상태를 나타내는 프로퍼티와, 프로퍼티를 참조하고 조작할 수 있는 메서드를 하나로 묶는 것을 말함
    • 전역 네임스페이스의 오염을 막는 기능, 정보 은닉에 사용됨
  • 퍼블릭 멤버(public member) : 즉시 실행함수가 반환하는 객체의 프로퍼티로 외부에 노출 되는 것들
  • 프라이빗 멤버(private member) : 즉시 실행함수가 반환하는 객체의 프로퍼티로 추가하지 않은 것들로 외부에 노출 시키지 않고 싶은 것들

  • ES6 모듈 : ES6 모듈의 경우 파일 자체의 독자적인 모듈 스코프를 제공함으로서 더이상 전역 변수를 사용할 수 없음
    • var 키워드의 변수는 전역 변수가 아니고, window 객체의 프로퍼티도 아니게 됨
    • <script type="module" src="app.mjs>
    • 아직 까지는 브라우저의 ES6 모듈 기능보다, Webpack 등의 모듈 번들러를 사용함

var vs let vs const


  • var키워드 변수 선언
    • 변수 중복 선언 허용 : 먼저 선언했던 변수 값이 변경되는 부작용 발생
    • 함수 레벨 스코프: 전역변수 남발할 가능성을 높임
    • 변수 호이스팅 : 변수 선언문 이전에 변수를 참조하는 것은 가독성을 떨어뜨리고 오류 발생 여지를 남김
      • 런타임 전에 변수가 선언 되었으면 undefined로 초기화되고 할당문 실행시 해당 값이 할당됨
      • 변수 호이스팅으로 변수 선언 문 전에도 참조할 수 있음

  • let 키워드 변수 선언
    • 변수 중복 선언 금지 : 같은 변수를 중복 선언하면 syntaxError 발생
    • 블록 레벨 스코프 : 모든 코드블록(함수, if, for, while, try/catch)을 지역 스코프로 인정함
    • 변수 호이스팅 : 선언 단계와 초기화 단계가 분리되어 진행됨 (호이스팅이 안되는 것처럼 보임)
      • 런타임 전에 선언문이 확인되어 호이스팅 되긴 하지만, 런타임에서 선언문이 실행되는 때 undefined로 초기화가 됨
      • 변수 선언 문 실행 전에 참조 불가 (ReferenceError 발생)
      • 하지만, 변수 검색은 잘 동작하여 해당 지역 스코프에 해당 변수가 있다는 것은 호이스팅이 됨
      • 일시적 사각지대 (TDZ) : 스코프 시작 지점 부터 ~ 초기화 시작 지점(선언문 실행지점)까지 해당 변수를 참조할 수 없는 구간을 말함
    • 전역객체와 let:
      • var 로 x 전역 변수 선언, var 없이 y전역변수에 값할당(암묵적으로 전역), 전역함수f 정의하는 경우 모두 window객체에 프로퍼티로 들어감
        • window.x, window.y, window.f
      • let으로 선언한 전역 변수는 window의 프로퍼티가 아님

  • const 키워드 변수 선언
    • 선언과 동시에 초기화 해야함 (const foo = 1;)
    • 블록 레벨 스코프이며, 변수 호이스팅이 발생하지 않는 것 처럼 동작
      • (즉, 해당 선언문이 런타임에 실행되어야 undefined로 초기화가 발생함, 그런데 바로 값을 할당하므로 해당 값으로 초기화가 됨)
    • 재할당 금지 (재할당이 금지이지, 불변을 의미하진 않음)
    • const 키워드로 선언한 변수에 원시값 할당시 변수값을 변경 불가함
    • const 키워드로 선언한 변수에 객체 값 할당시 변경가능한 값이라서 직접 변경 가능함, 자체를 재할당은 안되지만
    • 상수 : 재할당이 금지된 변수, 상수 이름은 대문자 스네이크 케이스로 표현하여 상수임을 명확히 나타냄

프로퍼티 어트리뷰트


  • 내부 슬롯, 내부 메서드 : 이중 대괄호로 감싼 이름들로 자바스크립트 엔진의 내부 로직이다.
    • 원칙적으로 직접 접근은 불가하지만 일부 내부 슬롯, 내부 메서드에 한하여 접근할 수 있음
  • 자바스크립트 엔진은 프로퍼티 생성시 프로퍼티의 상태를 나타내는 프로퍼티 어트리뷰트를 기본값으로 자동 정의함 (해당 값, true, true, true)

  • 프로퍼티의 상태(meta-property) : 프로퍼티의 값(value), 값의 갱신 가능 여부(writable), 열거 가능 여부(enumerable), 재정의 가능 여부(configurable)
    • 상태값인 내부 슬롯 :[[Value]], [[Writable]], [[Enumerable]], [[Configurable]]
    • Object.getOwnPropertyDescriptor() : 특정 객체의 특정 프로퍼티의 상태를 확인할 수 있음
      • 첫번째 인수 : 객체의 참조를 전달
      • 두번째 인수 : 프로퍼티 키를 문자열로 전달
      • 함수의 결과로 프로퍼티 디스크립터 객체(PropertyDescriptor)를 반환함
        • {value: 'kim', writable: true, enumerable: ture, configurable: true}
      • 존재하지 않는 프로퍼티 또는 상속받은 프로퍼티의 경우 undefined 반환
      • Object.getOwnPropertyDescriptors() : 특정 객체의 모든 프로퍼티 상태 확인 가능

  • 데이터 프로퍼티(data property) : 키와 값으로 구성된 일반적인 프로퍼티
    • 프로퍼티 어트리뷰트
      • [[Value]] : 프로퍼티 키를 통해 프로퍼티 값에 접근하면 반환되는 값
      • [[Writable]]: 프로퍼티의 값의 변경 가능 여부를 불리언 값으로 나타냄
      • [[Enumerable]] : 프로퍼티의 열거 가능 여부를 불리언 값으로 나타냄
        • (false면 for,keys등의 메서등으로 열거 불가)
      • [[Configurable]] : 프로퍼티의 재정의 가능 여부를 불리언 값으로 나타냄
        • (false면 프로퍼티 삭제, 프로퍼티 어트리뷰트의 값의 변경이 금지됨, writable true시,value, wirtable false로는 변경가능)

  • 접근자 프로퍼티(accessor property) : 자체적인 값은 없고, 다른 데이터 프로퍼티의 값을 읽거나, 저장할 때 호출되는 접근자 함수로 구성된 프로퍼티
    • 프로퍼티 어트리뷰트
      • [[Get]] : 데이터 프로퍼티의 값을 읽을 때 호출되는 접근자 함수, getter, 참조로 사용시 getter 동작, 메세드 앞에 get을 붙여 지정
      • [[Set]] : 데이터 프로퍼티의 값을 저장할 때 호출되는 접근자 함수, setter, 값할당시 setter 동작, 메세드 앞에 set을 붙여 지정
      • [[Enumberable]], [[Configurable]] : 데이터 프로퍼티와 같음

  • 프로토 타입(prototype) : 어떤 객체의 상위 객체의 역할을 하는 객체, 하위 객체에게 자신의 프로퍼티와 메서드를 상속함
    • 프로토 타입의 프로퍼티와 메서드를 상속받은 하위 객체의 경우 자신의 프로퍼티, 메서드인 것 처럼 자유롭게 사용 가능함
  • 프로토 타입 체인 : 프로토타입이 단방향 링크드 리스트 형태로 연결되어 있는 상속 구조를 말함
// 일반 객체의 __proto__는 접근자 프로퍼티임
Object.getOwnPropertyDescriptor(Object.prototype, "__proto__");

// 함수 객체의 prototype은 데이터 프로퍼티임
Object.getOwnPropertyDescriptor(function () {}, "prototype");

  • 프로퍼티 정의 : 새로운 프로퍼티 추가시 프로퍼티 어트리뷰트를 명시적으로 정의하거나, 기존 프로퍼티의 프로퍼티 어트리뷰트를 재정의 하는 것을 말함
    • Object.definedProperty() : 프로퍼티의 어트리뷰를 정의 할 수 있음
      • Object.definedProperty(객체참조, 데이터 프로퍼티의 키인 문자열, 프로퍼티 디스크립터 객체)
      • 인수 누락시 undefined, false가 기본값임
        • value, get, set : undefined
        • writable, enumerable, configurable : false
    • Object.definedProperties(): 여러개의 프로퍼티 한번에 정의 가능

  • 객체 변경 방지 메서드 :

    • 얕은 변경 방지(shallow only) : 직속 프로퍼티만 변경이 방지되고 중첩 객체까지는 영향을 주지 않음
      • Object.preventExtensions : 객체 확장 금지(프로퍼티 추가만 안됨)
        • 프로퍼티 동적 추가, Objectd.defineProperty 메서드로 추가 모두 금지
        • 확장 가능 여부는 Object.isExtensible() 메서드로 확인 가능
      • Object.seal : 객체 밀봉 (프로퍼티 읽기, 쓰기(갱신)만 가능하고 나머지는 모두 안됨)
        • Object.isSealed() 메서드로 확인 가능
      • Object.freeze : 객체 동결 (프로퍼티 읽기만 가능하고 모두 안됨)
        • Object.isFrozen() 메서드로 확인 가능
    • 불변 객체(깊은 변경 방지) : 중첩 객체까지 불변하게 만들기 위해서는 재귀적으로 동결시켜야 함
    function deepFreeze(target) {
      if (target && typeof target === "object" && !Object.isFrozen(target)) {
        Object.freeze(target);
        Object.keys(target).forEach((key) => deepFreeze(taget[key]));
      }
      return target;
    }

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


  • 생성자 함수(contructor) : new 연산자와 함께 호출하여 객체(인스턴스)를 생성하는 함수
    • new 연산자와 함께 호출하면 생성자 함수로 동작하고, new 없이 호출하면 일반함수로 동작
  • 인스턴스 : 생성자 함수에 의해 생성된 객체
  • 빌트인 생성자 함수 : String, Number, Boolean, Function, Array, Date, RegExp, Promise 등
    • 해당 타입의 Object를 만들어줌

  • Object 생성자 함수
    • new 연산자와 함께 Object 생성자 함수를 호출시 빈 객체를 생성하여 반환함
    • 이후 프로퍼티 또는 메서드를 추가해서 객체 완성 가능
      const person = new Object()
      person.name = 'kim'
      person.sayHello = function() {
      console.log(`hi! I'm ${this.name}`)
      }
      person.sayHello() // hi! I'm kim

  • 객체 리터럴에 의한 객체 생성 방식의 문제점
    • 동일한 프로퍼티를 갖는 객체를 여러개 생성시, 비효율적 (동일한 프로퍼티를 반복적으로 작성해야 함으로)
    • 객체는 프로퍼티를 통해 객체 고유의 상태(state)를 표현, 메서드를 통해서 상태를 참조하고 조작함
    • 값만 조금 바뀌고 해당 구조는 반복될 것임

  • 생성자 함수에 의한 객체 생성 방식의 장점
    • 생성자 함수에 의한 객체 생성방식은 클래스처럼 생성자 함수를 사용하여 프로퍼티 구조가 동일한 객체 여러개를 간편하게 생성할 수 있음
    • this : 객체 자신의 프로퍼티나 메서드를 참조하기 위한 자기 참조 변수임
      • this 바인딩 : this가 가리키는 값으로 함수 호출 방식에 따라 동적으로 결정됨
        • 일반함수로 호출 - 전역객체
        • 메서드로서 호출 - 메서드를 호출한 객체(마침표 앞의 객체)
        • 생성자 함수로서 호출 - 생성자 함수가 (미래에) 생성할 인스턴스
    • new 연산자와 함께 함수를 호출하면 생성자 함수로 동작
    • new 연산자 없이 함수를 호출하면 일반 함수로 동작
function Circle(radius) {
  this.radius = radius;
  this.getDiameter = function () {
    return 2 * this.radius;
  };
}

const circle1 = new Circle(5);
console.log(circle1.getDiameter()); // 10

const circle2 = Circle(5);
console.log(circle2); // undefined (일반 함수로서 return이 없기 때문에)
console.log(radius); // 5 일반 함수로 작용해서 radius에 있는 this가 전역객체로 되어서 radius 전역 변수 생성
  • 생성자 함수의 인스턴스 생성과정
    • 생성자 함수가 인스턴스를 생성하는 것은 필수, 생성된 인스턴스를 초기화 하는 것은 옵션임
    • JS엔진에서 암묵적으로 인스턴스 생성하고 인스턴스 초기화 하고 암묵적으로 인스턴스 반환
    • 바인딩 : 식별자와 값을 연결하는 과정 (this 바인딩은 this가 가리킬 객체를 바인딩 하는 것을 이야기함)
      • 인스턴스 생성과 this 바인딩 : 함수의 몸체가 실행되기 전인 런타임 이전에 암묵적으로 생성된 빈 객체가 this에 바인딩 되어 내부의 this가 인스턴스를 가르킴
      • 인스턴스 초기화 : 생성자 함수에 있는 몸체가 실행되는 런타임때,
        • this에 바인딩된 인스턴스에 프로퍼티나 메서드를 추가 후
        • 생성자 함수가 인수로 전달 받은 초기값을 인스턴스에 할당하여 초기화 하거나 고정값을 할당
      • 인스턴스 반환 : 생성자 함수 내부의 모든 처리가 끝나면 완성된 인스턴스가 바인딩 된 this가 암묵적으로 반환됨
        • 명시적으로 생성자 함수에 return문에 객체를 반환되게 작성하면, this 반환이 무시되고 해당 객체가 인스턴스로 반환됨
        • 원시 값을 반환 하는 경우, 원시값은 무시되고 this가 인스턴스로 반환됨

  • 함수 객체 :
    • 함수는 객체이므로 일반 객체와 동일하게 동작 가능하지만, 일반 객체와 다르게 호출을 할 수 있음
    • 일반 객체의 내부 슬롯, 내부메서드 + 함수만의 내부 슬롯([[Environment]], [[FormalParameters]]), 내부 메서드([[Call]], [[Construct]])
      • [[Call]] : 함수가 일반 함수로서 호출 되는 경우 함수객체의 내부 메서드인 call이 호출됨
      • [[Construct]] : 함수가 생성자 함수로서 호출 되는 경우 함수객체의 내부 메서드인 contruct가 호출됨
        • [[Construct]]는 필수가 아니라서 함수 객체는 contructor 일수도 있고, non-constructor일 수도 있음 (callable-contuctor or callable-non_constructor)
    • callable : 내부 메서드에 call을 갖는 함수 객체로 호출 할수 있는 함수
      • 함수 객체는 반드시 callable이어야 한다 -> 모든 함수객체는 호출 가능하다.
    • contructor : 내부 메서드에 construct를 갖는 함수 객체로 생성자 함수로서 호출 할 수 있는 함수
      • 함수 선언문, 함수 표현식, 클래스
    • non-contructor : 내부 메서드에 construct를 갖지 않는 함수 객체로 생성자 함수로서 호출 불가한 함수
      • 메서드(ES6 메서드 축약 표현만 메서드로 간주), 화살표 함수
      • 일반적으로 프로퍼티 값으로 함수를 주면 메서드로 통하지만, constructor를 결정 지을 땐 축약 표현만 메서드로 간주

  • new 연산자 : 함수 호출시 [[Construct]]를 호출함, new 연산자가 없으면 [[Call]] 호출
    • new 연산자와 함께 생성자 함수에 의해 생성된 인스턴스는 프로토 타입에 의해 생성자 함수와 연결됨(생성자함수 - 인스턴스)
    • 빌트인 생성자 함수와 new 연산자
      • Object, Function 생성자함수는 new 연산자 없이 호출해도 동일 동작
      • String, Number, Boolean 생성자 함수는 new 연산자와 호출해야 String, Number, Boolean 객체를 생성반환, 없이 호출하면 문자열, 숫자, 불리언 값을 반환하여 타입을 변경시킴

  • new.target : 생성자 함수가 new 연산자 없이 호출되는 것을 방지
    • this와 유사하게 constructor인 모든 함수 내부에서 암묵적인 지역 변수와 같이 사용되며, 메타 프로퍼티라고 부름
    • new 연산자와 함께 생성자 함수 호출시 함수 내부의 new.target은 함수 자신을 가르킴
    • new 연산자없이 일반 함수로 호출시 함수 내부의 new.target은 undefined됨
    • new.target을 활용하여 new 연산자의 호출을 조건으로 new 연산자로 호출 되지 않으면, 재귀함수를 사용해서 new로 호출시키게 만들어서 일반 함수 call을 방어함

  • 스코프 세이프 생성자 패턴 : new.target을 사용할 수 없는 상황에서 사용할 수 있는 패턴

    • this가 window를 가르키게 되는 것을 활용해서, 해당 생성자 함수의 인스턴지인지를 비교(instanceof 연산자)하여 인스턴스가 아니면, new 키워드로 재귀함수를 부름
    function Circle(radius) {
      if (!(this instanceof Circle)) {
        return new Circle(radius);
      }
      // 생성자 함수 내용
      this.radius = radius;
    }

함수와 일급객체


  • 일급객체 :
    • 무명의 리터럴로 생성할 수 있다(런타임에 생성이 가능하다) (익명함수)
    • 변수나 자료구조에 저장할 수 있다. (함수 표현식)
    • 함수의 매개변수에 전달할 수 있다. (callback함수)
    • 함수의 반환값으로 사용할 수 있다.
  • 자바스크립트에서 함수는 일급 객체임
  • 그리고, 일반 객체와 달리 함수 고유의 프로퍼티를 소유함

  • 함수 객체의 프로퍼티:
    • console.dir() : 인자의 객체 구조를 볼수 있음
    • Object.getOwnPropertyDescriptors(): 인자로 받은 함수(객체)의 모든 프로퍼티 어트리뷰트를 메서드로 확인 가능
    • arguments, caller, length, name, prototype 프로퍼티가 함수 객체의 데이터 프로퍼티이자 함수 객체 고유의 프로퍼티임
    • proto는 접근자 프로퍼티이며, Object.prototype 객체의 프로퍼티를 상속 받은것임

  • arguments 프로퍼티 : arguments 프로퍼티 값은 arguments 객체임
    • 함수 호출시 전달된 인수들의 정보를 담고 있는 순회 가능한(iterable)유사 배열 객체이고, 함수 내부에서 지역 변수처럼 사용됨
    • 인수의 개수와 매개변수 개수가 일치하지 않아도 에러가 발생하지 않음
    • 매개변수 개수 > 인수개수 인경우, 할당 되지 않은 매개변수는 undefined
    • 매개변수 개수 < 인수개수 인경우, 넘치는 인수는 암묵적으로 arguments 객체 프로퍼티로 보관됨
    • 프로퍼티 키(0, 1, 2 ...) : 인수의 순서를 나타냄
    • callee 프로퍼티 : arguments 객체를 생성한 함수인 함수 자신을 가리킴
    • length 프로퍼티 : 함수 호출시 받은 인수의 개수를 가르킴
    • Symbol(Symbol.iterator) 프로퍼티 : arguments 객체를 순회가능한 자료구조로 만들기 위한 프로퍼티로 Symbol.iterator를 키로 사용하여 iterator를 받을 수 있음
    • 인수 개수를 확인하여 가변 인자 함수(매개변수 개수 확정이 안되는 경우)를 구현할때 유용함

  • caller 프로퍼티 : 비표준 프로퍼티로서 사용하지 말고 알아만 두자
    • 함수 자신을 호출한 함수(호출 위치)를 가르킴

  • length 프로퍼터 : 함수 정의할 때 선언한 매개변수의 개수를 가르킴
    • arguments의 length 프로퍼티(인수의 개수)와 헷갈리지 않게 주의

  • name 프로퍼티 : 함수 이름을 나타냄
    • ES6 이전 -> 익명함수 표현식의 경우 빈문자열 값을 갖음
    • Es6 이후 -> 익명함수 표현식의 경우 함수 객체를 가르키는 식별자를 값으로 갖음
      • 기명함수 표현식인 경우 식별자가 아닌 함수 이름을 값으로 갖음

  • __proto__ 접근자 프로퍼티 : 모든 객체가 가지고 있는 [[Prototype]] 이라는 내무 슬롯이 가리키는 프로토 타입 객체에 간접적으로 접근하기 위해 사용하는 접근자 프로퍼티

    • hasOwnProperty 메서드 : 인수로 전달받은 프로퍼티 키가 객체 고유의 프로퍼티 키인 경우에만 true를 반환하고 상속 받은 프로토타입의 프로퍼티 인 경우 false 반환 (프로퍼티 상속 체크)
  • prototype 프로퍼티 : 함수가 생성자 함수로 호출 될 때 생성자 함수가 생성할 인스턴스의 프로타입 객체를 가르킴

    • constructor만이 소유하는 프로퍼티임 (생성자 함수로 호출 할 수 있는 함수 객체), 일반 객체는 없음