var name = 'Hong';
console.log(name); //Hong
var name = 'GunWoo';
console.log(name); //GunWoo
function func() {
if (true) {
var a = 5;
console.log(a); //5
}
console.log(a); //5
}
func()
console.log(a); //Uncaught ReferenceError: a is not defined
function func() {
if (true) {
let a = 5;
console.log(a); // 5
}
console.log(a); //Uncaught ReferenceError: a is not defined
}
func();
console.log(a); //Uncaught ReferenceError: a is not defined
{
var a = 3;
console.log(a); //3
}
console.log(a); //3
{
let a = 3;
console.log(a); //3
}
console.log(a); //Uncaught ReferenceError: a is not defined
scope란 밖에서는 안이 보이지 않고 안에서만 밖을 볼 수 있는 것을 말한다.
false로 판정되는 값들: false, undefined, null, 0, NaN, ‘’(빈 문자열)
let a = 126
let b = a
a = a + 1
b = a + 1
// 위의 경우 126을 참조하는 변수가 없기 때문에 GC가 126이 할당된 메모리를 정리한다.
let variable = 126 // 주소: 111
let variable2 = variable //variable2는 variable의 주소를 가리키고 있는 상태(주소: 111)
variable = variable + 1 // 주소:111의 값이 변경되지 않고 variable은 주소: 112를 가리킴(값은 127)
let a = 10; // call stack
let b = 20; // call stack
const arr = []; // Heap (call stack에서 생성된 배열 변수 arr이 Heap의 배열 영역을 메모리 주소를 참조)
arr.push(5); // Heap 메모리를 변경하는 것이기 때문에 상수여도 push가 동작함
arr.push(3);
arr.push(1);
const arr1 = new Array();
const arr2 = [];
const arr3 = [1, 2, 3, 4, 5];
const arr4 = new Array(5);
const arr5 = new Array(5).fill(5); // [5, 5, 5, 5, 5]
const arr6 = Array.from(Array(5), function(v, idx) {
return idx + 1;
}) // [1, 2, 3, 4, 5]
const arr = [1, 2, 3];
// push 배열 끝에 새로운 요소 추가
arr.push(4); // [1, 2, 3, 4]
// pop 배열 끝의 요소 삭제
arr.pop(); // [1, 2, 3]
// shift 배열 맨 앞의 요소 삭제
arr.shift(); // [2, 3]
// unshift 배열 맨 앞에 요소 추가
arr.unshift(1); // [1, 2, 3]
const joinArr = [1, 2, 3, 4, 5, 6];
// join
console.log(joinArr.join(", ")); // 1, 2, 3, 4, 5, 6
// reverse
console.log(joinArr.reverse()); // [ 6, 5, 4, 3, 2, 1 ]
console.log(joinArr); // [ 6, 5, 4, 3, 2, 1 ] => 원본 배열에도 영향을 준다.
// concat
const a = [1, 2, 3];
const b = [4, 5, 6];
console.log(a.concat(b)); // [ 1, 2, 3, 4, 5, 6 ]
// slice
const arr = [1, 2, 3, 4, 5, 6];
// 첫 번째 인자: 시작점, 두 번째 인자: 끝나는 점
console.log(arr.slice(2, 4)); // [ 3, 4 ]
console.log(arr); // [ 1, 2, 3, 4, 5, 6 ] => 원본 배열이 변하지 않음
// splice: 중간의 요소 삭제
arr.splice(2, 2); // 첫 번째 인자: 시작점, 두 번째 인자: 삭제할 개수
console.log(arr); // [ 1, 2, 5, 6 ]
for (let i = 0; i < 5; i += 1) {
console.log(arr[i]);
}
// 추천하는 방식
for (const item of arr) {
console.log(item);
}
const arr = [1, 2, 3, 4, 5];
console.log(typeof arr); //object 출력 => 배열은 객체 타입이다.
arr['key'] = 'value';
console.log(arr); // [ 1, 2, 3, 4, 5, key: 'value' ]
console.log(arr.length); // 5 => key가 추가되었지만 배열의 길이는 변하지 않는다.
여러 값을 키-값 형태로 결합시킨 복합 타입
const obj1 = new Object();
const obj2 = {};
const obj3 = {name: 'Gun', company: 'dev'};
const obj = {};
obj["email"] = "foxrain.gg@gmail.com"; // 요소 추가 방법1
obj.phone = '01012345678'; // 요소 추가 방법2
console.log(obj); // { email: 'foxrain.gg@gmail.com', phone: '01012345678' }
delete obj.phone;
console.log(obj); // { email: 'foxrain.gg@gmail.com' }
// 객체 요소 유무 확인 방법
console.log('email' in obj); // true
console.log('phone' in obj); // false
const obj = {
email: "foxrain.gg@gmail.com",
phone: "01012345678",
};
// 키의 집합
console.log(Object.keys(obj)); // [ 'email', 'phone' ]
// 값의 집합
console.log(Object.values(obj)); // [ 'foxrain.gg@gmail.com', '01012345678' ]
const obj = {
email: "foxrain.gg@gmail.com",
phone: "01012345678",
};
// for in은 객체의 키 값을 순회함
for (const key in obj) {
console.log(key, obj[key]);
// 1번째 실행: email foxrain.gg@gmail.com
// 2번째 실행: phone 01012345678
}
변수가 어느 범위까지 참조되는 지를 뜻함
const a = 5; // Global Scope
{
const b = 3; // Local Scope
console.log(a, b); // 5 3
}
console.log(a, b); // Error
함수가 선언된 환경의 스코프를 기억하여 함수가 스코프 밖에서 실행될 때에도 기억한 스코프에 접근할 수 있게 만드는 문법
function makeGreeting(name) {
const greeting = "Hello, ";
return function() {
console.log(greeting + name);
};
}
const world = makeGreeting("World!");
const gunwoo = makeGreeting("GunWoo");
world();
gunwoo();
클로저를 사용하여 내부 변수와 함수를 숨길 수 있다.
function Counter() {
let privateCounter = 0;
function changeBy(val) {
privateCounter += val;
}
return {
increment: function() {
changeBy(1);
},
decrement: function() {
changeBy(-1);
},
getValue: function() {
return privateCounter;
},
}
}
const counter = Counter();
const counter2 = Counter();
console.log(counter.getValue()); // 0
counter.increment();
counter.increment();
console.log(counter.getValue()); // 2
counter.decrement();
console.log(counter.getValue()); // 1
console.log(counter2.getValue()); // 0 => 별개의 클로저
function counting() {
let i = 0;
for (i = 0; i < 5; i += 1) {
setTimeout(function () {
console.log(i);
}, i * 100);
}
}
counting(); // 5가 다섯번 출력됨
// setTimeout의 대기시간이 끝나 callback fuction이 실행되는 시점에는 루프가 종료되어
// i가 5인 상태이기 때문이다.
IIFE(Immediately Invoked Function Expression, 즉시 실행 함수)를 사용한다.
function counting() {
let i = 0;
for (i = 0; i < 5; i += 1) {
(function (number) {
setTimeout(function () {
console.log(number);
}, number * 100);
})(i);
}
}
counting(); //0 1 2 3 4 출력
let을 사용한다. ⇒ let은 블록 수준 스코프이기 때문에 매 루프마다 클로저가 생성된다.
function counting() {
for (let i = 0; i < 5; i += 1) {
setTimeout(function () {
console.log(i);
}, i * 100);
}
}
counting(); //0 1 2 3 4 출력
앞으로도 좋은 글 부탁드립니다!