[Java Script] 함수와 프로토타입 체이닝 1

2021. 7. 30. 21:58CSE/Java Script

- 자바스크립트에서 함수는 모듈화 처리나 클로저, 객체 생성 등 많은 기능을 제공한다.

=> 자바스크립트에서 가장 중요한 개념이기 때문에 제대로 된 이해가 필요하다.

 

1. 함수 정의

(1) 함수 리터럴

- 자바 스크립트에서는 함수도 객체처럼 값으로 취급된다. => 함수도 리터럴 방식으로 생성 가능

function add(x,y){
	return x+y;
}

- 함수명은 선택사항이다. 함수명이 없는 함수는 익명 함수이다.

 

(2) 함수 선언문 방식

- 반드시 함수명이 정의되어 있어야 한다.

- 형태는 앞의 함수 리터럴 방식과 동일하다

 

(3) 함수 표현식 방식

- 함수 리터럴로 함수를 만들고, 해당 함수를 변수에 할당하는 방식

- 함수 이름은 선택사항이며, 보통 사용하지 않는다.

 

- 익명 함수 표현식

var add = function(x,y){
	return x+y;
};

add(3,4);

- 기명 함수 표현식

var add = function sum(x,y){
	return x+y;
};

add(3,4);
sum(3,4); //에러발생

=> 함수 표현식에서 사용된 함수 이름은 외부 코드에서 접근 불가능하다.

=> 그렇다면 왜 함수 이름을 사용할까? : 보통 재귀적으로 호출하거나, 디버거 등에서 함수를 구분할 때 사용됨

 

(4) Function() 생성자 함수를 통한 함수 생성하기

- 자바스크립트의 함수도 Function()이라는 기본 내장 생성자 함수로부터 생성된 객체임

- 위의 방식들도 결국에는 다 Function() 생성자 함수로 함수가 생성된다고 볼 수 있음

- Function() 생성자 함수 : new Function (arg1, arg2, ... argN, functionBody)

var add = new Function('x', 'y', 'return x+y');

console.log(add(3,4)); //7

=> 자주 사용되는 방식은 아님

 

2. 함수 호이스팅

- 호이스팅이란 ? : var 변수와 함수 선언문이 위로 끌어올려지는 것 (할당은 아님)

foo();
bar();

var foo = function(){
	console.log("foo and x = " + x);
};

function bar() {
	console.log("bar and x = " + x);
}

var x = 1;

위의 코드는 다음과 같이 호이스팅 된다.

var foo;

function bar(){
	console.log("bar and x = " + x);
}

var x;

foo(); // Type Error
bar();

foo = function(){
	console.log("foo and x = " + x);
}

x = 1;

=> 즉, 함수 선언문 형태로 정의한 함수의 유효 범위는 코드의 맨 처음부터 시작하게 된다.

=> 더글러스 크락포드는 함수 호이스팅이 함수를 사용하기 전에 반드시 선언해야 한다는 규칙을 무시하므로 함수 표현식 사용을 권장하고 있다.

 

3. 함수 객체

(1) 함수도 객체이다.

- 자바스크립트에서는 함수도 객체로 취급된다.

=> 즉, 함수 자체도 프로퍼티들을 가질 수 있다.

function add(x,y){
    return x+y;
}

add.result = add(3,2);
add.status = 'OK';

console.log(add.result); //5
console.log(add.status); //OK
console.log(add); //[Function: add] { result: 5, status: 'OK' }

 

(2) 자바스크립트에서 함수는 값으로 취급된다.

- 함수도 일반 객체처럼 취급된다. 따라서 다음과 같은 동작이 가능하다.

  • 리터럴에 의해 생성
  • 변수나 배열의 요소, 객체의 프로퍼티 등에 할당 가능
  • 함수의 인자로 전달 가능
  • 함수의 리턴값으로 리턴 가능
  • 동적으로 프로퍼티를 생성 및 할당 가능

=> 따라서 함수는 일급 객체라고 부른다. (앞에 나열한 기능이 모두 가능한 객체라는 뜻)

 

(3) 함수를 변수나 프로퍼티의 값으로 할당하기

var p = 100;
var func = function(x,y){return x+y;};
console.log(func(2,3)); //5

var obj = {};
obj.first = p;
obj.second = func;
console.log(obj); //{ first: 100, second: [Function: func] }
console.log(obj.second(2,5));//7

 

(4) 함수를 함수 인자로 전달하기

var add = function (x,y) {return x(1) + y(1)};
var addOne = function (x) { return x+1;};
var addTwo = function (x) { return x+2;};

console.log(add(addOne, addTwo)); //5

(5) 함수를 리턴값으로 활용

var getadd = function(){
    return function(x,y){
        return x+y;
    }
}

var add = getadd();
console.log(add); //[Function (anonymous)]
console.log(add(3,5)); //8

 

4. 함수 객체의 기본 프로퍼티

- 함수는 일반 객체와는 다르게 함수 객체만의 표준 프로퍼티가 정의되어 있다.

- 모든 함수는 length와 prototype 프로퍼티를 가져야 한다.

- name 프로퍼티 : 함수의 이름

- caller 프로퍼티 : 나를 호출한 함수 => 호출한 것이 아니므로 null값

- arguments 프로퍼티 : 함수를 호출할 때 전달된 인자값 -> //

- length 프로퍼티 : 함수가 정상적으로 실행될 때 기대되는 인자의 개수

- prototype 프로퍼티 : Function.prototype 객체 => 모든 함수들의 부모 역할을 함

 

* prototype 프로퍼티 != [[Prototype]] 프로퍼티

- [[Prototype]] 프로퍼티 : 객체 입장에서 자신의 부모역할을 하는 프로토타입 객체

- prototype 프로퍼티 : 이 함수가 생성자로 사용될 때, 이를 통해 생성된 객체의 부모 역할을 하는 프로토타입 객체

- prototype 내의 constructor 프로퍼티는 자신과 연결된 함수를 가리킨다

=> 자바 스크립트에서는 함수를 생성할 때, 함수 자신과 연결된 프로토타입 객체를 동시에 생성하며, 함수는 prototype 프로퍼티로 프로토타입 객체를 참조하고, 프로토타입 객체는 constructor 프로퍼티로 함수를 참조한다.