WEB/JavaScript
[ES6] [Part1] arrowFunction, this, variable, hoisting, template/tagged literals, spread Operator, apply, call
Harimad
2022. 1. 20. 10:54
🔖TAG 💡apply, 💡Arrow, 💡call, 💡hoisting, 💡setTimeout, 💡SPREAD, 💡tagged, 💡Var, 💡비동기, 💡전역변수 📗

Arrowfunction 은 function을 대체하는 신문법이 아님
var 오브젝트1 = { 함수 : function(){ console.log(this) } }
오브젝트1.함수() // 오브젝트1 출력
var 오브젝트2 = { 함수 : () => { console.log(this) } }
오브젝트2.함수() //window 출력
- this값은 함수를 만나면 항상 변하는데 arrowfunction 안에서는 변하지 않고 밖에 있던 this를 그대로 쓴다
this & arrow function 연습문제 해설
<!-- 3. setTimeout 이용해보기 -->
<button id="버튼">버튼</button>
<script>
document.getElementById('버튼').addEventListener('click', () => {
console.log(this); //window 출력
});
document.getElementById('버튼').addEventListener('click', function() {
console.log(this); // 버튼 출력 !!
});
//옛날 방식
document.getElementById('버튼').addEventListener('click', function () {
var 버튼 = this;
setTimeout(function() {console.log(버튼.innerHTML)}, 1000); //버튼 출력
});
//이거 쓰세요
document.getElementById('버튼').addEventListener('click', function () {
setTimeout(() => {console.log(this.innerHTML)}, 1000); // 버튼 출력
});
document.getElementById('버튼').addEventListener('click', () => {
setTimeout(function() {console.log(this.innerHTML)}, 1000); //undefined
});
document.getElementById('버튼').addEventListener('click', () => {
setTimeout(() => {console.log(this.innerHTML)}, 1000); //undefined
});
// 콜백함수(함수안에 파라미터 역할로 들어가는 함수)는
//그냥 일반함수랑 똑같기 때문에 window가출력
});
</script>
변수 신문법 총정리 2. Hoisting, 전역변수, 참조
//자바스크립트 변수, 함수의 Hoisting 현상
function 함수() {
console.log('hello');
var 이름 = 'kim';
}
//위 코드의 실행 순서는 아래와 같다
//변수의 선언 부분을 강제로 변수의 범위 맨 위로 끌고가서 해석-
function 함수() {
var 이름;
console.log('hello');
이름 = 'kim';
}
//전역변수 저장방법 2가지
var 전역1 = '전역1';
window.전역2 = '전역2';
let 전역3 = '전역3'
console.log(전역1, 전역2); // 전역1, 전역2
console.log(window.전역1); // 전역2
console.log(window.전역3); //undefined
// window 객체는 자바스크립트 기본 함수를 보관하는 객체임
// 쌩으로 전역변수 선언하면 window에도 보관됨
//그래서 전역변수를 더 엄격하게 구분지으려면 window를 쓴다
window.이름 = 'Tom';
console.log(window.이름, 이름); //Tom Tom
변수 연습문제 6개
<script>
//다음 코드 콘솔창 출력결과는?
//Q1.
함수1();
function 함수1() {
console.log(안녕); //Uncaught ReferenceError: Cannot access '안녕' before initialization
let 안녕 = 'Hello!';
}
//함수 실행을 함수선언 전에 해도 되나? ㅇㅇ 호이스팅됨
// let 안녕도 function 함수1 안에서 호이스팅 되지만 let, const는 이런식으로 쓰면 안됨
//Q2.
함수2();
var 함수2 = function () {
console.log(안녕); //Uncaught TypeError: 함수2 is not a function
var 안녕 = 'Hello!';
}
//함수실행을 함수선언 전에 해도 되나? ㅇㅇ
//그러나 함수 표현식은 함수 내용이 전부 호이스팅 되는게 아니다.
//함수 표현식 해당 줄이 읽혀야 함수가 선언 완료됨.
//함수 선언전에 실행해버리면 함수가 아니라고 에러가 난다.
// //Q3.
let a = 1;
var 함수3 = function () {
a = 2;
}
console.log(a); //1
//Q4.
let a = 1;
var b = 2;
console.log(a, b); //1, 2
window.a = 3; //error아님 let으로 선언하면 window.a = 3 이 적용안됨
window.b = 4; //ok
console.log(a, b); //1, 4
console.log(a + b); //1+4 = 5
//Q5.
//정상작동
setTimeout(function () { console.log(1); }, 1000);
setTimeout(function () { console.log(2); }, 2000);
setTimeout(function () { console.log(3); }, 3000);
setTimeout(function () { console.log(4); }, 4000);
setTimeout(function () { console.log(5); }, 5000);
//6만 계속 출력. 원인은?
for (var i = 1; i < 6; i++) {
setTimeout(function () { console.log(i); }, i * 1000);
}
//var -> let으로 변경하면 제대로 출력됨
//6이 나오는 이유: setTimeout은 비동기 함수이므로 for반복문이 i = 1에서 6까지 진행되고나서 실행됨
//그래서 setTimeout에 인자 i가 6만 들어간다.
for (let i = 1; i < 6; i++) {
//let i = 0 -> 1 -> 2 ... 5 생성되어 아래 인자로 들어감
setTimeout(function () { console.log(i) });
}
</script>
<!-- 6번 문제 -->
<div style="display : none">모달창0</div>
<div style="display : none">모달창1</div>
<div style="display : none">모달창2</div>
<button>버튼1</button>
<button>버튼2</button>
<button>버튼3</button>
<script>
//Q6. 각 버튼 누르면 오류 나는 이유와 해결책은?
const $버튼들 = document.querySelectorAll('div');
const $모달창들 = document.querySelectorAll('button');
for (var i = 0; i < 3; i++) {
$버튼들[i].addEventListener('click', function () {
$모달창들[i].style.display = 'block'
});
}
//코드 실행순서
//1. 반복문 내 코드 3번 돌아감
//2. 이벤트리스너의 콜백함수는 나중에(클릭시에) 실행됨
//3. 클릭 -> 콜백함수속 i인자를 채우려 보니까 i = 3인 값이 들어감
//해결책: var i 를 let i로 진행
</script>
자바스크립트가 문자 다루는 신기한 방법 (Template literals / tagged literals)
<script>
//Tagged Literals
//함수로 문자 해체분석기능 만들 수 있다
//문자 중간중간의 단어 순서 바꾸거나 변수 제거 할때 유용
var 변수 = 'Son';
function 해체분석기1() {
return 10;
}
console.log(해체분석기1`안녕하세요 ${변수} 입니다`); // 10
//--------------------------------------------------------------------------------//
function 해체분석기2(문자들, 변수들) {
console.log(문자들, 변수들);
}
해체분석기2`안녕하세요 ${변수} 입니다`; // ['안녕하세요 ', ' 입니다'] 'Son'
// 첫째 파라미터: 백틱 기호안의 먼저 나오는 순수 문자만 골라내서 Array로 만든다.
// 둘쨰 파라미터: ${}내의 변수를 담는다. 변수 추가 가능
//--------------------------------------------------------------------------------//
var 변수1 = 'Tim', 변수2 = 'Lee';
function 해체분석기3(문자들, 변수1, 변수2) {
console.log(문자들);
console.log(변수1);
console.log(변수2);
}
해체분석기3`안녕하세요 나는 ${변수1} 과 ${변수2} 입니다`; //['안녕하세요 나는 ', ' 과 ', ' 입니다'] Tim Lee
//--------------------------------------------------------------------------------//
var pants = 20;
var socks = 100;
function 해체분석기4(문자들, 변수1, 변수2) {
if (변수1 === 0) {
console.log(`바지안팔아요 ${문자들[1]} ${변수2}`);
} else {
console.log(문자들[0], 문자들[1]);
console.log(`${문자들[1]}: ${변수1}, ${문자들[0]}: ${변수2}`);
}
}
해체분석기4`바지 ${pants} 양말${socks}` // 양말: 20, 바지 : 100
pants = 0;
해체분석기4`바지 ${pants} 양말${socks}` // 바지안팔아요 양말 100
</script>
모든 괄호를 없애주는 Spread Operator 활용방법 1
Spread Operator 활용방법 2 & apply, call 함수 알아보기
<script>
//Spread Operator 활용방법
//1. spread operator: 괄호제거 해주는 연산자
var 어레이 = ['hello', 'world'];
console.log(어레이); //Array
console.log(...어레이); //console.log('hello', 'world')와 똑같다 !
//2. 문자를 해체할 수도 있다
var 문자 = 'hello';
console.log(...문자); //h e l l o
console.log('h', 'e', 'l', 'l', 'o'); //이것과 동일
//3. 배열 새로 만들기 쉬움
var a = [1, 2, 3];
var b = [4, 5];
var c = [...a, ...b];
console.log(c); // [ 1, 2, 3, 4, 5 ]
//4. 깊은 복사 가능
var a = [1, 2, 3];
var b = a; //얕은 복사(값 공유) - 같은 값을 가리키기 때문
console.log(a, b); // [1, 2, 3] [1, 2, 3]
b[0] = 100;
console.log(a, b); // [100, 2, 3] [100, 2, 3]
var a = [1, 2, 3];
var b = [...a]; //깊은 복사(독립된 객체)
console.log(a, b); //[1, 2, 3] [1, 2, 3]
b[0] = 100;
console.log(a, b); //[1, 2, 3] [100, 2, 3];
// Spread Operator 사용처?
// 함수소괄호 인자, 오브젝트 중괄호내, 어레이 대괄호내에서 사용
// 다른 곳에 쓰면 에러남
//--------------------------------------------------------------//
//Spread Operator 활용방법 2
function 더하기(a, b, c) {
console.log(a + b + c);
}
var 어레이 = [10, 20, 30];
//노가다
더하기(어레이[0], 어레이[1], 어레이[2]); //60
//옛날방식
더하기.apply(undefined, 어레이); //60 //undefiend에다가 어레이를 넣어서 함수 실행해 주세요의 뜻
//요즘방식
더하기(...어레이); //60
//--------------------------------------------------------------//
//apply 설명
var person = {
name: 'Kim',
인사: function () {
console.log(this.name);
}
}
//person의 인사 함수를 person2에 붙이고싶다?
var person2 = {
name: 'Lee',
}
person.인사(); //Kim
person.인사.apply(person2); //Lee
person2.인사(); //Uncaught TypeError: person2.인사 is not a function
//call 설명 (apply, call 비슷함)
person.인사.apply(person2, 1); //person.인사(1) 과 같이 파라미터1을 넣는것과 같음
person.인사.call(person2, 1);
//apply는 파라미터를 array로 넣기 가능 (call과 apply의 유일한 차이점!)
person.인사.apply(person2, [1, 2]);
person.인사.call(person2, 1, 2);
</script>