JavaScript(JS)는 '웹페이지에 생동감을 불어넣기 위해' 만들어진 프로그래밍 언어입니다.

JS로 작성한 프로그램을 script라고 부르며 HTML의 script태그안에 넣어 작성할 수 있습니다. 

작성된 JS는 웹페이지를 불러올 때 자동으로 실행됩니다. 

 

 

JavaScript의 자료형과 Javascript만의 특성

 

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

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

 

정적언어와 동적언어란?

타입, 즉 자료형이란 int, short, float, bool등이 있다. 

변수를 선언할 때 앞에 붙여 사용한다.

int num = 1;

 

정적언어

정적언어는 위에서 언급한 타입, 즉 자료형을 컴파일 시에 결정하는 것이다. 

컴파일 시에 자료형에 맞지 않은 값이 들어가 있으면 컴파일 에러가 발생하게 된다.

bool num = 1; //error

장점으로는 컴파일 시 타입에 대한 정보를 결정하기 때문에 속도가 빠르다.

ex) C, C#, JAVA 

 

동적언어

동적 타입 언어의 자료형은 컴파일 시 자료형을 정하는 것이 아니고 런타임에 의해 결정된다.

소스가 컴파일, 빌드될 때 자료형을 결정하는 것이 아니라 실행할 때 결정된다. 

언어 자체에서 타입을 추론하여 형을 변환해 줍니다. 

장점으로는 기본적으로 변수 생성시 매번 타입을 써줄 필요가 없기 때문에 편하고 빠르게 코드 작성 가능

ex) JavaScript, Ruby, Python 

 

  • JavaScript의 형변환

함수와 연산자에 전달되는 대부분 적절한 자료형으로 자동 변환됩니다. 

이러한 과정을 "형변환(type  conversion)"이라고 한다.

ex) alert가 전달받은 값의 자료형과 관계없이 이를 문자열로 자동 변환하여 보여주는 것. 

 

이 외에, 전달받은 값을 의도를 갖고 원하는 타입으로 변환(명시적 변환)해 주는 경우도 형 변환이라고 할 수 있다.

ex) 수학과 관련된 함수와 표현식에서 자동으로 일어나는 것을 볼 수 있다.

 

alert( "6" / "2" ); // 3, 문자열이 숫자형으로 자동변환된 후 연산이 수행됩니다.

 

  • ==, ===

동등 연산자(equality operator)

"==" 는  같음(동등)을 비교하는 연산자로 같다면 true, 다르다면 false를 반환한다.

alert( 2 == 1); // false
alert( '01' == 1 ); // true, 문자열 '01'이 숫자 1로 변환된 후 비교가 진행됩니다.

두번째 줄 처럼 다른 형을 가진 값 간의 비교시 JS는 이 값들을 숫자형으로 변환시킨 후 비교가 이뤄진다.

 

하지만 동등연산자 "=="는 0과 false를 구별하지 못합니다.

alert( 0 == false ); // true
alert( '' == false ); // true

이를 구별하기 위해 일치 연산자(strict equality operator) ===를 사용하면 형 변환 없이 값을 비교할 수 있습니다.

일치 연산자는 엄격한(strict) 동등 연산자입니다. 자료형의 동등 여부까지 검사하기 때문에 피연산자 a와 b의 형이 다를 경우 a === b는 즉시 false를 반환합니다.

 

alert( 0 === false ); // false, 피연산자의 형이 다르기 때문입니다.

 

  • 느슨한 타입(loosely typed)의 동적(dynamic)언어의 문제점은 무엇이 있을지 생각해보세요.

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

 

  • undefined와 null의 미세한 차이들을 비교

null이란?

null은 JavaScript의 원시 값 중 하나로, 어떤 값이 의도적으로 비어있음을 표현하며 불리언 연산에서는 거짓으로 취급합니다. null은 undefined과 같이 글로벌 객체의 속성에 대한 식별자가 아닙니다. 대신 null은 식별되지 않은 것을 표현합니다. 즉, 변수가 아무런 객체를 가리키지 않음을 표현합니다. API에서는 null을 종종 관련된 객체가 존재하지 않을 때 그 객체 대신 사용합니다.

ex)

// 정의되지 않고 초기화된 적도 없는 foo
foo; //ReferenceError: foo is not defined

// 존재하지만 값이나 자료형이 존재하지 않는 foo
var foo = null;
foo; //null

 

undefined란?

undefined는 원시값으로, 선언한 후 값을 할당하지 않은 변수 혹은 값이 주어지지 않은 인수에 자동으로 할당됩니다.

ex)

var x; // 값을 할당하지 않고 변수 선언

console.log("x's value is", x) // "x's value is undefined" 출력

 

null 과 undefined의 차이

typeof null          // "object" (하위호환 유지를 위해 "null"이 아님)
typeof undefined     // "undefined"
null === undefined   // false
null  == undefined   // true
null === null        // true
null == null         // true
!null                // true
isNaN(1 + null)      // false
isNaN(1 + undefined) // true

 

JavaScript 객체와 불변성이란 ?

  • 기본형 데이터와 참조형 데이터

데이터 타입의 종류는 두가지로 나눌 수 있는데, 기본형  타입(primitive Type)과 참조형 타입(Reference Type)두가지 로 나눌 수 있다. 

 

기본형(Primative Type)

객체가 아닌 데이터 유형 : Number, String, Boolean, Null, Undefined

- 기본형 데이터는 값을 그대로 할당하여 메모리상에 고정된 크기로 저장되며 원시 데이터 값 자체를 보관하므로 불변적이다. 

let a = 10;
let b = 0;

b = a;
a = 11;

console.log(a); //11
console.log(b); //10

b에 a를 넣으면 a 값이 변해도 b값은 변하지 않는다.

 

참조형(Reference Type)

객체 데이터 유형: Object, Array, Map, Function RegExp 등 

- 참조 타입은 변수에 할당 할 때 값이 아닌 데이터의 주소를 저장 

- const로 선언한 Object, Array에 데이터를 수정할 수 있는 것도 참조 타입이기 때문

- 참조형은 기본형 데이터의 집합이다. 참조형 데이터는 값이 지정된 주소값을 할당한다.

let object = {
  name: '윤영성',
  age: 26,
};

let object2 = {};

object2 = object;
object.gender = '남';

console.log(object); //{ name: '윤영성', age: 26, gender: '남' }
console.log(object2); //{ name: '윤영성', age: 26, gender: '남' }

 데이터를 직접 저장한 것이 아닌 주소만 참조한 것이기 때문에 참조된 객체 값이 변경되면 참조한 객체의 값도 같이 변경된다. 

 

  • JavaScript 형변환

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

obj끼리 더하거나 빼는 연산을 하거나 alert(obj)로 객체를 출력할 때는 자동 형 변환이 일어나게 된다. 

객체는 원시값으로 변환되고, 그 후 의도한 연산이 수행된다.

객체 형 변환은 세 종류로 구분되는데, 'hint'(목표로 하는 자료형 정도로 이해)라 불리는 값이 구분 기준이된다. 

 

"String"

alert 함수같이 문자열을 기대하는 연산을 수행할 때는(객체-문자형 변환), hint가 string이 됩니다.

// 객체를 출력하려고 함
alert(obj);

// 객체를 프로퍼티 키로 사용하고 있음
anotherObj[obj] = 123;

 

"number"

수학 연산을 적용하려 할 때(객체-숫자형 변환), hint는 number가 됩니다.

// 명시적 형 변환
let num = Number(obj);

// (이항 덧셈 연산을 제외한) 수학 연산
let n = +obj; // 단항 덧셈 연산
let delta = date1 - date2;

// 크고 작음 비교하기
let greater = user1 > user2;

 

 

"default"

연산자가 기대하는 자료형이 ‘확실치 않을 때’ hint는 default가 됩니다. 아주 드물게 발생합니다.

이항 덧셈 연산자 +는 피연산자의 자료형에 따라 문자열을 합치는 연산을 할 수도 있고 숫자를 더해주는 연산을 할 수도 있습니다. 따라서 +의 인수가 객체일 때는 hint가 default가 됩니다.

동등 연산자 ==를 사용해 객체-문자형, 객체-숫자형, 객체-심볼형끼리 비교할 때도, 객체를 어떤 자료형으로 바꿔야 할지 확신이 안 서므로 hint는 default가 됩니다.

 

// 이항 덧셈 연산은 hint로 `default`를 사용합니다.
let total = obj1 + obj2;

// obj == number 연산은 hint로 `default`를 사용합니다.
if (user == 1) { ... };

 

  • 불변 객체를 만드는 방법

불변 객체란? 

"변하지 않는 객체" 즉 이미 할당된 객체가 변하지 않는다는 뜻

 

const

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

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

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

객체의 내용이 변경되기 때문에 불변객체라고 하기는 힘들다.

이를 Object.freeze()라는 JS내장메소드를 통해 보완 할 수 있다.

 

Object.freeze()

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

let test = {
    name : 'kim'
}

Object.freeze(test);

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

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

Object.freeze()는 객체의 속성을 변경하는 시도는 불가능하지만, 객체의 재할당은 되는 모습을 볼 수 있다.

 

 

const + Object.freeze()

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

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

Object.freeze(test);

 

  • 얕은 복사와 깊은 복사

객체는 참조에 의해 할당되고 복사됩니다. 변수엔 ‘객체’ 자체가 아닌 메모리상의 주소인 '참조’가 저장됩니다. 따라서 객체가 할당된 변수를 복사하거나 함수의 인자로 넘길 땐 객체가 아닌 객체의 참조가 복사됩니다.

 

그리고 복사된 참조를 이용한 모든 작업(프로퍼티 추가·삭제 등)은 동일한 객체를 대상으로 이뤄집니다.

 

얕은 복사란?

const obj1 = { a: 1, b: 2};
const obj2 = obj1;

console.log( obj1 === obj2 ); // true

- 위의 예시처럼 객체를 직접 대입하는 경우 참조에 의한 할당이 이루어지므로 둘은 같은 데이터(주소)를 가지고 있다.

깊은 복사란?

참조값만 복사하는 것이 아닌 객체 자체를 복사하고 싶다면 어떻게 해야 할까?

1.새로운 객체를 만들어 다음 기존 객체의 프로퍼티들을 순회하여 원시 수준까지 프로퍼티를 복사한다.

let user = {
  name: "John",
  age: 30
};

let clone = {}; // 새로운 빈 객체

// 빈 객체에 user 프로퍼티 전부를 복사해 넣습니다.
for (let key in user) {
  clone[key] = user[key];
}

// 이제 clone은 완전히 독립적인 복제본이 되었습니다.
clone.name = "Pete"; // clone의 데이터를 변경합니다.

alert( user.name ); // 기존 객체에는 여전히 John이 있습니다.

 

2. Object.assign

let user = { name: "John" };

let permissions1 = { canView: true };
let permissions2 = { canEdit: true };

// permissions1과 permissions2의 프로퍼티를 user로 복사합니다.
Object.assign(user, permissions1, permissions2);

// now user = { name: "John", canView: true, canEdit: true }

반복문 없이도 간단하게 객체를 복사할 수 있다.

 

그러나 위 두 방법은 내부의 모든 프로퍼티가 원시값인 경우만 가정되어 있다. 그런데 프로퍼티가 다른 객체에 대한 참조 값일 수도 있다.즉 중첩되어 있는 객체는 복사하지 못한다.

 

이 문제를 해결하려면 user[key]의 각 값을 검사하면서, 그 값이 객체인 경우 객체의 구조도 복사해주는 반복문을 사용해야 합니다. 이런 방식을 '깊은 복사(deep cloning)'라고 합니다.

자바스크립트 라이브러리 lodash의 메서드인 _.cloneDeep(obj)을 사용하면 이 알고리즘을 직접 구현하지 않고도 깊은 복사를 처리할 수 있다.

let user = {
  name: "John",
  sizes: {
    height: 182,
    width: 50
  }
};

let clone = Object.assign({}, user);

alert( user.sizes === clone.sizes ); // true, 같은 객체입니다.

// user와 clone는 sizes를 공유합니다.
user.sizes.width++;       // 한 객체에서 프로퍼티를 변경합니다.
alert(clone.sizes.width); // 51, 다른 객체에서 변경 사항을 확인할 수 있습니다.

 

 

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

  • 스코프, 호이스팅, TDZ

scope란?

var x = 'global';

function foo () {
  var x = 'function scope';
  console.log(x);
}

foo(); // ?
console.log(x); // ?

이름이 같은 변수 x가 중복 선언되었다. 전역에서 변수 x를 참조할 때, 그리고 함수 foo 내부에서 변수 x를 참조할 때 이름이 중복된 2개의 변수 중 어떤 변수를 참조해야 하는가? 자바스크립트는 어떻게 변수를 식별하는 것일까?

 

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

 

프로그래밍은 변수를 선언하고 값을 할당하며 변수를 참조하는 기본적인 기능을 제공하며 이것으로 프로그램의 상태를 관리할 수 있다. 변수는 전역 또는 코드 블록(if, for, while, try/catch 등)이나 함수 내에 선언하며 코드 블록이나 함수는 중첩될 수 있다. 식별자는 자신이 어디에서 선언됐는지에 의해 자신이 유효한(다른 코드가 자신을 참조할 수 있는) 범위를 갖는다.

위 예제에서 전역에 선언된 변수 x는 어디에든 참조할 수 있다. 하지만 함수 foo 내에서 선언된 변수 x는 함수 foo 내부에서만 참조할 수 있고 함수 외부에서는 참조할 수 없다. 이러한 규칙을 스코프라고 한다.

 

만약 스코프가 없다면 어떻게 될까? 스코프가 없다면 같은 식별자 이름은 충돌을 일으키므로 프로그램 전체에서 하나밖에 사용할 수 없다. 디렉터리가 없는 컴퓨터를 생각해보자. 디렉터리가 없다면 같은 이름을 갖는 파일을 하나밖에 만들 수 없다. 스코프도 이와 같이 식별자 이름의 충돌을 방지한다.

 

스코프는 2가지로 나뉠 수 있다.

 

전역 스코프 (Global scope)

- 코드 어디에서든지 참조할 수 있다

 

- 지역 스코프 (Local scope or Function-level scope)

함수 코드 블록이 만든 스코프로 함수 자신과 하위 함수에서만 참조할 수 있다.

 

모든 변수는 스코프를 갖고, 변수의 관점에서 스코프를 구분하면 다음과 같이 나뉜다.

- 전역 변수 (Global variable)

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

- 지역 변수 (Local variable)

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

 

자바스크립트의 스코프는 타 언어와는 다른 특징을 가지고 있다.

int main(void) {
  // block-level scope
  if (1) {
    int x = 5;
    printf("x = %d\n", x);
  }

  printf("x = %d\n", x); // use of undeclared identifier 'x'

  return 0;
}

위처럼 C-family language는 블록 레벨 스코프를 따른다. 코드 블록{...}내에 유효한 스코프를 의미

 

하지만 자바스크립트는 함수 레벨 스코프(function-level scope)를 따른다. 함수 레벨 스코프란 함수 코드 블록 내에서 선언된 변수는 함수 코드 블록 내에서만 유효하고 함수 외부에서는 유효하지 않다(참조할 수 없다)는 것이다.

단, ECMAScript 6에서 도입된 let keyword를 사용하면 블록 레벨 스코프를 사용할 수 있다

 

 

호이스팅이란?

JavaScript에서 호이스팅(hoisting)이란, 인터프리터가 변수와 함수의 메모리 공간을 선언 전에 미리 할당하는 것을 의미합니다. var로 선언한 변수의 경우 호이스팅 시 undefined로 변수를 초기화합니다. 반면 let과 const로 선언한 변수의 경우 호이스팅 시 변수를 초기화하지 않습니다.

호이스팅을 설명할 땐 주로 "변수의 선언과 초기화를 분리한 후, 선언만 코드의 최상단으로 옮기는" 것으로 말하곤 합니다. 따라서 변수를 정의하는 코드보다 사용하는 코드가 앞서 등장할 수 있습니다. 다만 선언과 초기화를 함께 수행하는 경우, 선언 코드까지 실행해야 변수가 초기화된 상태가 됨을 주의하세요.

 

예제

JavaScript는 함수의 코드를 실행하기 전에 함수 선언에 대한 메모리부터 할당합니다. 덕분에 함수를 호출하는 코드를 함수 선언보다 앞서 배치할 수 있습니다. 예를 들어,

 

function catName(name) {
  console.log("제 고양이의 이름은 " + name + "입니다");
}

catName("호랑이");

/*
결과: "제 고양이의 이름은 호랑이입니다"
*/

위가 일반적인 코드를 작성하는 순서라면, 

 

catName("클로이");

function catName(name) {
  console.log("제 고양이의 이름은 " + name + "입니다");
}

/*
결과: "제 고양이의 이름은 클로이입니다"
*/

함수 호출이 함수 자체보다 앞서 존재하지만, 그럼에도 불구하고 이 코드 역시 동작합니다. 이것이 JavaScript에서 실행 맥락이 동작하는 방식입니다. 다른 자료형과 변수에도 호이스팅은 잘 작동 된다.

그리고 변수를 JavaScript는 초기화를 제외한 선언만 호이스팅한다.

console.log(num); // 호이스팅한 var 선언으로 인해 undefined 출력
var num; // 선언
num = 6; // 초기화

let과 const 호이스팅

let과 const로 선언한 변수도 호이스팅 대상이지만, var와 달리 호이스팅 시 undefined로 변수를 초기화하지는 않습니다. 따라서 변수의 초기화를 수행하기 전에 읽는 코드가 먼저 나타나면 예외가 발생합니다.

 

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

자바스크립트에서 함수 선언은 그 선언을 둘러싼 함수의 최상부나 전역 범위(global scope)로 끌어올려집니다.

hoisted(); // logs "foo"

function hoisted() {
  console.log("foo");
}

함수 표현식은 끌어올려지지 않으므로 주의하세요:

notHoisted(); // TypeError: notHoisted is not a function

var notHoisted = function() {
   console.log("bar");
};

 

  • 여러분이 많이 작성해온 let, const, var, function 이 어떤 원리로 실행되는지 알 수 있어요.

변수 

변수(variable)는 데이터를 저장할 때 쓰이는 ‘이름이 붙은 저장소’ 입니다. 

자바스크립트에선 let 키워드를 사용해 변수를 생성합니다.

 

let 

let message = 'Hello!'; // 변수를 정의하고 값을 할당합니다.

alert(message); // Hello!

- let으로 변수를 두 번 선언하면 에러가 발생한다.

let message = "This";

// 'let'을 반복하면 에러가 발생합니다.
let message = "That"; // SyntaxError: 'message' has already been declared

 

만들어진 지 오래된 스크립트에서 let 대신 var라는 키워드를 발견하는 경우가 있습니다

 

var

var message = 'Hello';

- var는 블록 스코프가 없습니다.

- var로 선언한 변수의 스코프는 함수 스코프이거나 전역 스코프입니다. 블록 기준으로 스코프가 생기지 않기 때문에 블록 밖에서 접근 가능합니다.

- 한 스코프에서 같은 변수를 let으로 두 번 선언하면 에러가 발생합니다. var로 같은 변수를 여러 번 중복으로 선언할 수 있습니다. 하지만 이미 선언된 변수에 var를 사용하면 두 번째 선언문은 무시됩니다.

var user = "Pete";

var user = "John"; // 이 "var"는 아무것도 하지 않습니다(이전에 이미 선언됨).
// ...에러 또한 발생하지 않습니다.

alert(user); // John

- var 선언은 함수가 시작될 때 처리됩니다. 전역에서 선언한 변수라면 스크립트가 시작될 때 처리되죠.

function sayHi() {
  phrase = "Hello";

  alert(phrase);

  var phrase;
}
sayHi();

- 선언은 호이스팅 되지만 할당은 호이스팅 되지 않습니다.

function sayHi() {
  alert(phrase);

  var phrase = "Hello";
}

sayHi();

 

상수

변화하지 않는 변수를 선언할 땐, let 대신 const를 사용합니다.

const myBirthday = '18.04.1982';

이렇게 const로 선언한 변수를 '상수(constant)'라고 부릅니다. 상수는 재할당할 수 없으므로 상수를 변경하려고 하면 에러가 발생합니다.

const myBirthday = '18.04.1982';

myBirthday = '01.01.2001'; // error, can't reassign the constant!

변숫값이 절대 변경되지 않을 것이라 확신하면, 값이 변경되는 것을 방지하면서 다른 개발자들에게 이 변수는 상수라는 것을 알리기 위해 const를 사용해 변수를 선언하도록 합시다.

 

대문자 상수

기억하기 힘든 값을 변수에 할당해 별칭으로 사용하는 것은 널리 사용되는 관습입니다.

const COLOR_RED = "#F00";
const COLOR_GREEN = "#0F0";
const COLOR_BLUE = "#00F";
const COLOR_ORANGE = "#FF7F00";

// 색상을 고르고 싶을 때 별칭을 사용할 수 있게 되었습니다.
let color = COLOR_ORANGE;
alert(color); // #FF7F00

 

  • 실행 컨텍스트와 콜 스택

Excution context(실행 컨텍스트)

자바스크립트 코드가 실행되는 환경을 의미한다.
자바스크립트에서 대표적으로 두 가지 타입의 Execution context가 있다.

실행할 코드에 제공할 환경 정보들을 모아놓은 객체들로
자바스크립트의 동적 언어로서의 성격을 가장 잘 파악할 수 있는 개념이다.

  1. Global Execution context
    자바스크립트 엔진이 처음 코드를 실행할 때 Global Execution Context가 생성된다. 생성 과정에서 전역 객체인 Window Object (Node는 Global) 를 생성하고 this가 Window 객체를 가리키도록 한다.
  2. Function Execution context
    자바스크립트 엔진은 함수가 호출 될 때마다 호출 된 함수를 위한 Execution Context를 생성한다.
    모든 함수는 호출되는 시점에 자신만의 Execution Context를 가진다.

자바스크립트는 실행 컨텍스트가 활성화되는 시점에 다음과 같은 현상이 발생한다.

 

- 호이스팅이 발생한다(선언된 변수를 위로 끌어올린다)

- 외부 환경 정보를 구성한다.

- this 값을 설정한다.

 

 

Call stack

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

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

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

자바스크립트 엔진은 Call Stack의 Top에 위치한 함수를 실행하며 함수가 종료되면 stack에서 제거(pop)하고 제어를 다음 Top에 위치한 함수로 이동한다.

1줄 요약 : 프로그램이 함수 호출을 추적할때 사용한다.

 

 

  • 스코프 체인, 변수 은닉화

스코프 체인(Scope Chain)

스코프는 함수의 중첩에 의해 계층적 구조를 가진다.

변수를 참조할 때, 자바스크립트 엔진은 스코프 체인을 통해 변수를 참조하는 코드의 스코프에서 시작하여 상위 스코프로 이동하면서 선언된 변수를 검색한다.

스코프 체인은 outerEnvironmentReference와 밀접한 관계를 가진다.

💡 스코프 체인은 실행 컨텍스트의 렉시컬 환경을 '단방향'으로 연결한 링크드 리스트

 

변수 은닉화(variable shadowing)

여러 스코프에서 동일한 식별자를 선언한 경우, 무조건 스코프 체인 상에서 가장 먼저 검색된 식별자에만 접근이 가능하다.

(function s(){
let a = 'hi'
})() //a is not defined

즉, 직접적으로 변경되면 안되는 변수에 대한 접근을 막는것이다.

function hello(name) {
  let _name = name;
  return function () {
    console.log('Hello, ' + _name);
  };
}

let a = new hello('영서');
let b = new hello('아름');

a() //Hello, 영서
b() //Hello, 아름

이렇게 a와 b라는 클로저를 생성하면 함수 내부적으로 접근이 가능하다.

참고자료

https://ko.javascript.info/intro

 

자바스크립트란?

 

ko.javascript.info

https://developer.mozilla.org/ko/docs/Web/JavaScript/Data_structures

 

JavaScript의 타입과 자료구조 - JavaScript | MDN

모든 프로그래밍 언어에는 내장된 자료구조가 존재하지만 보통 그 내용은 언어마다 다릅니다. 이 글에서는 JavaScript에서 사용할 수 있는 내장 자료구조와 그 속성에 대해 알아보겠습니다. 그러

developer.mozilla.org

https://velog.io/@mmzgpgp/JavaScript%EC%9D%98-%EC%9E%90%EB%A3%8C%ED%98%95%EA%B3%BC-JavaScript%EB%A7%8C%EC%9D%98-%ED%8A%B9%EC%84%B1%EC%9D%80-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C

 

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

정적 언어란 컴파일 시간에 변수의 타입이 결정되는 언어입니다. 타입 즉, 자료형을 런타임 이전에 결정하는 것입니다. 대표적인 정적 언어로는 C, C++, Java 등이 있습니다.정적 언어는 변수에 들

velog.io

https://velog.io/@yunsungyang-omc/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EA%B8%B0%EB%B3%B8%ED%98%95%EA%B3%BC-%EC%B0%B8%EC%A1%B0%ED%98%95

 

자바스크립트 기본형과 참조형

자바스크립트의 데이터 타입의 종류와 차이점

velog.io

https://velog.io/@lilclown/Javascript-%EA%B8%B0%EB%B3%B8%ED%98%95-%EC%B0%B8%EC%A1%B0%ED%98%95

 

[Javascript] 기본형, 참조형

[Javascript] 기본형, 참조형

velog.io

https://spiderwebcoding.tistory.com/8#:~:text='%EB%B3%80%ED%95%98%EC%A7%80%20%EC%95%8A%EB%8A%94%20%EA%B0%9D%EC%B2%B4'%20%EC%A6%89%20%EC%9D%B4%EB%AF%B8,()%EB%A5%BC%20%EC%82%AC%EC%9A%A9%ED%95%98%EB%8A%94%20%EA%B2%83%EC%9D%B4%EB%8B%A4.&text=%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%20%ED%82%A4%EC%9B%8C%EB%93%9C%20%EC%A4%91%20%ED%95%98%EB%82%98%EC%9D%B8%20const%EC%9D%B4%EB%8B%A4. 

 

[JavaScript] 불변 객체 만들기(const, Object.freeze())

개요 카카오 코딩테스트 문제를 풀다가 임의 객체 A를 배열B에 Push한 후 객체 A의 내용을 바꿨는데 배열B에 Push 되어 있던 객체 값이 바뀐 결과가 발생했다. 이 때 나는 배열에 push한 값은 value로

spiderwebcoding.tistory.com

https://hanamon.kr/javascript-shallow-copy-deep-copy/

 

[JavaScript] 얕은 복사(shallow copy) vs 깊은 복사(deep copy) - 하나몬

💡 얕은 복사(shallow copy) vs 깊은 복사(deep copy) ❗️얕은 복사(shallow copy)란? const obj1 = { a: 1, b: 2}; const obj2 = obj1; console.log( obj1 === obj2 ); // true 위의 예시처럼 객체를 직접 대입하는 경우 참조에 의

hanamon.kr

https://poiemaweb.com/js-scope

 

Scope | PoiemaWeb

스코프는 참조 대상 식별자(identifier, 변수, 함수의 이름과 같이 어떤 대상을 다른 대상과 식별할 수 있는 유일한 이름)를 찾아내기 위한 규칙으로 자바스크립트는 이 규칙대로 식별자를 찾는다.

poiemaweb.com

https://velog.io/@mincho/%EC%8B%A4%ED%96%89-%EC%BB%A8%ED%85%8D%EC%8A%A4%ED%8A%B8%EC%99%80-%EC%BD%9C-%EC%8A%A4%ED%83%9D

 

실행 컨텍스트와 콜 스택

Execution context(실행 컨텍스트) 자바스크립트 코드가 실행되는 환경을 의미한다. 자바스크립트에서 대표적으로 두 가지 타입의 Execution context가 있다. 실행할 코드에 제공할 환경 정보들을 모아놓

velog.io

 

1. 웹개발 프로젝트 마지막 정리

2. 최종 발표 및 회고 

 

 우선 그동안 못한 1~3일차까지의 이야기를 하자면

처음 1일차부터 웹개발 플러스 강의를 듣고, 그것을 기반으로 팀프로젝트를 하게 되었다. 

나 포함 총 4명이었고, 팀 분위기는 좋았다. 

 

 다들 처음이라 시작을 어떻게 해야하는지 갈팡질팡하고 있었고 나또한 그랬다. 

우선 배포된 강의를 듣기로 하고 와이어프레임으로 구상한대로 각자 페이지를 맡아 기능 구현을 하기로 했다. 

내가 팀장이었지만, 나 또한 부족한게 많았기 때문에 팀원들에게 도움을 받은것도 많았고, 도움을 줬던것도 있었다. 

팀프로젝트를 시작할 때, 깃과 깃헙을 이용해서 하면 수월한데 성민님 빼고 어려워했다. 

나는 항해에 참여하기전에 노마드코더를 통해 깃헙데스크탑으로 어느정도 숙지하고 갔기 때문에 가능은 했는데, 업무에서 능숙하게 활용하기 위해서는 아직 배울게 많다는 것을 느꼈다. 

 

우선은 깃을 사용하는것을 미루고 그냥 깃헙에서 손수 수정하기로 했다.

맡은 페이지를 만들기 시작했고, 서로 오류난것들을 공유하고 해결해나가면서 어느정도 구현이 되었다. 

그 후 합치고 배포하는 일을 하였다.

 

 이 과정에서 느낀것은 개발에서 환경설정하는것이 시간도 많이들고 번거롭고 힘들다?정도는 알고 있었는데 생각보다 더 힘들었던거 같다.

웹개발 플러스 강의가 만든지 좀 된 것 같기도 하지만, 잘안되는 오류들을 찾아보면서 알게되거나 리마인드된것도 있는것 같다. 

 

 ex) mongodb에서 db에서 find할때 id값으로 찾는데 이 id값을 objectId 처리 하는것을 이미 wetube 클론코딩에서 들어서 알고 있었지만, 당시에 오류가 떳을때는 전혀 몰랐다. 그런데 에러메시지를 통해 오류의 원인을 찾아가는 과정에서 기억이나게되고 비교적 금방 해결할 수 있던것 같다. 

 

 처음 다인 프로젝트를 해봤는데, 늘 혼자서 공부하다가 다같이 공부하고 배운것을 이용하는 경험은 더 동기부여가 되고, 책임감과 압박감을 주는 것 같다. 나한테는 이 스트레스가 나쁜것보다 좋은 방향으로, 성장하는 방향으로 작용하는 것 같아 기분이 좋은 느낌도 받았다. 

 

기술적인 부분을 조금 작성해보자면 

우리는 풀스택 미니 프로젝트를 한 것이다. 

flask를 이용하여 서버를 만들고, 셀레니움을 이용하여 유기동물보호소의 data를 mongodb에 저장해서 연결하고, jinja2를 이용해 SSR을 하고, ajax를 통해 비동기 통신을 하였다. 

https://github.com/SpartaClassD2Jo/FindHand

 

GitHub - SpartaClassD2Jo/FindHand

Contribute to SpartaClassD2Jo/FindHand development by creating an account on GitHub.

github.com

협력해서 만들었다는 점이 뿌듯하지만, 아쉬운점은 기획했던 기능들을 전부 다 구현하지 못했다는 것이다. 

아쉬운 기능들은, 검색기능, 좋아요기능, 프로필페이지에 대쉬보드를 만들어 저장한 동물들을 모아 볼 수 있는 기능.. 등등 

나중에 토이프로젝트로 혼자서 만들 수 있을 것 같아 시간이 나면 시도해보도록 하겠다. 

JWT를 이용하여 로그인을 구현하는 부분이 있는데, 이부분이 맡은 부분이 아니고, 프로젝트 완성에 집중하느라 내가 맡은 페이지와 도움을 주는데에 시간을 많이 썼다. 그래서 JWT는 복습을 하는 시간을 가져야겠다고 생각했다.

 

오늘은 이번 프로젝트를 마무리하고, 내일 새로운 발제를 받게된다.

다음 커리큘럼은 알고리즘 기초라고 하는데, 담임매니저님께서는 그런것보다 반복문, 조건문등에 좀 더 친숙해지고, 능숙하게 사용하기 위한 기간이라고 들었다. 

 

우선 조원들도 다 착하고, 서로 협력하려하는 마음가짐을 갖고 있어서 좋았다. 다음에 만날 조도 좋은 팀원들을 만나 한층더 성장하고 경험을 쌓았으면 좋겠다. 

 

개선할점

1. 트러블슈팅 내역 기록  

2. 나름 적극적으로 한다고 했지만, 내 기준에서는 아직 수동적으로 움직이는 것 같다.

   - 좀 더 resourcefulness한 사람이 되도록 하자.

3. JS 문법 공부

  - 이번프로젝트 때, jqeury를 써서 크게 걸린점은 없었지만, 앞으로 알고리즘 주차를 위해 

4. 프로젝트의 진행사항을 어느정도 기록해놓자.

  

 

 

 

 

 

 

 

1주차 강의의 html 과 css에 관한 부분은 이미 어느정도 아는 내용이었다. 

그러나 그동안 다른 강의를 듣느라 조금 잊어버린 부분도 있었고, 새로 알게된 것도 있었다. 

 

강의내용

우선 html에 각 태그들의 쓰임새에 대해 배울 수 있었다.

또한 class를 통해 css를 이용할때 지정하여 꾸밀 수 있다는 것을 배운다.

 

부트스트랩 사용법에대해서도 배우는데

이름만 알고 사용법을 몰랐는데, 사용해보면서 빠른 제작을 위해 사용하면 좋을 것 같다고 생각했고, 굉장히 간편했던 것 같다. 

 

+ Recent posts