let a = 1
function f () {
console.log(a, b, c)
let b = 2
console.log(a, b, c)
if (true) {
let c = 3
console.log(a, b, c)
}
console.log(a, b, c)
}
f()
for (let i = 0; i < 5; i++) {
console.log(i)
}
console.log(i)
let a = 1
a = 2
console.log(a)
var funcs = []
for (var i = 0; i < 10; i++) {
funcs.push(function () {
console.log(i)
})
}
funcs.forEach(function (f) {
f()
})
var funcs = []
for (var i = 0; i < 10; i++) {
funcs.push((function (v) {
return function () {
console.log(v)
}
})(i))
}
funcs.forEach(function (f) {
f()
})
let funcs = []
for (let i = 0; i < 10; i++) {
funcs.push(function () {
console.log(i)
})
}
funcs.forEach(function (f) {
f()
})
-
for문에서 i 값이 변경되는 매 루프마다 각각 새로운 블록스코프가 형성됨
-
즉 아래와 같은 내용이 반복되는 형태로 생각하면 됨.
for (let i = 0; i < 10; i++) {
funcs.push(function() {
console.log(i)
})
}
// ==================
{
let i = 0;
funcs.push(function(){ console.log(i); });
}
{
let i = 1;
funcs.push(function(){ console.log(i); });
}
{
let i = 2;
funcs.push(function(){ console.log(i); });
}
- i 값이 for문 종료 이후에도 for문의 scope의 영향을 받는 경우와 같은 개념은 실행컨텍스트와 클로저에 대한 내용
- 메모리 측면에서 효율적이라는 내용은 아래의 코드(ES5 하에서의 코드)와 비교하면 그렇다는 것입니다.
for (var i = 0; i < 10; i++) {
(function (i) {
funcs.push(function(){ console.log(i); });
})(i);
}
- 이 경우 i를 전달하기 위해 매번 즉시실행함수를 한 번 더 감싸기 때문에 상대적으로 성능이 저하될 수밖에 없음
- 불가, 재할당시 오류가 발생
const PI = 3.141593
PI = 3.14
- 에러가 발생한다.
const PI
PI = 3.14
- 참조타입의 경우 내부 값이 변경이 가능하다.
- 구체적으로 OBJ 내부의 property는 변경이 가능하다.
- 참조타입 자체는 mutable 하기 때문이다.
const OBJ = {
prop1 : 1,
prop2 : 2
}
OBJ.prop1 = 3
console.log(OBJ.prop1)
- 배열도 근본적으로는 객체이게 때문에 동일한 로직이 적용된다.
const ARR = [0, 1, 2]
ARR.push(3)
delete ARR[1]
console.log(ARR)
- 만약에 참조값 내부도 immutable 하게 하고 싶다면?
해결방안:
Object.freeze()
,Object.defineProperty()
const OBJ = {}
Object.defineProperty(OBJ, 'prop1', {
value : 1,
writable: false, // 재할당 금지 옵션
configurable: false //
})
const OBJ2 = {
prop1 : 1
}
Object.freeze(OBJ2)
여전히 남는 문제점: nested Object의 경우...
const OBJ = {
prop1 : 1,
prop2 : [2, 3, 4],
prop3 : { a: 1, b: 2 }
}
Object.freeze(OBJ)
OBJ.prop1 = 3
OBJ.prop2.push(5)
OBJ.prop3.b = 3
console.log(OBJ)
Object.freeze(OBJ.prop2)
OBJ.prop2.push(6)
console.log(OBJ)
- 내부 객체까지 재귀적으로 freeze 하는 키워드 - deepfreeze
- deepcopy 키워드도 함께 알아두자.
- immutable 한 객체라는 키워드(데이터 기반의 자료형 다뤄야하는 환경에서 중요한 키워드)
var obj = {
prop1: 1,
prop2: 2,
prop3: 3
}
// (추가) for in 문에 const 를 쓰는 이유라도 ?
// for 문이 실행되는 과정에서 내부적으로 프로퍼티를 변경못하게 하기 위해
// 안될 것 같지만 된다.
for (const prop in obj) {
console.log(prop)
}
// 위 코드는 사실 아래와 같은 코드여서 에러가 발생하지 않는다.
let keys = Object.keys(obj);
for(let i = 0; i <keys.length; i++){
const prop = obj[keys[i]];
console.log(prop);
}
{
const prop = obj[key[i]];
console.log(prop);
}
{
const prop = obj[key[i]];
console.log(prop);
}
{
const prop = obj[key[i]];
console.log(prop);
}
{
const prop = obj[key[i]];
console.log(prop);
}
...
// 이 코드도 에러를 발생하지 않는다.
for (const element of obj) {..}
// 이 코드는 에러가 발생한다.
for (const i = 0; i < 5; i++) {
console.log(i)
}
{
const i = 0;
console.log(i);
}
{
const i = 0;
console.log(i);
}
// 아직 의문점이 남는다. 아래 for 문에서도 각 i 는 독립적인 block scope를 가지게 되는 것이 아닌가?
// 현재 강의에 질문을 남겼다.
- 위 코드는 사실 아래와 같은 코드이기 때문에 된다.
{
let a = 10
{
const b = 20
console.log(b)
}
console.log(a)
console.log(b)
}
console.log(a)
var a = 0
var a = 1
console.log(a)
let b = 2
let b = 3
console.log(b)
const c = 4
const c = 5
console.log(c)
var d = 4
let d = 5
const d = 6
console.log(d)
{
console.log(a)
let a = 10
{
console.log(b)
let b = 20
}
}
{
console.log(a)
const a = 10
{
console.log(b)
const b = 20
}
}
=> hoisting X ?
{
let a = 10
{
console.log(a)
let a = 20
}
}
{
const a = 10
console.log(a)
{
console.log(a)
const a = 20
console.log(a)
}
}
// 전역공간에서 var 로 선언한 변수는 전역변수임과 동시에 전역객체의 property
// 전역 객체의 프로퍼티 할당
window.b =10
// 지우기 가능
delete window.b // ture
//어떻게 해도 지워지지 않음/ 양쪽에 다 걸려있어서 그럼
var b = 10
delete window.b // false
delete b // false
b // 10
window.b //10
var a = 10
console.log(window.a) // 10
console.log(a) // 10
delete a
console.log(window.a) // 10
console.log(a) // 10
delete window.a // false
window.b = 20
console.log(window.b)
console.log(b)
delete b
console.log(window.b)
console.log(b)
let c = 30
console.log(window.c) //전역 객체의 property와 전역 변수가 분리됨
console.log(c) // 전역 변수에 해당
delete c //fale delete 명령 자체가 객체의 프로퍼티를 지우라는 명령이기 때문에 안먹음 변수접근 x
l