by Kyojin Hwang
// 함수 선언문(Declaration)
function hello() {}
// 함수 표현식(Expression)
const hello = function () {}
// 호출방법 : 함수이름을 적고 소괄호로 호출하여 실행한다.
hello()
😫선언식과 표현식의 차이점
선언식
: 함수 전체를 호이스팅 한다. 정의된 범위의 맨 위로 호이스팅되서 함수 선언
전에 함수를 사용할 수 있다는 것이다.
표현식
: 별도의 변수에 할당하고, 변수는 선언부와 할당부를 나누어 호이스팅한다.
함수선언식 과 함수 표현식
// 호이스팅
// 함수 선언식
alert(bomb()) // ❌에러 발생 bomb 함수는 아직 로드안됨
const bomb = function () {
return 1
}
// 함수 표현식
alert(bomb())
// 선언 전에 호출되도 정상 동작⭕
function bomb() {
return 5
}
🙄그럼 누가 더 좋아?
함수 표현식의 장점
내생각
: 아무래도 함수표현식이 더좋다!
그이유는 코드가 너무 깔끔하게 보이는게 나에게는 아직은 가장 큰 장점인것 같다...
클로저
함수가 종료돼도, 렉시컬 스코프의 index와 같은 정보를 유지한다.
인자 전달
함수 표현식은 중간 임시 변수에 할당 할 필요없이 함수에 직접 전달할 수 있다.
IIFE (즉시 주입 함수 표현식)
함수와 변수가 전역 스코프에 영향을 미치지 않도록 방지하는 데 사용된다.
👊호이스팅이란?
코드가 실행하기전 변수선언
/ 함수선언
이 해당 스코프의 최상단으로
끌어 올려진것 같은 현상을 말한다.
📃변수 호이스팅
자바스크립트에서의 변수 처리
자바스크립트에서는 총 3단계에 걸쳐 변수를 생성한다.
선언 단계(Declaration phase)
초기화 단계(Initialization phase)
할당 단계(Assignment phase)
❗호이스팅 예시
// 호이스팅 때문에 선언이 끌어올려져서 오류 안남⭕
console.log(text); // (선언 + 초기화 된 상태)
text = 'kyo!'; // (선언 + 초기화 + 할당 된 상태)
var text;
console.log(text);
----------------------------------------------------
text = 'Hello'; // 선언 없으면 var로 선언한 것과 동일해진다.❌
let text; // 여기서 var 선언을 let으로 변경해준 것이다.❌
console.log(text);
// let 키워드로는 선언이 끌어올려지지 않기 때문에 undefined를 리턴함.
----------------------------------------------------
const text;
// 에러남. 주의❗ 애초에 const 키워드로 재할당 불가능! 그래서 선언과 동시에 할당해야함
----------------------------------------------------
참고 블로그
https://hanamon.kr/javascript-%ED%98%B8%EC%9D%B4%EC%8A%A4%ED%8C%85%EC%9D%B4%EB%9E%80-hoisting/
https://yoo11052.tistory.com/151
return
function hello() {
return "Hello~";
}
console.log(hello()); // Hello~
function hello2() {
return;
}
console.log(hello2()); // undefined
-------------------------------------
// 예시
function plus(num){
return num + 1;
}
console.log(plus(2)); // 3
console.log(plus(7)); // 8
console.log(plus()); // NaN : 이유는 num에 아무값도 들어오지않아서 (undefined + 1)
// 하지만 NaN 이 안나오는 방법이 있다❗
function plus(num){
// 조건문을 활용한다.
if(typeof num !== 'number'){
console.log('숫자를 입력해주세요.')
return 0; // 여기서 return을 사용하였기 때문에 아래의 return은 사용되지 않는다.
}
return num + 1;
}
매개변수
인자
// function add(a,b) => a와 b는 매개변수 이다.
function add(a, b) {
return a + b;
}
// add(5, 3) => 5와 3은 인자
console.log(add(5, 3)); // 8
----------------------------------------------
// 🧐기본값 패턴
// b 에 기본 값 1을 주고
// 값을 넣어도되고 안넣어줘도 기본값을 사용할 수 있게 만들어줬다.
function sum(a, b = 1){
return a + b;
}
console.log(sum(7)); // 8
console.log(sum(1,2)); // 3
----------------------------------------------
// 🧐객체 구조분해할당 패턴
const userObj = {
name : 'kyo',
age : 28
email: 'owen1127@naver.com'
}
// ex)1 : user 파라미터를 구조분해할당하여 변수에 저장하여 사용
function getName(user){
const { name } = user // 여기는 파라미터를 가지고온다.
return name;
}
// ex)2 : 파라미터에서 구조분해할당하여 코드를 줄인다.
function getName({name}){
return name;
}
// ex)3 : 기본값을 활용한 구조분해할당 패턴
function getEmail({ email = '이메일이 없습니다.'}) {
return email;
}
// 여기는 맨상단 객체를가져와서 인자로 넣는다
console.log(getName(userObj)); // kyo
console.log(getEmail(userObj)); // owen1127@naver.com
----------------------------------------------
// 🧐배열 구조분해할당 패턴
const fruits = ['Apple', 'Banana', 'Cherry']
// ex1 ) 첫번째 방법
function getFruits([a, b, c]){
return b;
}
// ex2 ) 두번째 방법
function getFruits([, b]){
return b;
}
console.log(getFruits); // Banana
----------------------------------------------
// 🧐나머지 매개변수(Rest parameter)
// 매개변수 몇개를 사용할지 모를때 사용하게 된다.
function sum(...rest) {
console.log(rest);
console.log(arguments);
// arguments(유사배열)는 배열데이터가 아니여서 reduce 사용불가
return rest.reduce(function (acc, cur) {
return acc + cur;
}, 0);
}
console.log(sum(1, 2)); // 3
console.log(sum(1, 2, 3, 4)); // 10
console.log(sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)); // 55
const sum = (a, b) => {
return a + b
}
console.log(sum(1, 2)) // 3
화살표 함수의 패턴
const a = () => {}
const b = (x) => {}
const c = (x, y) => {}
const d = (x) => {
return x * x
}
const e = (x) => x * x
const f = (x) => {
console.log(x * x)
return x * x
}
const g = () => {
return { a: 1 }
}
const h = () => ({ a: 1 })
const i = () => {
return [1, 2, 3]
}
const j = () => [1, 2, 3]
// 기존함수 사용방법
const a = 7
const double = () => {
console.log(a * 2)
}
double() // 14
// 즉시실행함수
const a = 7
;(() => {
console.log(a * 2)
})()
// 즉시실햄함수 패턴
;(() => {})() // 첫번째
;(function () {})() // 두번째
// 즉시실행함수 사용해보기
;((a, b) => {
console.log(a)
console.log(b)
})(1, 2)
// ex1)
const a = (callback) => {
callback()
console.log('A')
}
const b = () => {
console.log('B')
}
a(b) // B다음 A 가 나온다.
// ex2)
const sum = (a, b, c) => {
// setTimeout : 지연시켜주는 함수 (현재 여기서는 콜백으로 사용된다.)
setTimeout(() => {
// c 는 sum의 세번째 매개변수의 함수를 실행시킨다.✔
c(a + b)
}, 1000)
}
sum(1, 2, (value) => {
console.log(value) // 3
})
sum(3, 5, (value) => {
console.log(value) // 8
})
// 조건을 주지않으면 무한반복된다 그리고 컴퓨터가 터진다.💣
let i = 0
const a = () => {
console.log('A')
i += 1
if (i < 4) {
a()
}
}
a()
// 객체로 재귀예시 만들어보기
const userA = { name: 'A', parent: null }
const userB = { name: 'B', parent: userA }
const userC = { name: 'C', parent: userB }
const userD = { name: 'D', parent: userC }
const getRootUser = (user) => {
if (user.parent) {
// userB,C,D 는 parent가 이어져서 다시 함수를 호출한다.
return getRootUser(user.parent)
}
// 마지막으로 A에는 null 이기때문에 A객체가 나오게 된다.
return user
}
console.log(getRootUser(userD))
스케줄링이란?🧐
const hello = () => {
console.log('Hello')
}
// 스케줄
const timeout = setTimeout(hello, 2000)
// ex1) 곧바로 종료
// clearTimeout 으로 인하여 timeout이 실행되지 않는다.
clearTimeout(timeout)
// ex2) h1 클릭으로 인해 종료
const h1El = document.querySelector('h1')
h1El.addEventListener('click', () => {
console.log('Clear!')
clearTimeout(timeout)
})
setTimeout과 setInterval 차이
객체
또는 자신이 생성할 인스턴스
를 가리키는 자기 참조 변수렉시컬이란?🧐
함수가 동작할 수 있는 유효한 범위!!
// ex 1)
const user = {
firstName: "Kyojin",
lastName: "Hwang",
age: 28,
// 일반함수 접근
getFullName: function () {
// user 안에서 사용하기 때문에 단순하게 this로 접근이 가능하다
return `${this.firstName} ${this.lastName}`;
},
// 화살표함수 접근
getArrowFullName: () => {
return `${this.firstName} ${this.lastName}`;
},
};
console.log(user.getFullName()); // Kyojin Hwang
console.log(user.getArrowFullName()); // undefined undefined
----------------------------------------------
// ex 2)
function user() {
this.firstName = "Cold";
this.lastName = "Owen";
return {
firstName: "Kyojin",
lastName: "Hwang",
age: 28,
getFullName: function () {
return `${this.firstName} ${this.lastName}`;
},
getArrowFullName: () => {
return `${this.firstName} ${this.lastName}`;
},
};
}
const friend = {
firstName: "Yonam",
lastName: "Youtube",
};
const u = user();
console.log(u.getFullName()); // Kyojin Hwang
console.log(u.getArrowFullName()); // Cold Owen
console.log(u.getFullName.call(friend)); // Yonam Youtube
----------------------------------------------
// ex 3) 렉시컬 예제 만들기
const timer = {
title: "TIMER!",
timeout() {
console.log(this.title);
// 아래의 setTimeout에서 일반함수를 사용하면 안되는이유❗
// setTimeout의 내부구조를 알 수 없기 때문에 undefined 가 나오게된다.
// 그래서 setTimeout을 화살표함수로 표기할 경우 timeout의 this를 바라본다.
setTimeout(() => {
// 콜백
console.log(this.title);
}, 1000);
},
};
timer.timeout(); // TIMER! (1초뒤) TIMER!
Property
객체의 내부의 속성이다.
객체 내부에 함수를 값으로 가지는 속성은
메서드(Method)
라고 할 수 있습니다.
Method란?🧐
getFullName
과getArrowFullName
같이 객체에 할당되는 함수
this 일반함수 접근 ( 상단의 예제로 설명)
this 화살표함수 접근 ( 상단의 예제로 설명)