티스토리 뷰

Edu_hanghae99/TIL

[TIL] Javascript_221118

soobin Choi 2022. 11. 18. 09:57

🐤 JavaScript의 자료형과 JavaScript만의 특성은 무엇일까 ?

1. 느슨한 타입(loosely typed)의 동적(dynamic) 언어

동적 타입 - JavaScript는 느슨한 타입(loosely typed)의 동적(dynamic) 언어입니다. JavaScript의 변수는 어떤 특정 타입과 연결되지 않으며, 모든 타입의 값으로 할당 (및 재할당) 가능합니다.

let foo = 42 // foo가 숫자
foo = 'bar' // foo가 이제 문자열
foo = true // foo가 이제 불리언

2. JavaScript 형변환(type conversion)

: 함수와 연산자에 전달되는 값이 적절한 자료형으로 자동 변환되는 과정

 

문자형으로 변환 은 무언가를 출력할 때 주로 일어납니다. String(value)을 사용하면 문자형으로 명시적 변환이 가능합니다. 원시 자료형을 문자형으로 변환할 땐, 대부분 그 결과를 예상할 수 있을 정도로 명시적인 방식으로 일어납니다.

 

숫자형으로 변환 은 수학 관련 연산시 주로 일어납니다. Number(value)로도 형 변환을 할 수 있습니다.

숫자형으로의 변환은 다음 규칙을 따릅니다.

 

전달받은 변환
undefined NaN
null 0
true / false 1 / 0
string 전달받은 문자열을그대로읽되, 처음과 끝의 공백을 무시합니다. 문자열이 비어있다면 0 되고, 오류 발생  NaN 됩니다.

 

불린형으로 변환 은 논리 연산 시 발생합니다. Boolean(value)으로도 변환할 수 있습니다.

불린형으로의 형 변환은 다음 규칙을 따릅니다.

전달받은 변환
0, null, undefined, NaN, "" false
외의 true

형 변환 시 적용되는 규칙 대부분은 이해하고 기억하기 쉬운 편에 속합니다. 다만 아래는 예외적인 경우이기 때문에 실수를 방지하기 위해 따로 기억해 두도록 합시다.

  • 숫자형으로 변환 시 undefined는 0이 아니라 NaN이 됩니다.
  • 문자열 "0" " "같은 공백은 불린형으로 변환 true 됩니다.

3. ==, ===

다른 프로그래밍 언어들에서는 비교 연산자가 ==인데 비해, 자바스크립트는 ==(동등 연산자)와 ===(일치 연산자)로 나뉜다. 이는 자바스크립트의 특징 때문인데, 약타입 언어인 자바스크립트에서는 1과 "1"을 비교하면 "1"을 자동으로 1로 형변환해 비교하고, 결국 1 == "1"은 true가 나오게 된다. 이와 비슷하게 null == undefined도 true로 판단되는 등 여러 문제가 많아 타입까지 비교하는 ===의 존재가 필요하게 되었다.

===(일치 연산자) 경우 타입까지 비교하게 되므로, 1 "1" 타입이 다르므로 1 === "1" false 판단된다. 최근 들어서는 많은 스타일 가이드에서 불편한 버그가 발생하지 않는 ===(일치 연산자) 사용이 권장된다.

4. 느슨한 타입(loosely typed)의 동적(dynamic) 언어의 문제점? 보완할 수 있는 방법?

실행 도중에 변수에 예상치 못한 타입이 들어와 타입에러가 발생할 수 있습니다. 동적타입 언어는 런타임 시 확인할 수 밖에 없기 때문에, 코드가 길고 복잡해질 경우 타입 에러를 찾기가 어려워집니다. 이러한 불편함을 해소하기 위해 TypeScipt나 Flow 등을 사용할 수 있습니다.

5. undefined와 null의 차이?

undefined은 변수를 선언하고 값을 할당하지 않은 상태, null은 변수를 선언하고 빈 값을 할당한 상태(빈 객체)이다.  즉, undefined는 자료형이 없는 상태이다.

*출처:  javascript.info, namu.wiki, https://triplexlab.tistory.com/197

🐤 JavaScript 객체와 불변성이란 ?

1. 기본형 데이터와 참조형 데이터

JavaScript는 원시 타입과 참조 타입이라는 두가지 자료형을 제공하며 Object를 제외한 모든것들은 Primitive한 성격을 갖고 있다.

  • Primitive Type : 데이터의 실제 값 할당
  • Reference Type : 데이터의 위치 값만 할당

1) Primitive Type (원시타입)

원시 타입의 데이터는 변수에 할당이 될 때 메모리 상에 고정된 크기로 저장이 되고 해당 변수가 원시 데이터 값을 보관한다. 원시 타입 자료형은 모두 변수 선언, 초기화, 할당 값이 저장된 메모리 영역에 직접적으로 접근한다. 즉, 변수에 새 값이 할당이 될 경우, 변수에 할당된 메모리 블럭에 저장된 값을 바로 변경한다.  Access By Value

ㄱ. Primitive Type의 종류

  • Boolean
  • number
  • String
  • null
  • undefined

ㄴ. Primitive Type의 변수 복사

각 변수 간에 원시 타입 데이터를 복사할 경우, 데이터의 값이 복사된다.

var x = 100;
var y = x;

x = 99;

console.log(y);	// 100;

데이터의 값을 복사하기 때문에 console을 찍기 전, x를 99로 바뀌었지만 이전의 값인 100을 복사해두었기 때문에 100이 찍히는 것을 볼 수 있다.

2) Reference Type (참조 타입)

참조 타입의 데이터는 크기가 정해져 있지 않고 변수에 할당이 될 때 값이 직접 해당 변수에 저장될 수 없으며 변수에는 데이터에 대한 참조만 저장된다. 변수의 값이 저장된 힙(Heap) 메모리의 주소값을 저장한다. 참조 타입은 변수의 값이 저장된 메모리 블럭의 주소를 가지고 있고 자바스크립트 엔진이 변수가 가지고 있는 메모리 주소를 이용해서 변수의 값에 접근한다. Access By Reference

ㄱ. Referece Type의 종류

  • Object ( array, function, object )

ㄴ.  Reference Type의 변수 복사

각 변수 간에 참조 타입 데이터를 복사할 경우, 데이터의 참조가 복사된다.

var x = { count : 100 };
var y = x;

x.count = 99;

console.log(y);	// 99

변수 x와 y는 동일한 참조를 담고 있다. 따라서 동일한 객체를 가리키게 된다.

3) Primitive Type vs Reference Type

Ex) 1

var list1 = [1, 2, 3];	// 메모리 주소 : 8765e 라고 가정
var list2 = [1, 2, 3];	// 메모리 주소 : 9524d 라고 가정

var isSame = list1 === list2;	8765e === 9524d

console.log(isSame);	// false

list1, list2안의 요소는 같지만 배열을 새롭게 만들어 변수에 담고 있기 때문에 각자 새로운 메모리 위치를 만들어 저장하고 그 위치를 참조하여 변수에 해당 위치값을 저장하는 것과 같다. 따라서 결과는 false가 된다.

Ex) 2

var list3 = [ 1, 2, 3];
var list4 = list3;

var isSame = list3 === list4;

console.log(isSame);	// true

위의 예제와는 다르게 새롭게 배열을 생성하지않고 list3의 위치값을 그대로 list4에 넣는 것이기 때문에 위치값이 같은 경우라고 할 수 있다. 따라서 결과는 true가 된다.

Ex) 3

var updateAge = function () {
	this.age++;
};	// '메모리 주소 : 4737d' 라고 가정

var son = {
	age : 3,
    growUp : updateAge
};

var daugther = {
	age : 7,
    growUp : updateAge
};

var mother = {
	age : 38,
    growUp : updateAge,
    children : [ son, daugther ]
};

var father = {
	age : 38,
    growUp : updateAge,
    wife : mother,
    children : [ son, daugther ]
};

// Ex 3.1
if (father.growUp === son.growUp) {	// 4737d === 4737d
	console.log('성장 가능');
}	// 성장 가능

// Ex 3.2
if (father.children === mother.children) {
	console.log('부부!');
}	// false로 console이 찍히지 않음

Ex 3.1의 경우, updateAge라는 변수의 데이터 값으로 함수의 위치값을 저장했다. 가상 메모리 주소가 4737d라는 가정하에 object는 해당 데이터의 위치값을 저장하므로 father.growUp과 son.growUp의 값은 같은 값이 된다. 따라서 결과는 true로 console에 '성장 가능'이 찍히게 된다.

Ex 3.2의 경우, 똑같은 변수들이 담겨있지만 객체 내에서 배열을 새롭게 만들어 mother.children과 father.children은 서로 다른 위치값을 할당을 새롭게 할당받았기 때문에 위치값이 다르게 된다. 따라서 결과는 false로 console에 아무것도 찍히지 않게 된다.

2. JavaScript 형변환

객체를 원시형으로 변환하기

  1. 객체는 논리 평가  true 반환합니다. 하나의 예외도 없죠. 따라서 객체는 숫자형이나 문자형으로만 변환이 일어난다.
  2. 숫자형으로의 변환은 객체끼리 빼는 연산을 때나 수학 관련 함수를 적용할 일어난다. 객체 Date끼리 차감하면(date1 - date2) 날짜의 시간 차이가 반환됩니다.
  3. 문자형으로의 변환은 대개 alert(obj)같이 객체를 출력하려고 일어납니다.

+ KEYWORD : ToPrimmitive, Symbol.toPrimitive, toString, valueOf, 반환타입

3. 불변 객체를 만드는 방법

불변 객체'란? '변하지 않는 객체' 즉 이미 할당된 객체가 변하지 않는다는 뜻을 가지고 있다.

자바스크립트에서 불변 객체를 만들 수 있는 방법은 기본적으로 2가지 인데 const Object.freeze()를 사용하는 것이다.

 

const

자바스크립트 키워드 중 하나인 const이다. ES6문법부터 let과 const를 지원한다.

const 키워드는 변수를 상수로 선언할 수 있다, 일반적으로 상수로 선언된 변수는 값을 바꾸지 못하는 것으로 알려져 있다.

그렇다면 상수로 선언한 객체는 불변 객체일까? 

const test = {};
test.name = "mingyo";

console.log(test);  // {"mingyo"}

ES6에서의 const는 할당된 값이 상수가 되는 것이 아닌 바인딩된 값이 상수가 되는, 즉 test변수가 상수가 되기 때문에 const 키워드로 선언된 test변수에는 객체 재할당은 불가능하지만 객체의 속성은 변경 가능하다.

재할당이 불가능 한 이유는 변수와 값(객체) 사이의 바인딩 자체가 변경이 되기 때문에 상수인 test변수는 재할당이 불가능한 것이고

객체의 속성이 변경가능 한 이유는 실제 객체가 변경은 되지만 ( {} -> name : "mingyo" ) 객체와 변수(test)사이의 바인딩은 변경이 되지 않기 때문에 객체의 속성은 변경가능한 것이다. 

때문에 비록 재할당은 불가능하지만 객체의 속성을 변경함으로 인해 변수에 바인딩된 객체의 내용까지 변경이 되기 때문에 불변객체라고 하기는 힘들다. 따라서 Object.freeze()라는 JS내장메소드도 살펴보도록 하겠다.

 

Object.freeze()

자바스크립트에서 기본적으로 제공하는 메소드인 Object.freeze() 메소드이다. 공식 문서에서는 "객체를 동결하기 위한 메소드" 라고 적혀있다.

그렇다면 이 메소드를 사용하면 불변 객체를 만들 수 있을까? 먼저 이 메소드의 사용법부터 알아보면,

let test = {
    name : 'kim'
}

Object.freeze(test);

test 변수에 key value를 가진 객체를 바인딩 후 Object.freeze(test)를 사용해 바인딩된 변수를 동결 객체로 만들었다. 때문에 test 객체는 객체의 속성을 변경하는 시도는 불가능하다.

test.name = 'Jung';
console.log(test) // {name: 'kim'}

위와 같이 객체의 속성을 변경하는 시도는 무시된다.

그러나 Object.freeze()는 동결된 객체를 반환하지만 객체의 재할당은 가능하다. 

test = {
    age : 15
};
console.log(test); // {age: 15}

위와 같이 객체의 재할당은 가능하다. 때문에 Object.freeze()도 불변 객체라고 할 수는 없을 것 같다.

그럼 결국 불변 객체는 어떻게 만들 수 있냐면..

const와 Object.freeze()를 조합하여 만들 수 있다. (const의 재할당불가 + Object.freeze()의 객체속성 변경불가)

그렇다면 아래 코드와 같이 사용하면 된다.

const test = {
    'name' : 'jung'
};

Object.freeze(test);

먼저 const키워드로 바인딩 된 변수를 상수화 시킨 다음, Object.freeze()로 해당 변수를 동결 객체를 만들면

객체의 재할당과 객체의 속성 둘 다 변경불가능한 불변 객체가 된다.

4. 얕은 복사와 깊은 복사

1) 깊은 복사(Deep copy)란?

- 데이터 자체를 통째로 복사한다

- 복사된 두 객체는 완전히 독립적인 메모리를 차지한다

- value type의 객체들은 깊은 복사를 하게 된다.

 

아래의 예시에서 arr1은 string 배열을 가진다. arr2에 arr1을 할당 해보자.

이때, arr1에 있는 모든 string들은 깊은 복사가 일어나서 새로운 배열을 생성하여 arr2에 할당한다. (String은 value type이므로 깊은 복사가 일어난다.) 때문에 arr1을 변경하여도 arr2에서는 값이 변경되지 않는다.

아래 예시에서는 string1에 string2를 할당한다. 이 후, string1의 값을 변경하면 string2에 값도 변할까?


아니다. String은 깊은 복사가 일어나므로 string1을 변경하여도 string2는 변경되지 않는다.

이렇게 깊은 복사는 인스턴스가 완전히 독립적이다. 이와 같은 개념은 모든 value type에 적용된다.

2) 얕은 복사(Shallow copy)란?

얕은 복사는 아주 최소한만 복사를 한다. 값을 복사한다 하더라도, 인스턴스가 메모리에 새로 생성되지 않는다. 값 자체를 복사하는 것이 아니라 주소값을 복사하여 같은 메모리를 가리키기 때문이다. 새로운 인스턴스를 생성하지 않기 때문에 깊은 복사보다 상대적으로 빠르다. reference type을 복사하는 경우 얕은 복사가 일어난다.

class Address {
    var address : String
    
    init(_ string : String){
        self.address = string
    }
}

*여기서 init(_:) 주어진 문자열에서 인스턴스를 만드는 것

init?<S>(_ text: S) where S : StringProtocol

 

a1의 인스턴스를 a2에 할당한다. 이때 앝은 복사가 일어나기 때문에 같은 주소값을 가지게 된다.

만약 a2의 address에 값을 바꾼다면 a1의 address도 같이 바뀌게 된다. 같은 메모리를 차지하고 있기 때문이다.

출처: javascript.info, https://velog.io/@surim014/JavaScript-Primitive-Type-vs-Reference-Type, https://spiderwebcoding.tistory.com/8, https://velog.io/@ellyheetov/Shallow-Copy-VS-Deep-Copy

🐤 호이스팅과 TDZ는 무엇일까 ?

1. 스코프, 호이스팅, TDZ

1) Scope(유효범위)

: 변수가 유효성을 갖는 영역. 참조 대상 식별자(identifier, 변수, 함수의 이름과 같이 어떤 대상을 다른 대상과 구분하여 식별할 있는 유일한 이름) 찾아내기 위한 규칙이다. 자바스크립트는 규칙대로 식별자를 찾는다.

변수는 전역 또는 코드 블록(if, for, while, try/catch 등)이나 함수 내에 선언하며 코드 블록이나 함수는 중첩될 수 있다. 식별자는 자신이 어디에서 선언됐는지에 의해 자신이 유효한(다른 코드가 자신을 참조할 수 있는) 범위를 갖는다. 식별자 이름의 충돌을 방지한다.

 

자바스크립트에서 스코프를 구분하면 다음과 같다.

 

- 전역 스코프 (Global scope)코드 어디에서든지 참조할 수 있다.

- 지역 스코프 (Local scope or Function-level scope)함수 코드 블록이 만든 스코프로 함수 자신과 하위 함수에서만 참조할 수 있다.

 

모든 변수는 스코프를 갖는다. 변수의 관점에서 스코프를 구분하면 다음과 같이 2가지로 나눌 수 있다.

 

- 전역 변수 (Global variable)전역에서 선언된 변수이며 어디에든 참조할 수 있다.

= 지역 변수 (Local variable)지역(함수) 내에서 선언된 변수이며 그 지역과 그 지역의 하부 지역에서만 참조할 수 있다.

 

변수는 선언 위치(전역 또는 지역)에 의해 스코프를 가지게 된다.

즉, 전역에서 선언된 변수는 전역 스코프를 갖는 전역 변수이고, 지역(자바스크립트의 경우 함수 내부)에서 선언된 변수는 지역 스코프를 갖는 지역 변수가 된다. 전역 스코프를 갖는 전역 변수는 전역(코드 어디서든지)에서 참조할 수 있다. 지역(함수 내부)에서 선언된 지역 변수는 그 지역과 그 지역의 하부 지역에서만 참조할 수 있다.

 

+ More

https://hanamon.kr/javascript-%EC%8A%A4%EC%BD%94%ED%94%84%EC%99%80-%EB%B3%80%EC%88%98%EC%84%A0%EC%96%B8%ED%82%A4%EC%9B%8C%EB%93%9C-%EC%B0%A8%EC%9D%B4%EC%A0%90/

 

[JavaScript] 스코프(Scope)와 변수 선언 (var, let, const 키워드 차이점) - 하나몬

⚡️ 스코프(Scope) 스코프(Scope)라는 영어 단어 자체는 ‘범위’라는 의미를 가진다. 컴퓨터 공학, 그리고 JavaScript 에서도 ‘범위’의 의미를 가지고 있다. JavaScript 에만 국한된 개념은 아니다.  

hanamon.kr

2) hoisting 호이스팅

인터프리터가 변수와 함수의 메모리 공간을 선언 전에 미리 할당하는 것. 변수의 선언과 초기화를 분리한 후, 선언만 코드의 최상단으로 옮기는 것. let과 const로 선언한 변수의 경우 호이스팅 시 변수를 초기화하지 않습니다.

JavaScript는 함수의 코드를 실행하기 전에 함수 선언에 대한 메모리부터 할당합니다.!

함수를 선언하기 전에 먼저 호출했을 때의 예제 ex)

catName("클로이");

function catName(name) {
  console.log("제 고양이의 이름은 " + name + "입니다");
}
//결과: "제 고양이의 이름은 클로이입니다"

함수 호출이 함수 자체보다 앞서 존재하지만 동작함. 

-> 이것이 JavaScript에서 실행 맥락이 동작하는 방식

호이스팅은 변수를 선언하기 전에 먼저 초기화하고 사용할  있는 

*출처 : https://developer.mozilla.org/ko/docs/Glossary/Hoisting

3) TDZ(Temporal Dead Zone)

Scope 시작 지점부터 초기화 시작 지점까지의 구간. 

" Temporal Dead Zone semantics forbids accessing a variable before its declaration. It enforces the discipline: don't use anything before declaring it "

TDZ은 선언문이 존재하는 스코프 범위 안에서 변수에 영향을 준다.

TDZ는 const, let, class 구문의 유효성에 영향을 미친다. TDZ는 선언 전에 변수를 사용하는 것을 허용하지 않는다.

https://ui.toast.com/weekly-pick/ko_20191014

 

TDZ을 모른 채 자바스크립트 변수를 사용하지 말라

간단한 질문을 하나 하겠다. 아래 코드 스니펫에서 에러가 발생할까? 첫 번째 코드는 인스턴스를 생성한 다음 클래스를 선언한다.

ui.toast.com

2. 함수 선언문과 함수 표현식에서 호이스팅 방식의 차이

1) 함수 선언식

일반적인 함수 선언 방식

function funcDeclarations() {
    return 'enchovy';
}
 
funcDeclarations();

2) 함수 표현식

자바스크립트 언어의 특징을 활용한 선언 방식

let funcExpression = function () {
    return 'enchovy';
}
 
funcExpression();

 

함수 선언문은 var와 같이 함수 스코프(function scope)를 가지고 let과 const 변수는 블록 스코프(block scope)를 갖는다. 또한, 함수 선언식은 코드가 실행되기 전에 로드되지만, 함수 표현식은 인터프리터가 해당 코드 줄에 도달할 때 로드된다. 함수 선언식은 호이스팅 되지만 함수 표현식은 호이스팅 되지 않으므로 정의된 범위에서 로컬 변수의 복사본을 유지할 수 있다.

 

*출처 : https://poiemaweb.com/js-scope, https://string.tistory.com/117

3. let, const, var, function 이 어떤 원리로 실행되는지?

  • 선언 단계(Declaration phase) : 변수를 실행 컨텍스트의 변수 객체에 등록하는 단계를 의미합니다. 이 변수 객체는 스코프가 참조하는 대상이 됩니다.
  • 초기화 단계(Initialization phase) : 실행 컨텍스트에 존재 하는 변수 객체에 선언 단계의 변수를 위한 메모리를 만드는 단계 입니다. 이 단계에서 할당된 메모리에는 undefined로 초기화 됩니다.
  • 할당 단계(Assignment phase) : 사용자가 undefined로 초기화된 메모리의 다른 값을 할당하는 단계 입니다. 

var의 경우는 변수의 선언과 초기화가 동시에 일어난다. 즉, 변수가 초기화가 되는데 할당되기 이전의 undefiend상태로 존재하게 된다.

그러나 let과 const는 변수의 선언과 초기화가 동시에 일어나지 않는다. 변수의 선언만 인정되어 실행컨택스트에는 담기게 되나(호이스팅이 일어난다.) 초기화가 되지 않았기 때문에 초기화 되기 이전에 console로 실행시키게 되면 error가 발생하게 된다.

*출처: https://zep.us/play/yxZ7M7

4. 실행 컨텍스트와 콜 스택

1) Execution Centext

실행 가능한 코드가 실행되기 위해 필요한 환경. 자바스크립트 코드가 실행되고 연산되는 범위.

 

ㄱ. Execution Context의 종류

  • Global Context(전역 컨텍스트)
    함수 안에서 실행되는 코드가 아니라면 모든 스크립트는 Global Context에서 실행된다.
    스택 구조를 가지는 형태로 Execution Context가 생성이 된 후 global object로 window가 this로 할당되고 스택에 쌓이게 된다.
    Global Context 안에 포함되는 모든 코드들의 실행 가능한 코드들은 순서대로 스택에 쌓이게 되며 LIFO(Last In First Out)으로 함수를 실행하게 된다.
  • Functional Context(함수 컨텍스트)
    Functional Context는 선언된 함수가 호출이 될 때를 기점으로 생성, 함수의 모든 동작이 종료되면 Functional Context는 소멸된다.(closure를 사용한다면 scope가 소멸하지 않고 이용할 수 있다.) 각각의 함수들은 각각의 Functional Context를 가지지만 함수가 호출이 되어야만 생성된다.

ㄴ. Execution Context의 3가지 객체

  • Variable Object(변수 객체)
    실행 컨텍스트가 생성되면, 자바스크립트 엔진은 (실행에 필요한 정보들이 있기 때문에) 정보들을 담을 객체를 생성한다.
    • variable
    • parameter 와 arguments
    • 함수 선언(함수 표현식은 제외)
    • Variable Object는 실행 컨텍스트의 프로퍼티이기 때문에 값을 갖는다. 전역 코드에서 생성되는 Global Context 와 함수가 호출 될 때 생성되는 Functional Context 의 경우 값들이 가리키는 객체가 다르다. 왜냐하면 Functional Context에는 parameter 와 arguments가 들어 있기 때문이다.
  • Scope Chain
    스코프 체인(Scope Chain)은 실행 컨텍스트가 참조할 수 있는 변수, 함수 선언 등의 정보를 담고 있는 리스트를 뜻한다. 전역 객체와 함수의 스코프의 레퍼런스를 저장하고 있다.
    자바스크립트 엔진은 스코프 체인을 통해 Lexical Scope(렉시컬 스코프)를 파악한다.
    상위 함수, 전역 스코프 등을 참조할 수 있는 이유가 스코프 체인이 검색을 하기 때문이다.
    (하위 -> 상위 -> 전역) 참조에 실패한다면 스코프 체인에 담겨진 순서대로 계속해서 이어간다.
    검색에 실패하게 된다면 정의되지 않은 변수에 접근하는 것이기 때문에 에러를 발생시킨다.
  • this value
    this 프로퍼티는 this 값이 할당되는데 그 값은 함수 호출 패턴에 의해 결정된다.

실행에 필요한 정보를 형상화하고 구분하기 위해서 자바스크립트 엔진은 실행 컨텍스트를 물리적 객체의 형태로 관리한다.

 

*출처: https://velog.io/@stampid/Execution-Context%EC%8B%A4%ED%96%89-%EC%BB%A8%ED%85%8D%EC%8A%A4%ED%8A%B8%EB%9E%80

2) Call stack

코드가 실행되면서 생성되는 Execution Context를 저장하는 자료구조.

엔진이 처음 script를 실행할 때, Global Execution Context를 생성하고 이를 Call Stack에 push합니다.

그 후 엔진이 함수를 호출할 때 마다 함수를 위한 Execution Context를 생성하고 이를 Call Stack에 push 합니다.

 

*출처: https://medium.com/sjk5766/call-stack%EA%B3%BC-execution-context-%EB%A5%BC-%EC%95%8C%EC%95%84%EB%B3%B4%EC%9E%90-3c877072db79

5. 스코프 체인, 변수 은닉화

1) Scope chain

유효 범위를 나타내는 스코프가 scope 프로퍼티로 각 함수 객체 내에서 연결리스트 형식으로 관리되는데,  스코프 간의 상하관계를 스코프 체인이라고 한다.

 

+ Closure

: the combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment). In other words, a closure gives you access to an outer function's scope from an inner function. 

- Lexical Environment : 자신이 실행되었을 때의 환경

-> Closure란 생성될 당시의 환경을 기억하는 함수

(캡슐화와 은닉화를 구현하는 또 다른 방법)

https://meetup.toast.com/posts/86

2) Hiding Variables

(function () {
  var a = 'a';
})();

console.log(a); // a is not defined

함수 외부에서 a를 출력해보면, 아직 정의되지 않았다(a is not defined)는 에러메세지를 확인할 수 있습니다. 이러한 방식과 같이 직접적으로 변경되면 안 되는 변수에 대한 접근을 막는 것.

function a(){
  let temp = 'a' 
  
  return temp;
} 

// console.log(temp)  error: temp is not defined
const result = a()
console.log(result); //a

현재 위 함수 내부적으로 선언된 temp에는 직접적으로 접근을 할 수 없습니다. 함수 a를 실행시켜 그 값을 result라는 변수에 담아 클로저를 생성함으로써 temp의 값에 접근이 가능합니다. 이렇게 함수 안에 값을 숨기고 싶은 경우 클로저를 활용해볼 수 있다.

 

+ Difference between Encapsulation and Hiding

https://dokdogalmaegi.tistory.com/48

 

캡슐화와 은닉화의 차이점 - Difference between Encapsulation and Hiding

캡슐화 ( Encapsulation ) 객체지향 패러다임 중 하나인 캡슐화는 중요한 데이터를 보존, 보호하는 것입니다. 일반적으로 연관 있는 변수와 함수를 클래스로 묶는 작업을 말하기도 합니다. 은닉화,

dokdogalmaegi.tistory.com

*출처 : https://velog.io/@0seo8/JS-%EC%9D%80%EB%8B%89%ED%99%94-os17ra37

 

📌 Reference

프로그래머스 자바스크립트 기초 (https://programmers.co.kr/learn/courses/3)전 범위

모던 자바스크립트 튜토리얼 (https://ko.javascript.info/)

모던 자바스크립트 Deep Dive (http://www.yes24.com/Product/Goods/92742567)


👊🏻 오늘 한 일

  • 자바스크립트 공부 TIL 기록
  • 등 웨이트 운동 및 유산소 40분
  • 모니터, 노트북 받침대, 어댑터, 키보드 주문

 😲 오늘 느낀 점

정말 공부할 게 많다. 자바스크립트 과제는 냈지만 기초문법, 자바스크립트 책, 공식문서들 등을 보며 더 공부해야 한다. 그림으로 보거나 동기분들께 말로 설명을 듣는 게 좋다. 나는 어떤 지식을 배울 때 늘 동영상<<<<<글<<그림<<<말 이렇게 동영상이 제일 안 되고 면대면으로 말으로 듣는 게 제일 집중이 잘 된다. 호이스팅이 뭔지, 자바스크립트가 어떻게 파일을 읽는지에 관해 설명을 들었는데 한 번에 이햐가 됐다. 함수가 한 줄마다 바로 실행을 하는 줄 알았는데 먼저 선언을 읽고 다시 올라가서 한 줄씩 실행을 한다는 게 흥미로웠다. 전체 파일을 읽을 때는 처음부터 끝까지 위치만 파악하고 함수가 호출되는 지점으로 가서 그 함수 안으로 들어가며, 그 함수를 실행시키고 다시 runtime이 시작된다. '함수 안으로 들어간다'라는 표현이 재밌다. 눈높이 맞춤 강의를 들려주는 고마운 동기 강사님♥️♥️♥️

오늘 4일 만에 운동을 했더니 정말 자극이 잘 오고 땀나는 것도 기분이 좋았다! 유산소는 재미가 없었는데 노래를 들으며 뛰듯이 걸으니 그 것마저 좋았다. 운동을 다 하고 샤워하고 나오니 세상을 가진 기분이었다. 몸을 풀어주기 전에는 온 몸이 찌뿌둥했는데 몸이 풀리니 아픈 것도 사라졌다. 역시 스트레스를 가장 빨리 푸는 방법은 운동이다! 집에 오면서 순대를 사왔다. 저녁과 함께 순대를 먹으며 넷플릭스 블랙리스트를 봤다. 요즘 추리물이 재밌다. 푹 쉬며 에너지를 충전하고 공부를 시작했다.

모니터 등을 사느라 지갑이 얇아졌다. 지금 쓰고있는 mac air m2가 말도 안되게 좋다. 세 손가락으로 다른 창들을 띄우는 기능뿐만 아니라 다 좋다. 원래도 타자 소리는 좋아했는데 이 아이의 타자 소리가 좋다. 조금 더 작아도 좋을 것 같다. 모니터가 오면 큰 화면으로 코드를 볼 수 있겠지 기대된다. 오늘은 자체 반 휴강이었지만 내일은 정말 집중해서 목표를 다 끝내야겠다.

 

👏🏻 오늘의 칭찬

자바스크립트 공부 기록 남길 깃허브 만들었음. 한 두 시간만에 집중해서 과제의 반 이상을 끝냄. 운동을 했음!

 

🤔 오늘의 아쉬운 점

어제 세운 오늘의 목표를 잊고있었음. 매일 아침 목표를 다시 보고 하루를 시작해야겠다. 그리고 '해야지'라고 생각만 하고 있는 것들을 언제 할 건지 데드라인을 정해야겠다. 데드라인 없으면 미루고 또 미루다가 벼락치기하는 나..^^

 

⛵️ 내일 할 일

  • 자바스크립트 과제 추가 공부
  • 자바스크립트 기본 문법 공부
  • 자바스크립트 과제 가이드 자료들 다 읽기
  • 자바스크립트 references 다 읽기
  • 알고리즘 문제 풀이 깃허브 레포지토리 만들기
  • 알고리즘 문제 1~10번까지 풀