자바스크립트에서의 함수는 함수를 표현하는 방법, 함수를 호출하는 방법, 함수의 사용 범위 등이 다양하게 쓰인다. 함수를 사용하기 전에 확실이 알아보자!
📖 함수 표현식 const sum = function(x, y){ return x + y }
📖 함수 선언식 function sum(x, y){ return x + y }
같은 이름의 add 함수이지만 함수 표현식과 함수 선언식은 함수의 사용 가능한 범위가 다르다. 함수 선언식은 어디에서든지 호출 할 수 있지만 함수 표현식은 함수를 생성한 코드 아래에서만 호출 가능하다.
// 📖 1. 화살표 함수 const sum = (x) => { return x + 2 }
// 📖 2. 화살표 함수 const sum = x => x + 2
정말 간단해보이는 화살표 함수는 애초에 이름이 없는 함수이므로 변수에 담아서 사용 가능하다. 간단하게 쓰기 위한 용도로 쓰이고, 2번 코드처럼 인자가 하나일 때는 소괄호 생략이 가능하고 {return}
을 쓰지 않아도 된다.
한줄코드라고도 불린다.
// 📖 즉시실행함수 표현 (function (a) { console.log(a * 7) })(2);
// 📖 or (function mul(a) { console.log(a * 7) })(2);
즉시실행함수는 위의 표현법처럼 기명함수, 익명함수로 사용 할 수 있다. 즉시실행함수에서의 함수는 함수도 값이 되고 그 값을 말그대로 바로 실행시키기 위해 사용한다. 함수를 변수에 선언하면 전역객체( 글로벌 스코프 )의 속성이 되는데 그것을 막기 위해서 사용한다고 생각하면 될 것 같다.
함수명 ( ) ;
특정한 기능을 실행시키거나, 특정한 값을 받기 위해서는 함수를 호출해야한다. 호출된 함수는 인수와 매개변수, 반환 값이 일치되어야 한다.
함수명a( 함수명b( ) ) ;
let a = 7
function double() {
return a * 2
}
function ddd() {
return double() * 2
}
console.log(ddd(double())) // 28
위의 로직처럼 함수도 값이 되기 때문에 반환된 값을 또 다른 함수의 매개변수로 할당 시킬 수 있다. 하지만 위의 방법은 단순 로직으로 봤을 땐 값이 정확히 반환되는 것을 알 수 있지만 실무에서는 반환된 값이 어떻게 들어올지 모르고, 최종적으로 에러를 반환 할 수 있으니 확인이 쉬운 로직에서 사용하는 것이 좋을 것 같다.
함수 선언부가 유효범위 최상단으로 끌어올려지는 현상
const a = 7
double()
function double() {
console.log(a * 2)
}
상단의 double( )함수가 함수 선언부에 선언을 하면 최상단에 호출이 가능해진다. 호이스팅을 이용해서 함수를 최상단에 호출하는 이유는 상단부터 변수 선언, 함수 선언, 함수 로직의 순서대로 하면 함수의 이름만보고도 함수의 로직을 추측가능하기 때문이다.
호이스팅을 사용할 때 주의 할 점은 변수 선언의 위치이다.
double()
function double() {
console.log(a * 2)
const a = 7
}
위의 코드처럼 a변수의 선언 위치를 바꿔보자.
함수가 선언되고 함수 내부의 출력 이후에 변수를 지정하면 NaN( Not a Number )가 출력된다. 즉, 함수 내부의 출력에서 로직이 종료되기때문에 원하는 값을 제대로 출력 할 수 없다.
스코프는 범위를 뜻하고 자바스크립트 내의 명명된 참조 대상 식별자(유일한 이름)를 찾기 위한 규칙이다. 그렇기때문에 같은 스코프 내에서 동일한 이름을 가질 수 없다.
스코프의 범위는 크게 3분류로 나뉜다.
전역스코프 ( 글로벌 스코프 )
: 어떤 것에도 감싸져있지 않은 스코프, 코드 어디에서든지 참조 할 수 있다.
지역스코프
: 특정 범위 스코프, 함수 내부, 실행되고있는 상황에서 다른 함수 내부에 선언된 객체를 불러올 수 없다. ( 실행기준 )
블럭스코프
: 블럭 범위, 선언된 블럭 내부에서만 호출 가능
📌 전역스코프 ( 함수스코프 ( 블럭스코프 ) ) )
스코프는 중첩 된다.
블럭내부에서 해당 객체가 없으면 상위스코프, 그 상위스코프까지 찾는다.
let a = {
id: "ABC",
getId: function () {
return (a.id = "abc")
},
getPw: function () {
return (a.pw = "1234")
},
}
console.log(a.id) // ABC
console.log(a.getId()) // abc
console.log(a.getPw()) // 1234
console.log(a) // {id: 'abc', pw: '1234', getId: ƒ, getPw: ƒ}
위의 로직처럼 같은 a 변수여도 호출되는 위치에 따라 값이 달라진다. a 의 id 값은 ABC가 되고 a의 getId( )의 id는 abc가 된다. 또한 a의 Object를 반환하면 다시 a의 id는 abc가 되는데, 이러한 이유는 id는 각각 다른 스코프에 존재하지만 a의 객체 데이터가 모두 반환되는 즉, 종료시점에서는 getId의 id값이 더 나중에 반환되므로 abc가 출력된다.
자바스크립트의 전역 객체로 window, document, navigation이 있다.
var ABC = 100;
선언된 해당 ABC변수는 전역객체의 속성으로 들어간다.
즉,window.ABC
의 값과 같다.
var는 변수의 범위를 쪼개는데 한계가 있고 블럭스코프를 지원하지 않는다. var값을 함수에 인수로 넣으면 내부에 있는 var변수를 함수 내부 최상위로 끌어올린다. 이렇게 전역 공간에 변수를 만들고, 함수 내부에 모든 변수가 호이스팅되면 로직의 에러와 버그를 불러온다.
let도 호이스팅이 되지만 전역 공간 TDZ( Temporal Dead Zone )에 따로 만들어지고 초기화가 되기 전에 접근이 금지된다.