"함수는 객체"👻
: 일련의 과정을 수행하기 위한 statement를 중괄호( { } )를 이용해서 하나의 실행단위로 만들어 놓은 것. 반복적인 코드를 함수화 시킨다.
<함수화의 이점>
<용어 정리>
: function keyword 사용
function 함수이름(파라미터/매개변수) { 리턴값 }
function add(x,y) {
return x+y;
}
리터럴과 다르게 변수에 저장되지 않는다.
: 함수 리터럴로 만드는 것
var myFunc = function() {
return x+y;
}
: 상속 관계를 위해 만든 것이다. 사용을 권장하지 않는다.
JavaScript engine 안에 built-in 되어있다.
var add = new Function('x', 'y', 'return x+y');
-> add라는 함수 객체가 만들어진다.
: 축약 표현
var add = (x,y) => x + y;
: 함수는 함수 이름으로 호출하지 않는다. 함수에 대한 식별자로 호출한다.
함수식별자(argument/인수/인자);
add(3,5);
function add(x,y) {
return x+y;
}
console.log(add(2)); // y에는 undefined가 들어간다. 호출은 가능하다.
console.log(add(2,3,4));
실행 결과 : NaN
5
function add(x,y) {
// arguments
let sum = 0;
for(var i = 0; i < arguments.length; i++) {
sum += arguments[i]
}
return x + y;
}
console.log(add(2,3,4)); // 호출은 가능
실행 결과 : 9
유사 배열 객체 (Array-like Object)
: length property를 가지고, 배열처럼 index를 사용해서 접근과 순환을 할 수 있다. 배열은 아니다. 배열이 가진 method를 모두 가지고 있지 않다.
-> ES6에서는 Rest Parameter를 제공한다.
Rest Parameter
: '...'으로 표현한다. arguments 유사 배열 객체 대신 사용한다. 진짜 Array로 사용한다. rest parameter는 parameter의 제일 마지막에 들어가야 한다. 두 개 이상 나올 수 없다.
-> 가변 인자 함수를 만들 때 사용한다.function foo(...args) { console.log(arguments); console.log(args); } foo(1,2,3,4,5); 실행 결과 : [Arguments] { '0': 1, '1': 2, '2': 3, '3': 4, '4': 5 } [ 1, 2, 3, 4, 5 ]
: 함수 내에서 arguments와 Rest parameter 둘 다 이용할 수 있다.
단, arrow function에서는 arguments를 쓸 수 없다. Rest parameter만 사용할 수 있다.
: 함수의 이름은 식별자이다.
함수 이름은 함수 내부에서만 사용 가능하다. 외부로 노출되지 않는다.
var func = function add(x,y) {
return x+y;
}
console.log(add(3,5));
실행 결과 : ReferenceError: add is not defined 발생
var myFunc = function add(x,y) {
return x+y;
}
console.log(myFunc(3,5)); // 식별자로 사용할 수 있다.
실행 결과 : 8
add 이름이 필요 없기 때문에 이렇게 익명 함수 형태로 많이 사용한다.
var myFunc = function (x,y) {
return x+y;
}
기명 함수(named function) - 함수 이름이 있다.
익명 함수(anonymous function) - 함수 이름이 없다.
// 함수 선언문
function foo() {
console.log('foo 함수');
}
// 함수 표현식
var add = function bar() {
console.log('bar 함수');
}
creation phase : 코드를 쭉 읽는 것
execution phase : runtime함수 선언문은 runtime 이전에 만들어진다.
함수 표현식은 runtime에 만들어진다.
foo(); // 호출 된다.
add(); // add is not a function
// 함수 선언문
function foo() {
console.log('foo 함수');
}
// 함수 표현식
var add = function bar() {
console.log('bar 함수');
}
JavaScript에서는 함수 표현식을 사용하는 것이 좋다!
선언문은 호이스팅 되어서 사용될 수 있기 때문이다.
: 함수를 선언함과 동시에 호출한다. 함수를 재사용 할 수 없다.
JavaScript 특유의 함수이다.
원래는 선언과 호출이 나뉘어져 있다.
function add() {
let x = 10;
let y = 20;
console.log(x + y);
}
add();
실행 결과 : 30
선언과 호출을 동시에 한다.
(function add() {
let x = 10;
let y = 20;
console.log(x + y);
}());
실행 결과 : 30
재사용을 못하기 때문에 함수 이름을 부여하지 않는다. (anonymous function)
(function() {
let x = 10;
let y = 20;
console.log(x + y);
}());
실행 결과 : 30
-> 즉시 실행 함수로 바꾸는게 좋다.
: nested function (inner function)
var x = 100; // global scope(전역변수)
var y = 200; // global scope(전역변수)
// outer function
function outer() {
let x = 0; // function level scope(지역변수)
// inner function
function inner() {
let x = 10; // function level scope(지역변수)
console.log(y);
}
}
외부함수 (outer function)
: 중첩함수를 가지고 있는 바깥쪽 함수
scope chain
: 모든 scope는 chain으로 이루어져 있다.
지역변수부터 찾기 시작해서 전역변수까지 올라간다. 전역변수는 scope chain의 가장 상단에 있기 때문에 전역변수를 사용하면 속도가 느려진다.
: 네가지 조건을 만족하는 객체를 1급 객체로 부른다.
함수형 언어에서 통용되는 용어이다.
익명의 literal로 생성이 가능하다.
: 동적으로 생성이 가능하다. (runtime에 생성이 가능하다.)
JavaScript 함수는 이 조건에 만족한다.
객체가 변수나 자료구조에 저장이 가능하다.
: 다른 객체에 property로 저장이 가능하다.
JavaScript 함수는 이 조건에 만족한다.
객체가 다른 함수의 인자로 전달이 될 수 있어야 한다.
: 함수를 다른 함수의 인자로 넘길 수 있다.
JavaScript 함수는 이 조건에 만족한다.
함수의 리턴값으로 객체를 사용할 수 있다.
: 함수의 리턴으로 함수가 될 수 있다.
JavaScript 함수는 이 조건에 만족한다.
-> JavaScript의 함수는 1급 객체이다.
잘 만들어서 사용하고 있는 함수가 이미 존재한다.
그런데 이 함수의 기능을 변경(추가) 해야 한다.
-> i가 홀수인 경우만 출력하게 바꾸고 싶다.
기존의 코드
: n이 입력되면 0부터 n개를 출력한다.
function repeat(n) {
for(var i=0; i<n; i++) {
console.log(i);
}
}
function repeat(n) {
for(var i=0; i<n; i++) {
if(i % 2) {
console.log(i);
}
}
}
function repeat1(n) {
for(var i=0; i<n; i++) {
if(i % 2) {
console.log(i);
}
}
}
function repeat(n, f) { // 고차 함수
for(var i=0; i<n; i++) {
f(i)
}
}
let logAll = function(i) { // 콜백 함수
console.log(i);
}
let logOdd = function(i) { // 콜백 함수
if(i % 2) {
console.log(i);
}
}
repeat(5, logOdd);
repeat(5, logAll);
콜백 함수(Callback Function)
: 고차 함수와 결합하는 함수
ex) 이벤트 처리, AJAX
고차 함수(Higher-Ordered Function)
: 콜백 함수를 받아서 합쳐서 하나의 기능을 하는 함수
: "식별자가 유효한 범위"
scope chain
: JavaScript engine이 식별자를 판단할 때 사용하는 메커니즘
JavaScript engine은 코드를 실행할 때 문맥(context)을 고려한다. 현재 실행 중인 코드가 어디에 있는 코드인지, 코드 주변 정보를 파악해서 실행한다. 이런 문맥이 저장되어 있는 곳을 context environment라고 한다.
=> lexical environment를 고려해서 실행한다.
=> 이를 실제로 구현한 것이 execution context이다.
함수가 호출되었을 때, scope를 함수가 호출된 곳을 기준으로 설정할 것인지, 함수가 정의된 곳을 기준으로 설정한 것인지 애매하다.
var x = 1; // 전역 scope의 전역 변수
function foo() {
var x = 10; // 지역 scope의 지역 변수
bar();
}
function bar() {
console.log(x);
}
foo();
실행 결과 : 1
-> 따라서 위의 코드는 정의된 곳을 기준으로 scope를 설정한다.