한 걸음씩
[JS][Udemy] JavaScript Functions 2 본문
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 |