한 걸음씩

[JS][Udemy] JavaScript Functions 2 본문

JS

[JS][Udemy] JavaScript Functions 2

winter17 2023. 3. 21. 23:15

1.  Scope & Block

Scope 

  • 범위는 '변수 가시성'을 참조함
  • 범위는 함수
// JS는 한정된 함수 안에 같은 이름으로 정의된 변수가 있을 경우 그 변수를 먼저 참조함

let bird = 'mandarin duck'
function birdWatch(){
  let bird = 'golden pheasant'
  console.log(bird); 
}
birdWatch() 

// golden pheasant
// 함수 안에 선언된 변수가 없다면 외부에 선언된 변수를 참조한다
let bird = 'mandarin duck'
function birdWatch(){
  console.log(bird);
}
birdWatch() 

// mandarin duck
let deadlyAnimal = "Blue-Ringed Octopus";
 
function handleAnimal() {
    let deadlyAnimal = "Scorpionfish";
    console.log(deadlyAnimal); // 함수안에 선언된 변수 먼저 출력
}
 
handleAnimal();
console.log(deadlyAnimal) // 함수 외부에 선언된 변수가 이미 존재하므로 "Blue-Ringed Octopus"

// Scorpionfish
// app.js:9 Blue-Ringed Octopus

 

 

► block 

  • 함수를 제외하고는 기본적으로 중괄호가 있는 모든 곳을 가리킴
  • 함수 자리에 함수 대신 블록이 들어가는 것 (loops, if condition)
  • 변수가 블록의 안에서 선언되면 해당 변수들은 그 블록의 중괄호 또는 중괄호 두 개 사이의 범위에서만 존재
let radius = 8
if (radius > 0){
  const PI = 3.14
  let circ = 2 * PI * radius
}

console.log(radius) // 8 (외부에서 선언된 변수이고 내부에서 외부 변수를 사용했다고 해도 영향X)
console.log(PI) // NOT DEFINED (내부에서 선언된 변수이기 때문)
console.log(circ) // NOT DEFINED (내부에서 선언된 변수이기 때문)
  • 예전에 많이 사용했던 var 를 사용했다면 가리키는 범위가 다르기 때문에 값이 위와 다름. 따라서 사용 자제할 것

 

► Lexical scope

  • 부모 함수의 안에 중첩된 내부 함수는 해당 외부 함수의 범위 또는 범위 내에서 정의된 변수에 액세스할 수 있음
  • 중첩된 함수나 내부 함수는 상위 몇 레벨 위에 있든 상관 없이 부모 함수나 조부모 함수 등이 액세스 하는 동일한 항목에 액세스 가능
function bankRobbery(){ // 부모함수
  const heros = ['스파이더맨', '울버린', '블랙팬서', '아이언맨']
  function cryForHelp() { // 내부함수 : 해당 부모함수 범위내에서 접근 가능
    for (let hero of heros) {
        console.log(`please help us, ${hero}`)
    }
  }
  cryForHelp()
}
console.log(bankRobbery())

>> please help us, 스파이더맨
>> please help us, 울버린
>> please help us, 블랙팬서
>> please help us, 아이언맨

// cryForHelp를 호출했고 이 cryForHelp 함수 안에서 heros를 참조하고 있음
// heros는 이 함수 안에 존재하는 게 아니라 부모 함수 안에 있다

2.  Function Expressions

// 기본 함수 
// add라는 이름의 함수를 만든 것
function add(x, y) {
  return x + y
}

console.log(add(3, 4)) // 7
// 함수 표현식
// square는 함수의 이름이 아니라 변수 이름일 뿐
// 함수는 이름이 없음, 함수는 내부적으로 객체임
// 이름 없는 함수를 변수에 저장한 것
const square = function (num) {
  return num * num 
}
console.log(square(7)) // 49

3.  Higher order functions 

  • 고차 함수 : 다른 함수와 함께 작동하거나 다른 함수에서 작동하는 함수를 고급스럽게 표현한 것
  • 다른 함수를 인자로 받아서 그 인수로 작업을 하거나 함수를 반환하는 함수
function callTwice(func){
    func()
    func()
}
callTwice(1)
>> Uncaught TypeError: func is not a function
function rollDie() {
  const roll = Math.floor(Math.random() * 6) + 1
  console.log(roll)
}

rollDie()
>> 1
  • 위 두개의 함수를 합친 경우 ↓
function callTwice(func){
    func()
    func()
}
function rollDie() {
  const roll = Math.floor(Math.random() * 6) + 1
  console.log(roll)
}
callTwice(rollDie)

// rollDie 함수와 callTwice 함수가 함께 실행
>> 6
>> 4
  • 또 다른 예시 : 반복문을 돌린 함수와 랜덤 수를 생성하는 함수의 결합
function callTenTimes(f) {
  for (let i = 0; i < 10; i++) {
    f()
  }
}
function rollDie() {
  const roll = Math.floor(Math.random() * 6) + 1
  console.log(roll)
}

callTenTimes(rollDie)
// 6 3 6 2 4 1 4 2 1 2

 

► return function

// 팩토리 함수 : 함수를 반환, 함수에 이름 없음, 단지 값으로 반환된 것 
function makeBetweenFunc(min, max) {
    return function (num) {
        return num >= min && num <= max
    }
}

// js파일에서 함수를 만들어두고
// console창에 다음과 같이 변수 선언
const isChild = makeBetweenFunc(1, 18)
const isAdult = makeBetweenFunc(19, 64)
const isSenior = makeBetweenFunc(65, 100)
isChild(7)
>> true
isChild(19)
>> false
isAdult(45)
>> true
isSenior(101)
>> false

4.  Methods

  • 메서드를 만들려면 함수와 객체가 어떻게 만날까 
  • 모든 메서드는 함수이지만 모든 함수가 메서드인 건 아님
  • 메서드는 객체에 속성으로 추가된 함수
const myMath = {
    PI: 3.14159,
    square: function (num){
        return num * num
    },
    cube: function (num) {
        return num ** 3
    }
}

myMath.square(4)
>> 16
myMath.cube(3)
>> 27
// 속기법
// 위의 코드와 같음
const myMath = {
    PI: 3.14159,
    square(num){
        return num * num
    },
    cube(num) {
        return num ** 3
    }
}

myMath.cube(4)
>> 64
myMath.square(3)
>> 9

5.  'this' in methods

  • 'this' keyword : 메서드에 있는 객체를 가리킬 때 사용
  • this의 값은 사용된 함수의 호출 컨텍스트에 따라 값이 달라짐(호출하는 방식에 따라 값이 달라짐)
const cat = {
    name: 'Blue steele',
    color: 'grey',
    breed: 'scottish fold',
    meow() {
    	console.log('THIS IS: ', this)
      console.log(`${this.name} says MEOWWW`)
    }
}

// 실행은 하지않고 위 cat의 meow 메서드를 가리킴
const meow2 = cat.meow


cat.meow() // 괄호가 고양이라는 객체를 가리킴
>> Blue steele says MEOWWW
>> THIS IS:  {name: 'Blue steele', color: 'grey', breed: 'scottish fold', meow: ƒ}

// meow2() 실행 시 아무것도 가리키는게 없는 것 같지만 앞에 window 객체가 생략된 것임
meow2() // 실행 시 cat.meow와 같은 함수이지만 다른 방식으로 다르게 호출
>> says MEOWWW 
// meow2의 this 키워드는 고양이라는 객체를 가리키는게 아니라 window 객체를 가리킴
// window 객체 : 최상위 객체
>> THIS IS:  Window {window: Window, self: Window, document: document, name: '', location: Location, …}
// layAnEgg를 한 번 호출할때 마다 1씩 증가하고 증가된 수만큼 'EGG' 반환함

const hen = {
    name: 'Helen',
    eggCount: 0,
    layAnEgg() {
        this.eggCount += 1;
        return 'EGG'
    }
}

hen.name
>> 'Helen'
hen.eggCount
>> 4
hen.layAnEgg()
>> 'EGG'
hen.layAnEgg()
>> 'EGG'
hen.eggCount
>> 6

6.  Try/ Catch

  • 예외 처리 : 오류가 발생하여 코드가 중단되지 않도록 예외처리를 해주면 코드 중단 없이 작동함
hello.toUpperCase()
>> Uncaught ReferenceError: hello is not defined
try {
    hello.toUpperCase()
} catch {
  console.log('ERROR!!!')
}

console.log('AFTER!')

>> ERROR!!!
>> AFTER!
function yell(msg) {
  try {
    console.log(msg.toUpperCase().repeat(3))
  } catch (e) {
      console.log(e)
      console.log("Please pass a string next time!")
  }
}

// 문자열일 경우 정상 출력
yell('hello')
>> HELLOHELLOHELLO

// 문자열이 아닌 경우 다음과 같이 출력 (boolean, 숫자, 특수문자 ...)
yell(123)
// 오류 메시지로 예외 처리
>> TypeError: msg.toUpperCase is not a function
// 다음 메시지로 예외 처리
>> Please pass a string next time!

 

'JS' 카테고리의 다른 글

[JS][Udemy] Params, Spread, Rest, Destructuring  (0) 2023.03.23
[JS][Udemy] Array Callback Methods  (0) 2023.03.22
[JS][Udemy] JavaScript Functions 1  (0) 2023.03.20
[JS][Udemy] todolist project  (0) 2023.03.20
[JS][multicampus] Controlling event  (0) 2023.03.16