본문 바로가기

Computer Programming/Javascript

Deep Dive 18-21 [함수와 일급 객체 | 프로토타입 | strict mode | 빌트인 객체]

18장. 함수와 일급 객체

일급객체의 조건 - '무명'의 리터럴로 생성 가능(런타임에 생성), 변수나 자료구조에 저장 가능, 매개변수에 전달 가능, 반환값으로 사용

- 함수는 위의 조건을 만족시킴

* 런타임(할당 단계)에 함수 리터럴이 평가되고, 함수 객체가 생성되어 변수에 할당되는 과정이 가능!!

function example() {
	return function() {
	    //...
    	return num;
    }
}

- 즉 함수를 객체와 동일하게 사용할 수 있음 (어디서든지 리터럴로 정의할 수 있고, 런타임에 함수 객체로 평가됨)

- 그러나 일반 객체와는 차이가 있음 -> 함수 객체는 호출할 수 있고, 함수 고유의 프로퍼티를 소유함

- 프로퍼티는 Object.prototype 객체의 프로퍼티를 상속받은 것 (즉 모든 객체가 사용 가능한 것을 상속받음 (prototype 이라는 프로퍼티로. ))

- 함수 객체 프로퍼티 : arguments, caller, length, name, prototype

 

arguments (이터러블)

- 함수 내에서 매개변수는 일반 함수의 지역변수와 동일하게 undefined로 초기화됨.

- 매개변수 개수 < 인수 개수 여도 초과된 인수는 arguments 객체에 정보가 추가되어있음

 

length

- 매개변수의 개수를 나타냄 !== arguments의 length (인자의 개수)

 

prototype

- constructor 함수만 가지고 있음 (생성자 함수로 호출할 수 없는 non-constructor 함수는 가지고있지 않음)

 

 

19장. 프로토타입

- 객체지향프로그래밍

- js는 프로토타입을 기반으로 상속을 구현해 불필요한 중복을 제거함

- Circle 생성자 함수에 메소드로 getArea() 와 같은 메소드를 만들면, 이후 생성되는 인스턴스들이 각각 이를 중복소유하게 되고 -> 메모리 낭비가 우려됨

=> 프로토타입 기반의 '상속'으로 이를 해결할 수 있음 (중복소유 -> 공유!) 즉, 모든 인스턴스들이 하나의 특정 메소드를 공유해서 사용함

 

프로토타입

- 프로토타입은 객체의 생성 방식에 의해 결정됨 (객체 리터럴로 생성 -> Object.prototype | 생성자 함수에 의해 생성 -> 

함수 객체의 프로퍼티인 prototype에 바인딩 되어 있음)

- 모든 객체는 __proto__ 접근자 프로퍼티로 자신의 프로토타입 (즉, [[Prototype]] 에 간접 접근)

 

접근자 프로퍼티란? 자체적으로는 값을 갖지 않고, 다른 데이터 프로퍼티의 값을 읽거나 저장할 때 사용하는 접근자 함수를 모아놓은 (프로퍼티 어트리뷰트) 것으로 구성된 프로퍼티

 

- 함수 객체만 가지고있는 prototype 프로퍼티는 앞으로 생성자함수가 생성할 인스턴스의 프로토타입을 가짐

=> 화살표 함수는 non-constructor 이기 때문에 prototype 프로퍼티를 갖지 않는다.

 

Person 생성자 함수로 만들어진 객체 person1의 constructor는, 자신을 만든 Person 생성자 함수를 가리킨다.

만약 객체 리터럴로 정의한 객체일 경우, prototype의 constructor는 Object를 가리킨다.

 

 

20. strict mode

- 함수별, 스크립트 태그별로 적용하지 x

- 즉시 실행함수로 감싸 선두에 'use strict' 선언 후 스크립트 단위로 적용해야한다

- lint 도구를 사용해도 됨 -> 정적 분석 기능으로, 소스코드 실행하기 전 스캔하여 잠재적 오류를 찾아냄

 

- strict mode에서 함수를 '일반함수'로 호출하면 (생성자 함수 말고) this에 undefined가 바인딩 됨. 생성자 함수가 아닌 함수에서는 this를 사용할 필요가 없기 때문

- 매개변수에 전달된 인수를 재할당해서 변경해도 arguments 객체에 반영되지 않음

 

21장. 빌트인 객체

 

자바스크립트의 객체

1) 표준 빌트인 객체 : js 실행 환경과 상관없이 언제나 사용 (전역 변수처럼 별도의 선언 없이)

2) 호스트 객체 : 실행환경에 따라 추가로 제공하는 객체

3) 사용자 정의 객체

 

 

1) 표준 빌트인 객체 

- Object, String, Number ... => 인스턴스를 생성할 수 있는 생성자 함수 객체임

const numObj = new Number(1.5) // Number {1.5}
typeof numObj // object

// 이 인스턴스의 프로토타입은 -> Number.prototype

// Number.prototype의 프토토타입 메소드인 toFixed 사용
console.log(numObj.toFixed()) //2 소수점 자리 반올림.

 

- 원시값에도 .length를 사용했을 때 사용 가능함 -> 객체처럼 접근해도 됨. 자바스크립트 엔진이 일시적으로 원시값을 연관된 객체로 변환해줌 => 이 임시 객체를 래퍼 객체라고 함.

=- null, undefined는 래퍼 객체를 생성하지 않아서 객체처럼 사용하면 에러가 발생함

 

전역 객체

- 코드가 실행되기 이전 js 엔진에 의해 가장 먼저 생성되는 특수한 객체.

- 브라우저 : window, Node.js : global

- 전역 객체에 포함되는 것 : 표준 빌트인 객체, 호스트 객체, var키워드로 선언한 전역 변수와 전역 함수

- 사용자가 생성할 수 없음. 전역 객체의 프로퍼티를 참조할 때 window 는 생략할 수 있음

 

빌트인 전역 프로퍼티

- 전역 객체의 프로퍼티를 의미함

- window. Infinity, window.NaN, window.undefined

- undefined === window.undefined

 

빌트인 전역 메소드 (빌트인 전역 함수)

1) eval : '코드'를 인수로 전달받음(문자열). => 이 문자열이 표현식이라면 런타임에 평가, 아니라면 런타임에 실행

  - 객체 리터럴과 함수 리터럴은 괄호로 감싸야 함. eval('({a : 1})') 또는 eval('(function(){return 1;})')

  - strict mode 에서는 자체적인 스코프를 생성하지만, 아닌 경우 원래 그 위치에 존재하던 코드 처럼 동작해서 자신이 속해있는 함수의 스코프에 동적으로 원하는 코드를 추가한다.

  => 성능 꽝. 최대한 사용하지 x

2) isFinite : 0, 10, null 등

3) parseFloat, parseInt (문자 -> 실수 또는 정수) => parseInt는 두 번째 인자에 진법을 나타내는 기수를 전달할 수 있음.

  반환값은 문자열을 두번째 인수 진법으로 환산한 10진수이다. 반대로 하고싶다면 x.toString(2) //2진수로 변환

4) encodeURI/ decode URI

- 인코딩: URI 문자를 이스케이프 처리하는 것. 이스케이프 처리란 특수문자를 안전하게 아스키문자 셋으로 변환하는 것.

 

암묵적 전역

- 선언하지 않은 변수에 할당할 경우, 이 변수는 전역 객체의 프로퍼티가 되어 전역 변수처럼 동작함. -> 그러나 변수로 추가된게 아니라, 전역 객체의 프로퍼티로만 추가된것임 -=> 변수 호이스팅이 발생하지 않는다.

- 이는 delete 키워드로 삭제할 수 있음 ( 프로퍼티 삭제임. 변수 삭제는 아님)