grade.getGrade(90,90,90)
// 출력: 수입니다
<script>
function Grade(kor, eng, math) {
this.kor = kor;
this.eng = eng;
this.math = math;
this.getGrade = function() {
let avg = (this.kor + this.eng + this.math) / 3;
let result = '';
if (avg >= 90) {
result = '수';
} else if (avg >= 80) {
result = '우';
} else if (avg >= 70) {
result = '미';
} else if (avg >= 60) {
result = '양';
} else {
result = '가';
}
return '성적은 ' + result + '입니다.<br>';
};
}
let grade = new Grade(90, 89, 90)
document.write(grade.getGrade()); // 출력: 성적은 수입니다.
</script>
출력)
당신: 가위
컴포터: 보
당신이 이겼습니다.
<script>
let RSP = {
run : function () {
let rsp_array = ['가위', '바위', '보'];
let user = prompt('가위, 바위, 보 중 하나를 입력하세요.');
if (!rsp_array.includes(user)) {
alert('올바른 입력이 아닙니다.');
return ;
}
let computer = rsp_array[Math.floor(Math.random() * rsp_array.length)];
let result = "";
if (user === computer) {
result = "비겼습니다.";
}
else if ((user === "가위" && computer === "보") ||
(user === "바위" && computer === "가위") ||
(user === "보" && computer === "바위")) {
result = "당신이 이겼습니다.";
}
else {
result = "컴퓨터가 이겼습니다.";
}
document.write(`당신 : ${user}<br>컴퓨터 : ${computer} <br>${result}`);
}
}
RSP.run();
</script>
<script>
let timeText = ""; // 출력할 내용을 저장할 변수
setInterval(function () {
let timer = new Date();
let h = timer.getHours();
let m = timer.getMinutes();
let s = timer.getSeconds();
//document.write(h + '시' + m + '분' + s + '초' + '<br>');
document.getElementById('clock').innerHTML =
h + '시' + m + '분' + s + '초';}, 1000);
</script>
클로저(Closure)는 자바스크립트에서 함수와 함수가 선언된 렉시컬 환경(Lexical Environment)의 조합을 의미한다.
쉽게 말해 "함수가 자신이 선언된 위치의 외부 변수를 기억하고 접근할 수 있는 기능"이다.
<script>
function outer() {
let count = 0; // 외부 변수 (지역 변수)
return function inner() { // 내부 함수 (클로저)
count++;
console.log(`현재 카운트: ${count}`);
};
}
const counter = outer(); // 외부 함수 실행 -> 내부 함수 반환
counter(); // 현재 카운트: 1
counter(); // 현재 카운트: 2
counter(); // 현재 카운트: 3
</script>
Q. 메모리 공간이 유지된다고 했는데 한번 호출되고 나서도 계속 유지되는거면 메모리 공간이 계속 낭비되는거 아닌가?
A. 클로저가 내부 변수의 메모리 공간을 유지하는 것은 맞지만 무조건 영구적으로 유지되는 것은 아니다.
자바스크립트의 가비지 컬렉터(GC, Garbage Collector)가 필요 없어진 클로저를 정리한다.
클로저는 내부 변수를 유지하지만 불필요하면 가비지 컬렉터(GC)가 해제한다.
하지만 변수를 계속 참조하고 있으면 메모리에서 해제되지 않아서 메모리 누수(memory leak)가 발생할 수도 있다.
더 이상 필요 없는 클로저는 null을 할당해서 해제하면 좋다.
<script>
function outer() {
let x = 10;
return function inner() {
console.log(x);
};
}
let closure = outer(); // 클로저 생성
closure(); // 10 출력
closure = null; // 참조 해제 → GC가 x의 메모리 회수 가능
</script>
closure = null;을 하면 inner()를 가리키던 변수가 없어지니까 x도 더 이상 필요 없어서 해제된다.
만약 클로저가 반환되지 않고 내부적으로만 사용된다면 함수가 종료된 후 GC가 자동으로 정리한다.
arguments 객체는 함수 내부에서 사용할 수 있는 유사 배열 객체(array-like object)로, 함수에 전달된 모든 인자(arguments)를 담고 있다.
배열과 비슷하지만 배열은 아니다.
: 배열처럼 인덱스로 접근할 수 있지만 배열의 메서드는 사용할 수 없다.
함수에 정의된 매개변수 외에도 모든 전달값을 포함한다.
: 함수에 전달된 인자의 개수가 매개변수보다 많더라도 모두 arguments에 저장된다.
함수 안에서만 사용 가능하다.
화살표 함수에서는 사용할 수 없다.
<script>
function example(a, b) {
console.log(arguments); // [Arguments] { '0': 1, '1': 2, '2': 3, '3': 4 }
console.log(arguments[0]); // 1
console.log(arguments[1]); // 2
console.log(arguments[2]); // 3
console.log(arguments.length); // 4
}
example(1, 2, 3, 4);
</script>
1) 호이스팅(Hoisting) 차이
함수 선언(function add() {})은 호이스팅 된다.
함수 선언은 코드가 실행되기 전에 메모리에 올라가서, 선언하기 전에 호출해도 문제없이 실행된다.
<script>
console.log(add(10, 20)); // 정상 실행
function add(num1, num2) {
return num1 + num2;
}
</script>
함수 표현식(let add2 = function() {})은 호이스팅은 되지만 변수에 할당되기 전에는 사용할 수 없다.
함수 표현식은 변수에 할당되므로 변수 자체는 hoisting되지만 할당되기 전에 호출하면 오류가 발생한다.
<script>
console.log(add2(10, 20)); // ❌ ReferenceError 발생!
let add2 = function(num1, num2) {
return num1 + num2;
};
</script>
2) this 바인딩 차이
함수 선언 (function add() {})은 일반 함수로 실행하면 this가 전역 객체 (window)를 가리킨다.
함수 표현식 (let add2 = function() {})은 일반 함수로 실행하면 위와 동일하게 this가 전역 객체를 가리킨다.
하지만 화살표 함수(=>)를 쓰면 this가 다르게 동작하므로 주의해야 한다.
<script>
let obj = {
num: 10,
func1: function() {
console.log(this.num); // 10
},
func2: () => {
console.log(this.num); // undefined (화살표 함수는 this를 바인딩하지 않음)
}
};
obj.func1(); // 10
obj.func2(); // undefined
</script>
3) 가독성과 사용 목적
함수 선언식 (function add() {})은 일반적인 함수 정의에 사용한다.
재사용할 함수라면 보통 선언식이 더 명확하다.
함수 표현식 (let add2 = function() {})은 콜백 함수나 한 번만 쓰일 함수에 적합하다.
<script>
setTimeout(function() {
console.log("1초 후 실행!");
}, 1000);
</script>
4) 화살표 함수와의 관계
함수 표현식은 화살표 함수(=>)로 변환할 수 있다.
<script>
let add2 = (num1, num2) => num1 + num2;
</script>
화살표 함수는 this를 바인딩하지 않으므로 객체 내부 메서드로 쓰기에는 주의해야 해.
3줄 요약:
1. 클로져란 외부변수가 살아 있다는 말이다.
2. 함수에는 명시적 함수, 익명 함수, 화살표 함수가 있다.
3. 객체는 중괄호 이며, 객체에 들어 가는 함수는 메서드라고 표현하며, 익명함수로만 구현하여야 한다.
오늘은 허리가 아파서 물리치료를 받고 왔다..
역시 오래 앉아있으니까 허리가 나갈 것 같군....
