Notice
Recent Posts
Recent Comments
Link
«   2026/07   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

어리바리 신입 개발자의 얼렁뚱땅 개발 기록 ✨

23.03.30 / 함수 function 본문

Front - end/JS

23.03.30 / 함수 function

낫쏘링 2023. 3. 30. 16:43
728x90

{ 함수 }

  • 메모리에 코드를 저장 할 수 있는 수단
  • function이라는 키워드를 사용하여 선언이 가능하다.
  • 함수는 선언 후에 호출이 되어야 저장된 코드가 실행된다. (단, 일반함수는 선언 전에 호출 가능)
  • 함수에는 일반함수와 익명함수가 존재한다.
  • 함수를 하나 선언해 두면 굳이 코드를 반복해서 사용할 필요 없이 함수를 호출만 하면 된다.
  • return 키워드를 만나면 함수는 종료 된다. - return 없으면 undefined (return 변수; / return; 형태 둘 다 사용 가능)
  • return 키워드와 값을 지정하게 되면 함수를 호출한 곳에 그 값을 전달하게 한다.
function returnCall(n1, n2){
    return n1 + n2; //리턴하려는 값
}
//호출한 곳에 값을 전달
var result = returnCall(10,20); // n1 + n2 의 값인 30이 출력된다.
console.log(result);

 

[ 함수와 메서드의 차이 ]

  • 객체의 구성 : 속성 / 메서드
객체 내에서 함수를 선언하는 것을 기능/동작/메서드(데이터를 참조하고 조작할 수 있음)라고 한다.
▶ 메서드의 구성 -> 메서드명(매개변수명-생략가능) {구현}

객체 내에서 함수 외의 것을 선언하는 것을 데이터/속성/프로퍼티라고 한다.
▶ 속성/프로퍼티의 구성 -> 키 : 값

즉, 객체에 생성된 함수를 메서드라고 한다.

 

[ 자바스크립트에서 함수의 특징 - 일급객체/일급함수  / 객체지향형 & 함수형]

  • 자바스크립트에서 객체는 일급 객체다.
  • 자바스크립트에서 함수는 객체이기 때문에 일급 객체 / 일급 함수다.
일급 함수란 ?
함수를 다른 함수의 매개변수로 전달이 가능하거나, 변수에 담을 수도 있고, 인자나 값으로도 사용이 가능한 함수

- 참조 값을 사용할 수 있는 곳이라면 어디든지 사용 가능무명의 리터럴(익명함수)로 생성할 수 있다. 즉, 런타임(실행시점)에 생성이 가능하다. (자바에서도 비슷하게 생성은 가능)
- 변수나 자료구조(객체, 배열 등)에 저장할 수 있다. (배열 안에 어떠한 형태든 다 저장할 수 있다. - 자바는 안 됨 데이터 타입 정해져 있기 때문 / 즉, 자바는 일급함수 일급객체 x )
- 함수의 매개변수에 전달할 수 있다.
- 함수의 반환값으로 사용할 수 있다.
이런 특징이 함수형 프로그래밍을 가능하게 함
(객체지향형 프로그래밍 - 자바 / 자바스크립트는 객체지향형,함수형 둘 다 지니고 있음)

프로그래밍의 발전 순서
절차지향형 프로그래밍(c) -> 객체지향형 프로그래밍(java) -> 객체지향형 & 함수형 프로그래밍(java script)

자바스크립트는 객체지향형 프로그래밍의 형태 역시 지니고 있지만 class 존재하지 않는다.
상속,추상화,다형성은 존재 - 사실 상속되는 것은 아니고 prototype으로 연결해서 상송을 받는 척 한다. (추상화와 다형성도 마찬가지)
자바에서 class를 통해 객체를 생성한다고 배웠는데 class가 없는데 어떻게 객체를 만들어? - 그냥 class 없이 만들어
// 클래스 없이 바로 객체 생성
let obj = {
	name : '홍길동',
    arr : []
}​

이와 같이 자바스크립트는 객체지향형과 함수형 프로그래밍을 섞어 사용하고 있다.

// 객체지향 프로그래밍 (자바)
// car라는 객체를 생성
// 객체 car의 주소로 찾아가 start 메서드와 move 메서드를 호출한다.
// 객체 중심
car.start();
car.move(10);

// 함수형 프로그래밍 (자바스크립트)
// 객체 생성 x (자바스크립트에서 객체 생성은 let obj = {}) 
// 함수 중심
start(car);
move(car, 10);

 

[ 함수 선언 ]

  • function 함수명(){}
  • {} - 스코프 (블럭, 유효범위)
  • 함수는 지역변수와 전역변수의 차이가 확실하다.

 

[ 자바스크립트의 매개변수 / 오버로딩 ]

  • 자바와 다르게 자바스크립트의 매개변수는 자유롭게 사용한다. (데이터 타입 없어도 됨 - java : String name / js : name)
  • 자바와 다르게 함수의 오버로딩 불가능
※ 자바스크립트의 오버로딩(불가능) ※

- 함수가 동일한 이름으로 선언됐을 때
- 평가 시점에 위의 함수와 아래 함수가 동시에 호이스팅 됨
- 이름이 같기 때문에 가장 아래에 선언된 함수로 덮어 씌워짐
- 때문에 1번 호출에서 최종적으로 호출1과 undefined를 콘솔에 출력한다.
- 여기서 undefined는 1번 리턴이 아닌 2번 리턴의 결과(호이스팅에서 덮어 씌워졌기 때문)
- 2번 호출을 통해서는 호출1이 콘솔에 출력되고 끝난다.

왜 1번 호출에서는 호출1과 undefined 까지 출력됐는데 2번 호출에서는 호출1만 출력되고 끝난걸까?
- 1번 호출에서는 return 값을 콘솔에 출력할 수 있는 콘솔로그 안에서 함수가 호출 되었고
- 2번 호출에서는 return 값을 콘솔에 출력할 수 있는 콘솔로그 없이 단독으로 함수가 호출 되었기 때문

function returnTestFn(){
    return;  // 1번 리턴
}
console.log(returnTestFn(), '1번 호출'); 
// 아래 동명의 함수가 선언되기 전에는 1번 리턴값 undefined 출력

// 동명의 함수 재선언(오버로딩) - 결과적으로 불가능
function returnTestFn(){
    console.log('호출1'); 
    return;	 // 2번 리턴						
    console.log('호출2'); 
}
returnTestFn(); // 2번 호출

------------------------------------------------------------------------------------

※ 자바의 오버로딩(가능) ※

void overload(){
  System.out.println("매개변수 없음");
}

void overload(Strin name, int age){
  System.out.println("매개변수" + name + age + "총 두 개");
}

void overload(char gender){
  System.out.println("매개변수" + gender + "한 개");
}

overload();
overload("홍길동", 8);
overload('남');
// 선언 당시 입력된 매개변수에만 맞게 호출해주면 동명 메서드도 선언 가능하고
// 출력도 다 다르게 나온다.

 

[ 함수의 종류 ]

< 1. 일반 함수 >

함수명 있음, 호이스팅 O -> 선언부 위에서 호출 가능

fn(); // 선언 전에 호출 가능
function fn(){ // 함수 이름 존재
    console.log('일반함수 실행');
}
fn(); // 선언 후에 호출하는 것도 당연히 가능

< 2. 익명 함수 >

함수명 없음 -> 변수 선언/할당해서 대신 사용 가능 , 호이스팅 X -> 선언부 위에서 호출 불가능

fn1(); //호이스팅 x (평가 시점에 함수 할당 x / 실행 시점에 함수 할당 o) -> 선언 전에 호출 불가능
const fn1 = function(){  // 익명함수는 함수명이 존재하지 x - 대신 변수에 대입해서 사용 
    console.log('익명함수 실행');
}
fn1(); // 선언 후에 호출하는 것은 당연히 가능

//화살표 함수 선언 ( 익명함수의 일종이기 때문에 호이스팅 x )
arrFn1(); // 호이스팅 x
arrFn2();
const arrFn1 = () => {
    console.log('화살표함수1 실행');
}
const arrFn2 = () => console.log('화살표함수2 실행'); // 코드가 하나일 때 한 줄로 쓰기 가능
arrFn1();
arrFn2();
[ 화살표 함수 이해하기 ]
화살표 함수 쓰는 이유
 1. 함수를 짧게 쓸 수 있음
     (매개변수) => 표현식;
 2. 자바스크립트에서는 함수를 생성하고 그 함수를 어딘가에 전달하는 것이 자연스러움
     그런데 어딘가에 함수를 전달하게 되면 함수의 컨텍스트(함수 동작에 필요한 정보를 담은 객체)를 잃을 수 있다.
     이럴 때 화살표 함수를 사용하면 현재 컨텍스트를 잃지 않아 편리
      - 컨텍스트? 코드의 흐름/문맥이나 함수 동작에 필요한 환경 정보가 담긴 객체

화살표 함수의 특징

 1. 익명 함수
 2. 생성자로 사용할 수 없다.
 3. 자기 자신의 this를 갖지 않는다. - 함수가 정의된 스코프에 존재하는 this를 가리킨다.
     (객체 안에 있는 메서드의 내부 함수에서 this를 사용하면 속한 객체의 this가 아닌 전역 객체의 this를 가리킴)
     즉, 컨텍스트를 잃을 수 있음.    [this 자세하게 보기]
 4. 생성될 때 this 가 결정된다.
 5. 화살표 함수가 어떻게 사용되건, 호출되건, this가 가리키는 것은 바뀌지 않는다.
 6. return하지 않아도 값이 반환된다. ( 중괄호 사용시 return 해야함 )
// 기본 익명함수를 사용했을 때
// 내부함수의 this는 자신이 속한 객체를 가리키지 않고 전역 객체를 가리키기 때문에
// this.name은 존재하지 않는다. (전역 스코프에 선언된 name 없음)
const cat = {
    name: 'meow',
    sound: function() {
        let sound2 = function() {
            console.log(this.name);
        }
    sound2();
    }
};
cat.sound(); // undefined


// 이 때 화살표 함수로 바꿔주면 this는 무조건 함수가 정의된 스코프의 객체를 가리키기 때문에
// meow를 출력한다.
const cat = {
    name: 'meow',
    sound: function() {
        let sound2 = () => console.log(this.name);
    	sound2();
    }
};
cat.sound(); // meow 출력

 

// 기본 익명함수
let func = function(arg1, arg2, ...argN) {
  return expression;
};

// 화살표 함수 (위의 기본 익명함수와 같은 코드)
// function 생략 , 화살표 입력
// let func = 는 변수에 할당해서 대신 사용해주는 방법이다.
// 즉 화살표 함수의 구조는 사실 (매개변수) => 표현식; 이다.
let func = (arg1, arg2, ...argN) => expression;
let func = (arg1, arg2, ...argN) => (expression);
let func = (arg1, arg2, ...argN) => {return expression};

// 받을 인수가 없는 경우 매개변수 자리 비워두는 것도 가능
// 단, 괄호 생략 불가
let func = () => expression;

// 단, 매개변수가 하나일 때 괄호 생략 가능 (매개변수가 없거나 두 개 이상이면 무조건 괄호 씀)
let func = arg => expression;

// 표현식이 여러 줄 일 경우 {} 사용
// 중괄호를 쓸 때는 반환할 값에 return 표시 해야함.
let func = () => {
    expression1;
    return expression2;
};

// 화살표 함수에서 객체 리턴하기
const arrowObj = () => ({}) 
const arrowObj = () => {return{}}

let : 변수 선언 키워드
func : 변수 이름 (화살표 함수는 익명함수기 때문에 변수에 할당)
arg1, arg2, ...argN : 매개변수
expression : 표현식

매개변수에 인자 값을 받아 표현식을 평가하고 평가 결과를 "반환 return"한다.

 

[ 함수 복사 ]

const func1 = function(){
    console.log('익명함수 func1 실행');
}

const arrowFn3 = () => {
    console.log('익명함수(화살표 함수) arrowFn3 실행');
}

let copyFn1 = func1;    // 함수는 객체 타입이기 때문에 주소 복사 가능 (얕은 복사)
let copyFn2 = arrowFn3;
copyFn1();
copyFn2();
console.log(copyFn1 == func1, '복사한 함수 같은 주소 여부 확인');
console.log(typeof copyFn1, '<- function의 타입'); //function 타입 연산 시 function 문자열 반환
console.log(typeof null, '<- null의 타입'); //null 타입 연산 시 object 문자열 반환
console.log(typeof [], '<- array의 타입'); //array 타입 연산 시 object 문자열 반환

// 깊은 복사도 가능하지만 주의해야할 점 (배열과 객체도 마찬가지)
// 복사의 범위가 가장 바깥의 depth 까지다.
// const arr = [1,2,3,[5,6],4]; 의 경우 1,2,3,4는 깊은 복사를 하지만 5,6은 얕은 복사가 된다.

 

 

728x90