function 명령으로 정의function 명령으로 정의function getTriangle(base, height) { // global 선언
return base * height / 2;
};
getTriangle(base, height) 에서 base, heght의 타입과 getTriangle의 리턴타입이 없음console.log(getTriangle(5, 2));
>> 5
권장하지 않으므로 신경쓰지 말기!
var getTriangle = function(base, height) {
return base * height
};
function(base, height) 의 function에 함수 이름을 쓸 필요 없다 (쓴다고 해도 무시됨)console.log(getTriangle(5, 2));
>> 5
(파라미터, ...) => { 함수의 본체 }
let getTriangle = (base, height) => {
return base * height / 2;
};
console.log(getTriangle(5, 2));
>> 5
// return 생략
let getTriangle = (base, height) => base * height / 2;
// 파라미터 1개인 경우 튜플의 괄호 생략
let getCircle = radius => radius * radius * Math.PI;
// 파라미터 없는 경우
let show = () => console.log('안녕하세요, 자바스크립트!');
함수로 지정된 변수를 출력하면, 함수 본문 내용이 출력
console.log(getTriangle);
getTriangle 변수값이 원래 함수로 지정되어 있다가, 숫자 0으로 변경
getTriangle = 0; console.log(getTriangle); >> 0✅ getTriangle의 데이터타입이 number로 변경됨
✅ 해당 함수는 사라지며, error 발생X
function 을 사용한 함수 정의console.log('사각형의 면적:' + getRectangle(5, 2)); function getRectangle(base, height) { return base * height; }✅ 정상적으로 5를 출력함
var로 선언하는 함수 리터럴 ➡ 변수선언변수를 먼저 사용하고 나중에 변수값이 결정되는 경우
변수 먼저 사용할 때 undefined의 값이 할당됨console.log(getTriangle(5, 2)); var getTriangle = (base, height) { return base * height / 2; };💥 'getTriangle is not a function' 에러 발생
console.log('사각형의 면적:' + callFunctionLiteral()); callFunctionLiteral = function () { console.log('함수 리터럴을 선언한 후에 이 함수 리터럴을 사용해야만 에러 발생X'); }💥 'callFunctionLiteral is not defined' 에러 발생
글로벌/로컬 변수는 var로 선언하여 사용
var scope = 'Global Variable'; function getValue() { var scope = 'Local Variable'; return scope; } console.log(getValue()); // 'Local Variable' console.log(scope); // 'Global Variable'
특히 로컬 변수 선언에 var사용 필수
✅ 로컬변수를 var로 선언하지 않으면 글로벌 변수로 인식됨 ⭐⭐scope1 = 'Global Variable'; // global 변수로 인식 function getValue1() { // scope1이 var로 선언되어 있지 않으면, global변수로 인식됨 scope1 = 'Local Variable'; // 기존 global 변수인 scope1 값을 변경 return scope1; } console.log(getValue1()); // 'Local Variable' console.log(scope1); // 'Local Variable'
로컬변수의 유효 범위
➡ 함수 중간에 로컬 변수를 선언하는 경우var scope = 'Global Variable'; function getValue() { // 아래의 scope : local variable // hoist에 의해 에러는 발생하지 않으나 // 실제 scope의 값이 뒤에 결정되어 undefined 출력 console.log(scope); var scope = 'Local Variable'; return scope; }✅ 오류의 많은 부분을 차지함
✅ 결론 : 가급적이면 로컬변수는 함수 첫 부분에 선언한다.
1) 매개변수가 기본형
: 로컬변수로 처리되고, 글로벌 변수에 영향을 미치지 않음
var value = 10;
function decrementValue(value) {
value--;
return value;
}
console.log(decrementValue(100)); // 99
console.log(value); // 10
2) 매개변수가 참조형
: 로컬변수로 처리되나, 글로벌 변수에 영향 미침
var value = [1, 2, 4, 8, 16]; // 주소=200 이라고 가정
function deleteElement(value) { // 주소=200을 참조
value.pop();
return value; // 주소=200의 값이 변함
}
console.log(deleteElement(value)); // [1,2,4,8]
console.log(value); // [1,2,4,8]
3) 블록 레벨 scope : 원래 자바스크립트에서 지원 안함 (ES5)
if (true) {
// 함수가 아닌 if, while문 등
// 제어문에서 var로 선언한 변수는 global 변수로 인식됨
var i = 5;
}
console.log(i); // 5
4) 즉시실행함수 (IIFE) ⭐⭐
( function() {...} ) (); <- 함수 선언 + 즉시 실행
(function() { // 무명 함수 선언
var a = 10; // 블록레벨
console.log(a); // 10
})(); // 즉시 실행
console.log(a); // a는 스코프 밖이므로 에러 발생
(function() { // 무명 함수 선언
var a = 5; // 블록레벨
console.log(a); // 10
}).call(this); // 즉시 실행
console.log(a); // a는 스코프 밖이므로 에러 발생
5) let 명령으로 블록레벨 스코프 지원 (ES6)
if (true) {
let i = 5; // 블록레벨
}
console.log(i); // 에러 발생
{
let a = 5;
console.log(a); // 5
}
console.log(i); // 에러 발생
// switch문의 각 case마다 똑같은 이름의 변수를 let으로 선언하면 error 발생
// switch(x) {
// case 0:
// let value = 'x:0';
// case 1:
// let value = 'x:1';
// }
// switch문 이전에 let으로 변수 선언하여 사용할 것
let value='';
switch(value) {
case 0:
value = 'x:0';
case 1:
value = 'x:1';
}
1) 자바스크립트는 기본적으로 매개변수의 수를 체크하지 않음 ⭐
2) 자바스크립트는 매개변수 정보를 argument 객체에 제공함 ⭐
✅ argument라는 function 객체의 field를 호출할 때, argument data들이 자동 저장됨
✅ argument 객체에는 건네진 모든 인수 값이 보존됨
function showMessage(value) {
console.log(value);
}
showMessage(); // arg[0] = undefined, arg[1] = undefined
// arg.length = 0
showMessage('철수'); // arg[0] = '철수', arg[1] = undefined
// arg.length = 1
showMessage('철수', '영희'); // arg[0] = '철수', arg[1] = '영희'
// arg.length = 2
3) 매개변수의 수를 체크할 경우 추가 코딩 필요
// 인수 갯수가 맞지 않을 때 error 처리
function showMessage1(value) {
if (arguments.length !== 1) { // 예외처리
throw new Error('인수의 수가 서로 다릅니다:' + arguments.length);
} // Error : 함수명
console.log(value);
}
try {
showMessage1(' 철수', ' 영희');
} catch(e) {
window.alert(e.message);
}
function getTriangle(base, height) {
if (base === undefined) { base = 1; }
if (height === undefined) { height = 1; }
return base * height / 2;
}
console.log(getTriangle(5)); // 2.5
4) 가변길이 매개변수 함수 정의하기
function sum() { // 인수 지정X
var result = 0;
console.log(arguments.length);
// 주어진 인수를 순서대로 취득하여 차례로 더하는 처리
for (var i = 0, len = arguments.length; i < len; i++) {
console.log(arguments[i]);
var tmp = arguments[i];
if (typeof tmp !== 'number') {
throw new Error('인수값이 숫자가 아닙니다.:' + tmp);
}
result += tmp;
}
return result;
}
try {
// 파라미터 수를 원하는 대로 줄이고 늘릴 수 있다는 장점
console.log(sum(1, 3, 5, 7, 9, 11));
} catch(e) {
window.alert(e.message);
}
5) 명명된 매개변수 사용 : { } 객체 표기 사용
✅ 파라미터를 Object로 변환 ⭐
// args : {} 객체 데이터타입
function getRectangle(args) { // default 값 정의
if (args.base === undefined) { args.base = 1; }
if (args.height === undefined) { args.height = 1; }
return args.base * args.height;
}
console.log(getRectangle({ base:5, height:4 })); // 20
console.log(getRectangle({ height:5 })); // 5
console.log(getRectangle({ height:6, base:2 })); // 12
1) 매개변수 default 값 선언
function getTriangle(base = 1, height = 1) {
return base * height / 2;
}
console.log(getTriangle(5)); // 2.5
function multi(a, b = a) {
return a * b;
}
console.log(multi(10, 5)); // 50
console.log(multi(3)); // 3*3 = 9
default 값 선언할 때 뒤에 있는 변수 참조하면 에러 발생 가능
// a = b를 인수의 처음에 사용하면 안됨 // 왜냐하면 나중에 선언된 인수 b를 사용하기 때문 function multi(a = b, b = 5) { return a * b; } console.log(multi());
default 값 사용시 주의점
- 함수를 부를 때 매개변수가 명시적으로 건네지지 않은 경우에만 default 값이 사용됨 (매개변수 값이 undefined도 포함)
✅ 함수를 부를 때 null/false/0/빈 문자열 '' 등 의미상 비어 있음을 나타내는 값이라도 명시적으로 건네지면 default 값 사용Xfunction getTriangle(base = 1, height = 1) { return base * height / 2; } console.log(getTriangle(5, null)); // 0 console.log(getTriangle(5, undefined)); // 2.5
- default 값을 갖는 매개변수는 매개변수 리스트의 끝에 선언
✅ default 값을 먼저 선언하면 코드의 의도가 명확하지 않음function getRectangle(base=1, height) { return base * height; } // 10이 base의 값으로 넘겨지고, height는 undefined가 됨 console.log(getRectangle(10));
2) 가변길이 매개변수 함수 정의
function sum(...nums) { // nums를 array 데이터타입으로 자동 형변환
let result = 0;
console.log(nums); // nums : array
for (let num of nums) {
if (typeof num !== 'number') {
throw new Error('지정값이 숫자가 아닙니다:' + num);
}
result += num;
}
return result;
}
try {
console.log(sum(1, 3, 5, 7, 9, 11));
} catch(e) {
window.alert(e.message);
}
// ...의 다른 사용 예
console.log(Math.max(15, -3, 78, 1));
console.log(Math.max([15, -3, 78, 1])); // error 발생 => NaN (argument가 1개인것으로 인식)
// 해결책
console.log(Math.max.apply(null, [15, -3, 78, 1])); // ES5 방식
console.log(Math.max(...[15, -3, 78, 1])); // ES6 방식
// ...[15, -3, 78, 1] => 배열을 배열이 아닌 형태로 변환
3) 분할대입 방법을 통한 명명된 매개변수 전달
function getTriangle({ base = 1, height = 1 }) {
return base * height / 2;
}
console.log(getTriangle({ base:5, height:4 })); // 10
function show({name}) { // 'name' property만 선택하여 가져옴
console.log(name);
};
let member = {
mid: 'Y0001',
name: '심우진',
address: 'shim_me_shim_Me_ya@example.com'
};
show(member); // 심우진
1) 복수의 return 값을 개별 변수에 대입
function getMaxMin(...nums) {
// return 값 여러개 -> 배열로 return 가능
// 별도의 배열 생성, 대입 과정 필요X
return [Math.max(...nums), Math.min(...nums)];
}
let result = getMaxMin(10, 35, -5, 78, 0);
console.log(result); // [78, -5]
let [max, min] = getMaxMin(10, 35, -5, 78, 0); // 분할대입
//let [,min] = getMaxMin(10, 35, -5, 78, 0);
console.log(max); // 78
console.log(min); // -5
2) 재귀 함수
function factorial(n) {
if (n != 0) { return n * factorial(n - 1); }
return 1;
}
console.log(factorial(5));
3) 함수 매개변수가 함수인 경우 : callback 함수 ⭐⭐
function arrayWalk(data, f) { // 함수를 파라미터로 받음 = callback 함수
for (var key in data) {
f(data[key], key); // 내부에서 함수 실행
}
}
function showElement(value, key) { // 사용자 정의 함수
console.log(key + ':' + value);
}
var ary = [1, 2, 4, 8, 16];
arrayWalk(ary, showElement); // 함수를 파라미터로 부름
var result1= 0; // 글로벌 변수
function sumElement(value, key) {
result1 += value;
}
arrayWalk(ary, sumElement);
console.log('합계:' + result1); // 31
4) 일회용 함수는 익명함수(anonymous function)로 표현 가능
arrayWalk(
ary,
function (value, key) {
console.log(key + ':' + value);
}
);
1) 변수 scope chain
// Global scope 객체 : property : var y = 'Global', method = outerFunc()
var y = 'Global';
function outerFunc() {
// call scope 객체 : property : var y = 'Local Outer', arguments, method = innerFunc()
var y = 'Local Outer';
function innerFunc() {
// call scope 객체 : property : var z = 'Local Inner', arguments, method(없음)
var z = 'Local Inner';
console.log(z); // Local Inner
console.log(y); // Local Outer
console.log(x); // 에러 (미정의)
}
innerFunc();
}
outerFunc();
2) 클로저 (Closure) ⭐⭐
// closure함수 정의 : 특정 함수의 return값이 함수이면서,
// return한 함수안에 부모 local 변수를 사용한 경우
function closure(init) {
// counter : local variable
var counter = init;
return function() {
return ++counter; // 부모 함수인 closure의 로컬변수를 사용
}
}
// myClousure = function() { counter=1, return ++counter; };
var myClosure = closure(1);
console.log(myClosure()); // 2
console.log(myClosure()); // 3
console.log(myClosure()); // 4
var myClosure1 = closure(1);
var myClosure2 = closure(100);
console.log(myClosure1()); // 2
console.log(myClosure2()); // 101
console.log(myClosure1()); // 3
console.log(myClosure2()); // 102
