[자바스크립트 중고급] 1.Function 오브젝트

Speedwell🍀·2022년 1월 26일
0

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 오브젝트} 형태
  • 함수를 호출하면

    1. 저장된 오브젝트에서 함수 이름(book)으로 검색
    2. value 값을 구하고
    3. value가 function 오브젝트이면 호출

생각의 전환

  • 함수가 호출되면 엔진은

    • 함수의 변수와 함수를 {name: value} 형태로 실행 환경을 설정하고 함수 코드를 실행
  • {name: value} 형태로 생각을 전환해야

    • JS의 아키텍처와 메커니즘을 쉽게 이해 가능
  • function(){} 코드를 보면

    • 함수와 변수와 함수가 {name: value} 형태로 연상되어야 함

function 오브젝트 생성 과정

  1. function sports(){...} 형태에서 function 키워드를 만나면

  2. 오브젝트를 생성하고 저장

    • {sports: {...}}
    • sports는 function 오브젝트 이름
    • 오브젝트 {...}에 프로퍼티가 없는 상태
  3. sports 오브젝트에 prototype 오브젝트 첨부

  4. prototype에 constructor 프로퍼티 첨부

    • prototype.constructor가 sports 오브젝트 참조
  5. prototype에 __proto__ 오브젝트 첨부

    • ES5 스펙에 __proto__가 기술되어 있지 않으며 ES6 스펙에 기술
    • 엔진이 사용한다는 뉘앙스로 정의
    • ES5 기준으로 보면 표준이 아니지만 2000년대 초부터 파이어폭스에서 사용
sports = {
	prototype: {
    		constructor: sports
        	__proto__: {}
	}
}
  1. 빌트인 Object.prototype의 메소드로

    • Object 인스턴스를 생성하여
    • prototype.__proto__에 첨부
  2. sports 오브젝트에 __proto__ 오브젝트 첨부

    • sports.__proto__구조가 됨
  3. 빌트인 Function.prototype의 메소드로

    • function 인스턴스를 생성하여
    • sports.__proto__에 첨부
  4. 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(){};

함수 코드 작성 형태

  1. 마지막 줄에서 book 함수 호출

    • book();
  2. title 변수 선언

    • var title = "JS책";
  3. 함수 선언문 작성

    • function getBook(){return title;}
  4. 함수 표현식 작성

    • var readBook = function(){};
// 브라우저의 개발자 도구 창에서 위의 설명 한 줄씩 따라가면서 실행해보기
function book(){
  debugger;
  var title = "JS책";
  function getBook(){
    return title;
  };
  var readBook = function(){};
  getBook();
};
book();

엔진 처리 상태

  1. 마지막 줄에서 book() 함수를 호출하면 debugger에서 실행이 멈춤

2. title, readBook 값은 undefined

3. getBook은 function 오브젝트

  1. getBook이 function 오브젝트라는 것은

    • function getBook(){}을 해석한 것을 뜻함
  2. 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;}

함수 코드 해석 순서

  1. 함수 선언문 해석

    • function getBook(){};
  2. 변수 초기화

    • var title = undefined;
    • var readBook = undefined;
  3. 코드 실행

    • var title = "JS책";
    • var readBook = function(){};
    • getBook();
function book(){
  debugger;
  var title = "JS책";
  function getBook(){
    return title;
  };
  var readBook = function(){};
  getBook();
};
book();

1. 함수 선언문 해석

  1. 마지막 줄에서 book() 함수를 호출
  1. 엔진 제어가 book 함수의 첫 번째 줄로 이동

    • debugger 실행하지 않음
  2. 함수 안에서 함수 선언문을 찾음

    • 위에서 아래로 내려가면서 하나씩 검색
  3. function getBook(){}이 함수 선언문이므로 function 오브젝트를 생성함

  4. 더 이상 함수 선언문이 없으므로 다시 함수의 첫 번째 줄로 이동


2. 변수 초기화

  1. debugger 실행하지 않음

  2. var title = "JS책";

    • title 변수에 undefined 할당
    • "JS책"은 할당하지 않음
  3. function getBook(){}은 초기화를 했으므로 초기화하지 않음

  4. var readBook = function(){};

    • readBook 변수에 undefined 할당
    • 함수 표현식은 변수를 선언만 함
  5. 여기까지가 초기화 단계이며 다시 함수의 첫 번째 줄로 이동


3. 코드 실행

  1. debugger를 실행하며, 실행이 멈춤

  2. var title = "JS책";

    • title 변수에 "JS책"을 할당
  3. function getBook(){return title};

    • 실행이 아닌 선언이므로 다음 줄로 이동
  4. var readBook = function(){};

    • function 오브젝트를 생성하여 readBook 변수에 할당

    • readBook이 function 오브젝트가 되므로 이제 readBook 함수를 호출할 수 있음

  5. 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가지 코드로 실행하고 결과가 나오는 이유를 설명하기

  • 함수 이름은 같으며 가운데에서 함수 호출

  1. 함수 선언문, 함수 호출(), 함수 선언문
function book(){
  function getBook(){
    return "책1";
  };
  // 여기서 함수 호출
  log(getBook());
  function getBook(){
    return "책2";
  };
};
book();

// 책2
  1. 함수 표현식, 함수 호출(), 함수 표현식

  2. 함수 선언문, 함수 호출(), 함수 표현식

  3. 함수 표현식, 함수 호출(), 함수 선언문


오버로딩

  • 오버로딩 형태
function book(one){};
function book(one, two){};
function book(one, two, three){};
                               
book(one, two);
  • 함수 이름이 같더라도
    • 파라미터 수 또는 값 타입이 다르면 각각 존재
  • 함수를 호출하면
    • 파라미터 수와 값 타입이 같은 함수가 호출됨
  • JS는 오버로딩을 지원하지 않음
    • JS는 파라미터 수와 값 타입을 구분하지 않고
    • {name: value} 형태로 저장하기 때문

오버로딩 미지원: 함수 선언문 초기화

  1. 마지막 줄에서 book() 함수를 호출하면

  2. function getBook(){return "책1";}을 만나 getBook 오브젝트를 생성

  3. getBook()을 호출하지 않고 아래로 내려감

  4. function getBook(){return "책2";}를 만나 getBook 오브젝트를 생성

    • 2번의 오브젝트와 이름이 같으므로 여기서 생성한 getBook 오브젝트로 대체됨
  5. {name: value} 형태에서 name이 같으므로 value이 변경됨

function book(){
  function getBook(){
    return "책1";
  };
  getBook();
  function getBook(){
    return "책2";
  };
};
book();

오브로딩 미지원: 변수 초기화

  1. book 함수의 첫 번째 줄로 이동

  2. 함수 표현식과 변수에 undefined를 설정하지만 설정할 대상이 없음

  3. 다시 book 함수의 첫 번째 줄로 이동


오버로딩 미지원: 코드 실행

  1. function getBook(){return "책1";};

    • 함수 선언문이므로 아래로 내려감
  2. getBook() 함수 호출

  3. return "책2";의 getBook 함수가 실행됨

    • 함수 이름이 같으므로 위의 함수가 아래 함수로 대체되었기 때문
    • "책2"가 [실행결과]에 출력됨
  4. 호출한 함수로 돌아와 다음 코드를 수행

  5. function getBook(){return "책2";};

    • 함수 선언문이므로 처리하지 않음
function book(){
  function getBook(){
    return "책1";
  };
  // 여기서 호출
  getBook();
  function getBook(){
    return "책2";
  };
};
book();

// 책2

0개의 댓글