script 태그 속성
기본 script 태그는 html 파싱을 중단하고 js파일을 다운로드하고 실행하여 웹페이지 로드가 지연될 수 있다.
하지만 async와 defer 속성은 비동기적으로 로드한다.
async : html 파싱과 병렬로 다운로드하고 js파일이 다운로드되면 파싱을 중단하고 다운로드된 js파일을 즉시 실행하여 실행 순서는 보장되지 않는다.
defer : html 파싱과 병렬로 다운로드하고 html 파싱이 완료된 후 순서대로 다운로드된 js파일을 실행한다.
defer는 html 파싱이 완료된 후에 순서대로 실행되는 반면에 async는 js파일이 다운로드되면 즉시 실행하기 때문에 순서에 대한 차이가 있다.
나머지 매개변수
function sum(...args){
console.log(args[0] + args[1]);
}
sum(10,20);
받아야할 인수가 많다면 위 처럼 ...args를 활용해 배열로 매개변수를 다룰 수 있다.
나머지 매개변수를 사용하려면 매개변수 마지막(function sum(test, ...args))에 입력하거나 단독으로 사용해야한다.
호이스팅
JavaScript 호이스팅은 인터프리터가 코드를 실행하기 전에 함수, 변수, 클래스 또는 임포트의 선언문을 해당 범위의 맨 위로 끌어올리는 것처럼 보이는 현상을 뜻한다.
먼저 선언, 초기화, 할당의 변수 생성 단계를 보면
// var
console.log(name) // undefined
var name = "Tom"
// let
console.log(name) // ReferenceError
let name = "Tom"
// const
console.log(name) // ReferenceError
const name = "Tom"
위 변수 예시를 보면 let, const는 참조에러가 발생하고 var에서는 에러가 발생하지않는다.
이유는 var는 선언과 동시에 초기화가 이루어진다. 그러므로 선언과 동시에 undefined가 할당된다.
let과 const는 선언만 되고 초기화가 되지않은 상태이다. 그래서 ReferenceError 참조 에러가 발생한다.
렉시컬 스코프
렉시컬 스코프는 함수가 정의된 위치에 따라 변수의 유효 범위 결정되는 스코프 규칙을 의미한다. 즉 렉시컬 스코프는 함수를 어디서 선언하였는지에 따라 상위 스코프를 결정한다는 뜻이다.
var num = 10;
function outer(x) {
function inner(x) {
console.log(x + 10);
}
inner(x);
}
outer(10); // 20
// inner는 outer 참조 outer는 전역 참조
< 반복문 연습문제 >
// 암스트롱 수 구하기 (100부터 ~ 999까지)
[ 암스트롱의 수는 세 자리의 정수 중에서 각 자리의 수를 세 제곱한 수의 합과 자신이 같은 수를 말합니다.
예를 들어 153 = 1 + 125 + 27 입니다. ]
> 나의 풀이
for (let i = 100; i <= 999; i++) {
let total = 0;
let str = i.toString().split('');
for (let j = 0; j < str.length; j++) {
let sum = Math.pow(Number(str[j]), 3);
total += sum;
}
if (i === total) {
console.log(`${i}는 암스트롱 수다`);
}
}
> 다른 풀이
for (let i = 1; i < 10; i++) {
for (let j = 0; j < 10; j++) {
for (let k = 0; k < 10; k++) {
const sum = i * i * i + j * j * j + k * k * k;
const origin = i * 100 + j * 10 + k;
if (sum === origin) {
console.log(origin);
}
}
}
}
정해진 기준 100부터 999까지 반복 순환을 하여 나온 수를 문자로 변경해 쪼깨는 방법으로 생각해서 문제를 해결했지만 일,십,백의 자리를 삼중 for문으로 순환하여 계산하는 방법은 생각하지 못했다.
// 1번
const sumHandler = (...args) => {
let sum = 0;
for (let num of args) {
sum += num;
}
return sum;
};
console.log(sumHandler(1, 2, 3));
// 2번
const calcHandler = (a, b, sym) => {
return sym === '+'
? a + b
: sym === '-'
? a - b
: sym === '*'
? a * b
: sym === '/'
? a / b
: '연산 기호를 확인해주세요.';
};
console.log(calcHandler(4, 5, '*'));
console.log(calcHandler(4, 5));
// 3번
const baseScore = {
'A+': 4.5,
A: 4,
'B+': 3.5,
B: 3,
'C+': 2.5,
C: 2,
F: 1,
};
const studentA = {
math: 'A+',
korean: 'B',
english: 'C+',
science: 'F',
};
const studentAvgHandler = (studentA) => {
let sum = 0;
let count = 0;
for (let key in studentA) {
sum += baseScore[studentA[key]];
count++;
}
return sum / count;
};
console.log(studentAvgHandler(studentA));
// 문제+(과제)
const i = 'aaabbbccc';
const o = 'a3b3c3';
const i2 = 'aabbaa';
const o2 = 'a2b2a2';
const i3 = 'abbbffd';
const o3 = 'a1b3f2d1';
const countHandler = (item) => {
let count = 1;
let result = '';
for (let i = 0; i < item.length; i++) {
if (item[i] === item[i + 1]) {
count++;
} else {
result += item[i] + count;
count = 1;
}
}
return result;
};
console.log(countHandler(i));
console.log(countHandler(i2));
console.log(countHandler(i3));
JavaScript에 기본 원리 및 개념에 대해 다시 짚어보고 채우면서 이 바탕으로 정리를 통해 확실하게 다져본다.