Javascript/[인프런] 자바스크립트 중고급
[자바스크립트 중고급] 1.Function 오브젝트
minha62
2022. 2. 17. 04:45
function 형태
- Built-in Function 오브젝트
- Function.prototype.call()
- function 오브젝트
- function book(){...}
- var book = function(){...}
- 인스턴스이지만, new 연산자로 생성한 인스턴스와 구분하기 위해 강좌에서는 function 오브젝트로 표기
- function 인스턴스
- new Book()처럼 new 연산자를 사용하여
- Book.prototype에 연결된 메소드로 생성
function 오브젝트 생성
- var book = function(){...}
- 엔진이 function 키워드를 만나면
- 빌트인 Function 오브젝트의
- prototype에 연결된 메소드로
- function 오브젝트 생성
- 생성한 오브젝트를 book 변수에 할당
- book() 형태로 호출
- function 오브젝트이므로 호출할 수 있음
오브젝트 저장
- 함수를 호출하려면
- 생성한 function 오브젝트를 저장해아
- function 오브젝트 저장 형태
- {name: value} 형태로 저장
- {book: 생성한 function 오브젝트} 형태
- 함수를 호출하면
- 저장된 오브젝트에서 함수 이름(book)으로 검색
- value 값을 구하고
- value가 function 오브젝트이면 호출
생각의 전환
- 함수가 호출되면 엔진은
- 함수의 변수와 함수를 {name: value} 형태로 실행 환경을 설정하고 함수 코드를 실행
- {name: value} 형태로 생각을 전환해야
- JS의 아키텍처와 메커니즘을 쉽게 이해 가능
- function(){} 코드를 보면
- 함수와 변수와 함수가 {name: value} 형태로 연상되어야 함
function 오브젝트 생성 과정
- function sports(){...} 형태에서 function 키워드를 만나면
- 오브젝트를 생성하고 저장
- {sports: {...}}
- sports는 function 오브젝트 이름
- 오브젝트 {...}에 프로퍼티가 없는 상태
- sports 오브젝트에 prototype 오브젝트 첨부
- prototype에 constructor 프로퍼티 첨부
- prototype.constructor가 sports 오브젝트 참조
- prototype에 __proto__ 오브젝트 첨부
- ES5 스펙에 __proto__가 기술되어 있지 않으며 ES6 스펙에 기술
- 엔진이 사용한다는 뉘앙스로 정의
- ES5 기준으로 보면 표준이 아니지만 2000년대 초부터 파이어폭스에서 사용
sports = {
prototype: {
constructor: sports
__proto__: {}
}
}
- 빌트인 Object.prototype의 메소드로
- Object 인스턴스를 생성하여
- prototype.__proto__에 첨부
- sports 오브젝트에 __proto__ 오브젝트 첨부
- sports.__proto__구조가 됨
- 빌트인 Function.prototype의 메소드로
- function 인스턴스를 생성하여
- sports.__proto__에 첨부
- sports 오브젝트 프로퍼티에 초기값 설정
- arguments, caller, length, name 프로퍼티
sports = {
arguments: {},
caller: {},
length: 0,
name: "sports",
prototype: {
constructor: sports,
__proto__: Object.prototype
},
__proto__: Function.prototype
}
function 오브젝트 구조
- function 오브젝트에 prototype이 있으며
- constructor가 연결됨
- __proto__가 연결되어 있음
- Object 인스턴스가 연결됨
- function 오브젝트에 __proto__가 있으며
- Function 인스턴스가 연결됨
- Array이면 Array 인스턴스가 연결되고, String이면 String 인스턴스가 연결됨
sports = {
arguments: {},
caller: {},
length: 0,
name: "sports",
prototype: {
constructor: sports,
__proto__: Object.prototype
},
__proto__: Function.prototype
}
함수 실행 환경 인식
- 함수 실행 환경 인식이 필요한 이유는?
- 함수가 호출되었을 때 실행될 환경을 알아야 실행 환경에 맞추어 실행할 수 있기 때문
- 실행 환경 설정 시점
- function 키워드를 만나 function 오브젝트를 생성할 때
- 설정하는 것
- 실행 영역(함수가 속한 스코프)
- 파라미터, 함수 코드 등
함수 실행 환경 저장
- function 오브젝트를 생성하고 바로 실행되지 않으므로 함수가 호출되었을 때 사용할 수 있도록 환경을 저장해야
- 어디에 저장?
- 생성한 function 오브젝트에 저장
- 인식한 환경을 function 오브젝트의 내부 프로퍼티에 설정
- {name: value} 형태로
내부 프로퍼티
- 엔진이 내부 처리에 사용하는 프로퍼티
- 스펙 표기로 외부에서 사용 불가
- 스펙 표기: [[ ]] 형태, 예: [[Scope]]
내부 프로퍼티 분류
- 공통 프로퍼티
- 모든 오브젝트에 공통으로 설정되는 프로퍼티
- 선택적 프로퍼티
- 오브젝트에 따라 선택적으로 설정되는 프로퍼티
- 해당되는 오브젝트에만 실행
공통 내부 프로퍼티
- 모든 오브젝트에 설정
선택적 내부 프로퍼티
- 오브젝트에 따라 선택적 설정
함수 정의 형태
함수 정의(Function Definition)
- 함수 코드가 실행될 수 있도록 JS 문법에 맞게 함수를 작성하는 것
- 함수 정의 형태
- 함수 선언문(Function Declaration)
- 함수 표현식(Function Expression)
- new Function(param, body) 문자열로 작성
함수 선언문
- function getBook(title){함수 코드}
- function, 함수 이름, 블록{} 작성은 필수
- 파라미터, 함수 코드는 선택
function book(one, two){
return one + ", " + two;
};
log(book("JS", "DOM"));
// JS, DOM
- 엔진이 function 키워드를 만나면
- function 오브젝트를 생성하고
- 함수 이름을 function 오브젝트 이름으로 사용
함수 표현식
- var getBook = function(title){함수 코드}
- function 오브젝트를 생성하여 변수에 할당
- 변수 이름이 function 오브젝트 이름
var getBook = function (title){
return title;
};
getBook("JS책");
//
- 식별자 위치의 함수 이름은 생략 가능
- var name = function abc(){}에서 abc가 식별자 위치의 함수 이름
var getBook = function inside(value){
if (value === 102){
return value;
};
log(value);
return inside(value + 1);
};
getBook(100);
//
엔진 해석 방법
엔진 해석 순서
- 자바스크립트는 스크립팅 언어
- 스크립팅 언어: 작성된 코드를 위에서부터 한 줄씩 해석(환경 설정)하고 실행
➡️ 하지만 자바스크립트는 다름 - 중간에 있는 코드가 먼저 해석될 수도 있음
- 첫 번째, 함수 선언문을 순서대로 해석
- function sports(){};
- 두 번째, 표현식을 순서대로 해석
- var value = 123;
- var book = function(){};
함수 코드 작성 형태
- 마지막 줄에서 book 함수 호출
- book();
- title 변수 선언
- var title = "JS책";
- 함수 선언문 작성
- function getBook(){return title;}
- 함수 표현식 작성
- var readBook = function(){};
// 브라우저의 개발자 도구 창에서 위의 설명 한 줄씩 따라가면서 실행해보기
function book(){
debugger;
var title = "JS책";
function getBook(){
return title;
};
var readBook = function(){};
getBook();
};
book();
엔진 처리 상태
- 마지막 줄에서 book() 함수를 호출하면 debugger에서 실행이 멈춤
2. title, readBook 값은 undefined
3. getBook은 function 오브젝트
- getBook이 function 오브젝트라는 것은
- function getBook(){}을 해석한 것을 뜻함
- title, readBook에 설정된 undefined도 값이며, 값이 있다는 것은 엔진이 해석한 것을 뜻함
- 해석하지 않으면 title, readBook 값이 표시되지 않음
function book(){
log(title);
log(readBook);
log(getBook);
debugger;
var title = "JS책";
function getBook(){
return title;
};
var readBook = function(){};
getBook();
};
book();
// undefined
// undefined
// function getBook(){return title;}
함수 코드 해석 순서
- 함수 선언문 해석
- function getBook(){};
- 변수 초기화
- var title = undefined;
- var readBook = undefined;
- 코드 실행
- var title = "JS책";
- var readBook = function(){};
- getBook();
function book(){
debugger;
var title = "JS책";
function getBook(){
return title;
};
var readBook = function(){};
getBook();
};
book();
1. 함수 선언문 해석
- 마지막 줄에서 book() 함수를 호출
- 엔진 제어가 book 함수의 첫 번째 줄로 이동
- debugger 실행하지 않음
- 함수 안에서 함수 선언문을 찾음
- 위에서 아래로 내려가면서 하나씩 검색
- function getBook(){}이 함수 선언문이므로 function 오브젝트를 생성함
- 더 이상 함수 선언문이 없으므로 다시 함수의 첫 번째 줄로 이동
2. 변수 초기화
- debugger 실행하지 않음
- var title = "JS책";
- title 변수에 undefined 할당
- "JS책"은 할당하지 않음
- function getBook(){}은 초기화를 했으므로 초기화하지 않음
- var readBook = function(){};
- readBook 변수에 undefined 할당
- 함수 표현식은 변수를 선언만 함
- 여기까지가 초기화 단계이며 다시 함수의 첫 번째 줄로 이동
3. 코드 실행
- debugger를 실행하며, 실행이 멈춤
- var title = "JS책";
- title 변수에 "JS책"을 할당
- function getBook(){return title};
- 실행이 아닌 선언이므로 다음 줄로 이동
- var readBook = function(){};
- function 오브젝트를 생성하여 readBook 변수에 할당
- readBook이 function 오브젝트가 되므로 이제 readBook 함수를 호출할 수 있음
- getBook() 함수 호출
- 지금까지와 같은 순서와 방법으로 getBook() 함수의 함수와 변수를 초기화하고 코드 실행
호이스팅
- 함수 선언문은 초기화 단계에서
- function 오브젝트를 생성하므로
- 어디에서도 함수를 호출할 수 있음
- 함수 앞에서 호출 가능
- 호이스팅(Hoisting)이라고 함
- 용어보다 개념으로 접근
var result = book();
log(result);
function book(){
return "호이스팅";
};
// 호이스팅
- 초기화 단계에서
- 값이 있으면 초기화하지 않음
var result = book();
log(result);
function book(){
return "호이스팅";
};
book function(){
return "함수 표현식";
};
// 호이스팅
코딩 시간
- 목적
- JS의 {name: value} 이해
- 함수 표현식과 함수 선언문 이해
- 4가지 코드로 실행하고 결과가 나오는 이유를 설명하기
- 함수 이름은 같으며 가운데에서 함수 호출
- 함수 선언문, 함수 호출(), 함수 선언문
function book(){
function getBook(){
return "책1";
};
// 여기서 함수 호출
log(getBook());
function getBook(){
return "책2";
};
};
book();
// 책2
- 함수 표현식, 함수 호출(), 함수 표현식
- 함수 선언문, 함수 호출(), 함수 표현식
- 함수 표현식, 함수 호출(), 함수 선언문
오버로딩
- 오버로딩 형태
function book(one){};
function book(one, two){};
function book(one, two, three){};
book(one, two);
- 함수 이름이 같더라도
- 파라미터 수 또는 값 타입이 다르면 각각 존재
- 함수를 호출하면
- 파라미터 수와 값 타입이 같은 함수가 호출됨
- JS는 오버로딩을 지원하지 않음
- JS는 파라미터 수와 값 타입을 구분하지 않고
- {name: value} 형태로 저장하기 때문
오버로딩 미지원: 함수 선언문 초기화
- 마지막 줄에서 book() 함수를 호출하면
- function getBook(){return "책1";}을 만나 getBook 오브젝트를 생성
- getBook()을 호출하지 않고 아래로 내려감
- function getBook(){return "책2";}를 만나 getBook 오브젝트를 생성
- 2번의 오브젝트와 이름이 같으므로 여기서 생성한 getBook 오브젝트로 대체됨
- {name: value} 형태에서 name이 같으므로 value이 변경됨
function book(){
function getBook(){
return "책1";
};
getBook();
function getBook(){
return "책2";
};
};
book();
오브로딩 미지원: 변수 초기화
- book 함수의 첫 번째 줄로 이동
- 함수 표현식과 변수에 undefined를 설정하지만 설정할 대상이 없음
- 다시 book 함수의 첫 번째 줄로 이동
오버로딩 미지원: 코드 실행
- function getBook(){return "책1";};
- 함수 선언문이므로 아래로 내려감
- getBook() 함수 호출
- return "책2";의 getBook 함수가 실행됨
- 함수 이름이 같으므로 위의 함수가 아래 함수로 대체되었기 때문
- "책2"가 [실행결과]에 출력됨
- 호출한 함수로 돌아와 다음 코드를 수행
- function getBook(){return "책2";};
- 함수 선언문이므로 처리하지 않음
function book(){
function getBook(){
return "책1";
};
// 여기서 호출
getBook();
function getBook(){
return "책2";
};
};
book();
// 책2