// 함수 선언문
function add (x,y){
return x+y;
}
// 함수 참조
// console.dir 은 console.log 와는 달리 함수 객체의 프로퍼티까지 추력한다.
// (단 node 환경에서는 console.log 와 동일)
console.dir(add); // f add(x,y)
console.log(add); // [Function : add]
console.log(add(2,5));
// 기명 함수 리터럴을 단독으로 사용 하면 함수 선언문으로 해석
// 함수 선언문에서는 함수 이름을 생략 할 수 없다.
function foo(){console.log('foo');}
foo(); // foo
// 함수 리터럴을 피연산자로 사용하면 함수 선언문이 아니라
// 함수 리터럴 표현식으로 해석된다.
// 함수 리터럴에서는 함수 이름을 생략할 수 있다.
(function bar(){console.log('bar');})
bar(); // bar is not defined
>> 이 경우 기명 함수 리터럴이 선언문으로 사용되어 사용가능하게 된 경우와 표현식으로 사용되어 함수만 사용하지 못하게 된 경우를 나타낸다.
// 기명 함수 표현식
var add = function foo(x,y){
return x+y;
}
console.log(add(2,5));
console.log(foo(2,5));// foo is not defined
-> 위 경우 add 라는 식별자로 foo라는 기명함수를 가리키는데 , 원래는 add 라는 식별자가 없다면 암묵적인 foo 식별자로 접근 할 수 있었겠지만 위와 같게 되면 add 만이 함수에 접근이 가능하므로 foo는 원칙적으로 접근이 불가능하게 된다.
console.dir(add);// f add(x,y)
console.dir(sub);// undefined
console.log(add(2,5)); // 7
console.log(sub(2,5)); // sub is not a function
function add(x,y){
return x+y;
}
var sub = function (x,y){
return x-y;
}
-> 일반적인 선언문으로 정의한 함수 add는 함수 선언문 이전에 호출 가능
그러나 함수 표현식으로 정의한 함수 sub는 함수 표현식 이전에 호출 불가능
이유는 생성 시점이 다르기 때문이다.
runtime 즉 코드가 순차적으로 실행되는 시점에서 함수 선언문은 자바스크립트 엔진에 의해 먼저 실행된다. 즉 runtime 이전에 실행된다.
따라서 위의 선언문 add 는 호출이 가능한 반면
sub의 경우에는 var 변수 자체는 runtime 이전에 선언이 되지만 값의 할당이 일어나지 않았다.
값의 할당은 runtime 즉 실행되면서 이루어 지기 때문에 표현식 이전에 사용한 sub 함수는 유효하지 않는것이다.
=> 이런것 때문에 보통 함수 사용시 선언문 보다는 표현식을 통해 코딩하는 것을 권장한다. (선언문의 경우 호출 전에 선언 먼저를 어기기 때문)
var add1 = (function(){
var a = 10;
return function(x,y){
return x+y+a;
}
}());
console.log(add1(1,2)); //13
var add2 = (function(){
var a = 10;
return new Function('x', 'y', 'return x+y+a;');
}());
console.log(add2(1,2)); // a is not defined
// 클로저 관련 내용 add1에서는 함수를 리턴하면서 클로저를
// 이용하여 내부 변수 'a' 에 접근이 가능하지만
// Function 객체를 이용한 경우 그렇지 않기 때문에 오류가 발생한다.
=>클로저 : 클로저는 함수와 그 함수가 선언될 당시의 렉시컬 환경(Lexical Environment)과의 조합이다. 이는 함수가 다른 스코프에서 생성되었을 때에도, 그 함수가 생성될 당시의 외부 변수에 접근할 수 있게 해주는데, 간단히 말해, 클로저는 함수가 정의될 때 주변 상태를 기억하는 함수이다. -> 좀더 자세히 다룸