TIL_170929 함수 프로토타입, 스코프

함수 프로토타입

  • 자바스크립트의 객체지향을 충족하기 위한 방식론
  • ES6에서는 클래스의 개념이 생겼음 (자바처럼 객체와 객체간의 상속관계를 개발자가 만들어줌)
  • 그 외에 꼼수처럼 프로토타입객체의 변경을 통해서도 객체끼리의 상속관계 만듬이 가능 (권장방식X, constructor프로퍼티 연결이 깨짐)
  1. function Person
  • 객체를 생산하는 생성자함수 person
    • (그러나 자바스크립트 엔진은 뭘 생산할지 몰라서 객체를 생산하는 함수가 아닐지언정, 생성자함수로 취급하여 prototype을 가지고 있음)
    • 개발자들 사이에선 암묵적으로 생성자함수명은 대문자로 시작
  • prototype 프로퍼티를 갖고있음
  • person.prototype.constructor와 같은 실상=
  • 프로토타입 체이닝에 의해, me.constructor와도 같음
  1. var me = new person() __proto__
  • Person이라는 함수를 생성자함수로 삼아 생성된 일반객체의 부모의 역할을 함.
  1. person.prototype
  • 객체를 생산하는 person이라는 함수가 생성됨으로써 생성되는 프로토타입
  • 즉, 생성자함수 Person의 프로토타입
  • constructor 프로퍼티를 갖고잇음
  • meproto와 같은 실상

프로토타입 체인

  • 프로토타입 체인의 종점은 object.prototype
  • 객체 리터럴로 객체를 생성했을때는 상속관계의 단이 종점인 objec.prototype밖에 없어 여기에 메소드를 추가할 시 빌트인이 변경됨 (비추)
  • 즉, 객체 리터럴 본인외에 공통부분이 있어 효율상 상속관계가 필요하다면, 객체리터럴로 객체를 생성X -> 생성자함수로 생성
  • 그래야만 생성자함수.prototype으로 전체 빌트인을 변경하지 않고도 상속관계를 사용하여 메소드 사용이 가능

기본자료형의 확장

  • 기본자료형일지라도, 메소드를 호출 시 자바스크립트 엔진이 순간적으로 객체형으로 취급하여 결과값 반환이 가능
  • 엔진은 String생성자 함수로 문자열(객체)로 탄생했다고 생각함 (wrapper성격의 생성자함수 String, Number)
  • 따라서 String.prototype에 자신의 메소드를 추가할 수 있음
  • 그러나 빌트인을 건들이게 되므로 비추

스코프

  • 자바스크립트는 함수 중괄호 만을 지역으로 갖음 (Function-Level Scope)
  • 자바스크립트는 중복변수, 중복함수를 허용 -> 에러나지 않고 작동(의도하지 않은 값으로)
  • 따라서 전역스코프는 되도록 사용x

전역스코프 탈피 방법

  1. IIFE, 즉시호출함수 사용
  2. ES6에서 let, const 사용

전역변수

  • 웹 브라우저 내 전역변수는 전역객체 window의 프로퍼티
  • 노드 환경 내 전역변수는 전역객체 global의 프로퍼티
  • 암묵적전역
    • 함수 내에 var를 선언하지 않고 변수A를 선언했을때 함수 내에도 A가 없고, 전역에서도 변수A가 없을때, 엔진은 함수 내의 변수A를 전역변수화 시킴
    • use strict모드일때는 전역변수화X -> 에러

This

  1. 함수에서만 사용 가능
  2. 함수가 어떻게 호출되느냐에 따라 this가 지칭하는것이 달라짐 (자바스크립트 특징)
  3. this의 지칭객체 기본값은 window.
    • 예) 메소드 내부에 있는 함수는 일반함수 -> 여기서의 this는 window
  4. 메소드와 생성자함수에 있을때만 this가 지칭하는 것이 다름

메소드 호출 패턴

  • 메소드에 있는 this는 해당 메소드를 소유한 객체
  • this를 사용함으로써 A/B/C객체 중 A객체에만 메소드를 할당하고, A = B = C 해줌으로써 해당 메소드를 같이 사용 가능 (pass by reference)
  • 같은 메소드를 사용하지만, 메소드가 가리키는 객체의 프로퍼티는 다 다름
  • 즉, this를 통해 메소드는 한번 사용하면서 각 객체의 다른 값을 불러올 수 있음

생성자함수 호출 패턴

  • 생성자함수가 생성되는 동시에 빈객체가 생성됨
  • this의 지칭객체가 기본값(window)에서 생성된 빈객체로 변경(바인딩)
  • 여기에 생성자함수 내, this.prop = 값을 할당할 경우, 생성자함수와 new연산자를 통해 생성될 인스턴스에 prop이라는 프로퍼티를 추가하는 기능을 수행
  • 즉, 생성자함수에 있는 this는 생성자함수가 new연산자를 통해 생성될 인스턴스를 지칭
    가 될지 모름 (인스턴스가 생성되기 전이므로)

[주의사항]

일반함수와 생성자함수 형식적차이X, new 연산자를 붙여서 호출할 시, 해당함수는 생성자함수로 동작

  • new연산자 없이 함수를 호출 -> 생성자함수가 아니고 일반함수로 취급됨으로 this는 전역객체(window)
  • 이에 오해발생을 줄이기위해 생성자함수명은 대문자 로 시작하는것을 관행으로 함

apply메소드 호출패턴

  • this가 지칭하는 객체를 내가 원하는 특정 객체로 바꾸고 싶을때 사용
  • 객체B는 생성자함수A를 통해 생성된 인스턴스가 아닌데도 불구, 그 생성자함수프로토타입이 가진 메소드를 쓰고 싶을때.
  • A프로토타입.메소드.apply(유사배열객체)로 선언함으로써 this의 지칭값을 소유한객체가 아닌 지정한 객체B로 바꿀수 있음 -> 해당 메소드 사용가능
  • 아무 객체로나 바꿀숭수 있는 것은 아님. 유사배열객체로만 (배열로 변할수있는 객체)

오늘의 느낀점

  • 프로토타입 체이닝은 처음에 들었을때는 헷갈릴 수 있는 개념! 도식화된 그림을 머리에 그려두자
  • 10일에 달하는 추석연휴를 맞이한 과제는 1주일 분량의 리뷰. 5일밖에 안되는 기간이지만 너무 많은 정보가 한번에 들어왔다. 키워드별로 차분히 정리해두자
  • 연휴가 끝나면 무려 “주관식” 테스트가 있을 예정 :(
  • ‘설명할 줄 알아야 진짜 아는 것이다’ 안다고 생각이 드는 개념이라도 말로 설명해보는 듯 공부해봐야지