[EST] 240712 JavaScript-06
this
- 객체를 가리키는 참조 변수
- 호출되는 위치에 따라 다른 값을 출력함
this = window
function a() {
console.log(this)
}
a(); // window
- this = myObj
let myObj = {
val1: 100,
func1: function() {
console.log(this); // [val: 100, func1: f]
}
}
myObj.func1();
전역 컨텍스트
- 전역 컨텍스트에서 this는 전역객체, 브라우저에서는 window를 가리킴
console.log(this); // window -> 브라우저에서는 window 객체
함수 호출
- 일반 함수 내부에서는 this를 전역 객체를 가리킴
function foo() {
console.log(this); // window -> 브라우저에서는 window 객체
}
foo();
메서드 호출
- 객체의 메서드 내에서는 this는 그 메서드를 호출한 객체를 가리킴
const person = {
name: 'Alice',
greet: function() {
console.log(`Hello, I'm ${this.name}`); // Hello, I'm Alice
}
}
person.greet();
이벤트 핸들러
- 이벤트 핸들러 내에서 this는 이벤트가 발생한 DOM 요소를 가리킴
<button id="btn">Click me!</button>
<script>
const button = document.getElementById('btn');
button.addEventListener('click', function() {
console.log(this); // <button id="btn">Click me!</button>
});
</script>
this를 사용자 의도대로 값 조작하기
- 함수의 apply(), call(), bind() 메소드를 사용하면 this를 조작하거나 고정 가능
- 사용자가 원하는 의도대로 binding을 통한 컨트롤을 할 수 있음
call( )
- call() 메소드의 인수에 this로 사용할 값을 전달 가능
- call() 메소드를 사용하여 함수 호출 시 'this'값을 변경 가능
var peter = {
name: 'Peter Parker',
sayNameL function() {
console.log(this.name);
}
}
var bruce = {
name: 'Bruce Wayne',
}
peter.sayName.call(bruce); // Bruce Wayne
apply( )
- apply() 메서드의 인수에 this로 사용할 값을 전달 가능
- 배열의 형태로 전달 가능
var peter = {
name: 'Peter Parker',
sayName: function (is, is2) {
console.log(this.name + 'is' + is + 'or' + is2);
}
}
var bruce = {
name: 'Bruce Wayne',
}
peter.sayName.apply(bruce, ['batman', 'richman']); // Bruce Wayne is batman or richman
bind( )
- this가 고정된 새로운 함수를 반환
function sayName() {
console.log(this.name);
}
var bruce = {
name: 'bruce',
sayName: sayName
}
var peter = {
name: 'peter',
sayName: sayName.bind(bruce)
}
peter.sayName(); // bruce
bruce.sayName(); // bruce
요약
- this는 어디에나 존재
- 전역 this는 window
- 호출된 함수는 호출된 곳을 this로 바인딩
- 실행되는 함수의 this를 임의로 bind 가능
- 화살표함수는 선언된 곳의 this를 바인딩
함수 심화
구조분해할당을 이용한 아규먼트 처리
- 구조분해 할당을 통해 함수에 전달하는 인자의 기본값을 지정가능
function printMe({name, age, email} = {}) {
console.log(`이름: ${name}, 나이: ${age}, 이메일: ${email}`)
}
const me = {
name: '뽀로로',
age: '15',
email: 'pororo@something.com'
};
printMe(me); // 이름: 뽀로로, 나이: 15, 이메일: pororo@something.com
rest 문법
- 함수의 매개변수에 ...를 붙이면 사용자가 제공한 모든 매개변수를 배열 안에 넣도록 지정
- rest문법 사용 시 주의사항
◽ 매개변수에는 하나의 rest만 존재가능
◽ rest는 반드시 함수 정의의 마지막 매개변수여야 함
function 함수2(a, b, ...c) {
console.log(c);
return Math.max(...c);
}
함수2('hello', 'world', 10, 20, 30, 40);
function 함수2([a, b], ...c) {
console.log(a);
console.log(b);
console.log(c);
}
함수2([1, 2], 10, 20, 30, 40);
/*
h
e
['world', 10, 20, 30, 40]
1
2
[10, 20, 30, 40]
*/
매개변수의 초기화
- 함수 선언과 동시에 값을 할당하여 초기화 가능
- 매개변수의 초기화는 기본적으로 왼쪽에서 오른쪽 순서로 설정
function 함수3 (a=10, b=20, c=30) {
return a + b + c;
}
console.log(함수3()); // 60 -> (a=10) + (a=20) + (c=30) = 60
console.log(함수3(100)); // 150 -> (a=100) + (b=20) + (c=30) = 150
console.log(함수3(100, 200)); //330 -> (a=100) + (b=200) + (c=30) = 330
console.log(함수3(100, 200, 300)); // 600 -> (a=100) + (b=200) + (c=300) = 600
console.log(함수3(c=1000)); // 1050 -> 실제로는 a=1000로 지정 (a=1000) + (b=20) + (c=30) = 1050
console.log(함수3(c=1000, a=2000));
// 3030 -> 실제로는 a=1000, b=2000으로 지정 (a=1000) + (b=2000) + (c=30) = 3030
자바스크립트 Scope
- 스코프: 변수의 접근성과 생존기간을 제어하는 '생존범위'를 의미
- 스코프는 이름이 충돌하는 문제를 덜어주고, 자동으로 메모리를 관리함
const func1 = function() {
var a = 1;
var b = 2;
console.log(a + b); // 3
};
var a = 20;
func1();
-> var 키워드를 이용해서 전역변수를 선언
-> 변수a는 어디서든 접근가능한 전역 변수임에도 불구하고 함수안의 a와 함수 밖의 a는 완전히 별개의 변수
-> 함수 안의 a변수는 함수가 종료되면 함수 스코프가 가비지 컬랙션으로 수거되기 때문에, 메모리상에서 자동으로 제거
스코프의 종류
- 전역 스코프
◽ 스크립트의 어디서든 접근이 가능하기 때문에 사용이 용이
◽ 타인과의 협업, 라이브러리 사용 시 충돌의 가능성이 있음
- 함수 스코프
◽ 함수 내부에서 정의된 변수와 매개변수는 함수 외부에서 접근할 수 없음
◽ 함수 내부에서 정의된 변수라면 함수의 어느 부분에서도 접근 가능
- 블록 스코프
◽ 중괄호 안에서만 접근 가능
◽ 블록 내부에 정의된 변수는 블록의 실행이 끝나면 해제
let z = 100;
function sum(x){ // x는 매개변수(parameter)이면서 지역변수(local val)
let y = 50; // y는 지역변수
z = z + y;
return x + y;
}
console.log(sum(10)); // 60 -> 10은 전달인자(argument)
console.log(x); // 오류 -> x is not defined
console.log(y); // 오류 -> y is not defined
console.log(z); // 150 -> 100+50
let a = 10;
function outer() {
let b = 20;
function inner() {
let c = 30;
console.log(a, b, c); // 10 20 30
}
inner();
console.log(a, b); // 10 20
}
outer();
console.log(a); // 10