Back to the Basics

[JS/Node][Codestates] 핵심 개념과 주요 문법 - lesson1 본문

Programming Languages/JavaScript & Node.js

[JS/Node][Codestates] 핵심 개념과 주요 문법 - lesson1

9Jaeng 2021. 7. 19. 20:26
728x90

1. 원시 자료형과 참조 자료형

Achievement Goals

  • 원시 자료형과(primary type) 과 참조 자료형(Reference Type)의 구분이 왜 필요한지에 대해 이해할 수 있다.
  • 원시 자료형과 참조 자료형의 차이를 이해하고, 사용할 수 있다.
  • 원시 자료형이 할당될 때에는 변수에 값(value) 자체가 담기고, 참조 자료형이 할당될 때에는 보관함의 주소(Reference) 가 담기는 개념을 코드로 설명할 수 있다.
  • 참조 자료형은 기존에 고정된 크기의 공간을 사용하는 것이 아니라, 동적으로 변하는 공간을 사용함을 이해할 수 있다.

원시자료형, 참조 자료형

  1. 원시 자료형 (primitive data type)
  • Stack에 저장된다.
  • 각 변수 간 원시타입 데이버를 복사항 경우 데이터 값이 복사되기 때문에 기존 값에 영향이 없다.
    a=10; a=b ; b // 10
  • 모두 고정된 저장 공간을 차지하는 하나의 정보들이다.
  • 변수 하나당 하나의 데이터만 할당이 가능하다 (let a='string')
  • javascript 에서 primitive data type 은 객체가 아니면서 method를 가지지 않는 6가지 타입
    string, number,bigint, boolean, undefined, symbole, null 을 갖는다.
    • 원시 자료형은 "하나"의 의미를 가지는 데이터이므로 원시자료형의 공간의 크기는 고정하는 것이 합당하다.
    • 원시 자료형은 값 자체에 대한 변경이 불가능(immutable)하지만, 변수에 다른 데이터를 담을 수는 있다
      let a="Hello World"는 모두 변경 할 수 있는 고정값이다.
      a[1]="K" --> 불가능
    • 원시 자료형은 주소값을 전달하는 것이 아니라 값 자체를 복사하여 전달한다.
    let score=80;
    function doStuff(value){
    value=90;
    }
    doStuff(score);
    //80
    score의 값 80은 참조 자료형이 아니기 때문에 주소값을 전달하지 않고, 값 자체를 복사하여 전달한다. 따라서 score에는 초기에 할당된 값인 80이 그대로 유지된다.

* Self-Guided Lesson *

  • symbol :ES6에서 새롭게 추가된 7번째 타입으로 변경이 불가능한 원시 타입의 값이다. 심볼은 주로 이름의 충돌 위험이 없는
    유일한 객체의 propery key를 만들기 위해 사용한다 출처 : https://poiemaweb.com/es6-symbol
  • bigint : The BigInt type is a numeric primitive in JavaScript that can represent integers with arbitrary precision. With BigInts, you can safely store and operate on large integers even beyond the safe integer limit for Numbers.(MDN)
  1. 참조 자료형 (Reference
  • javasctipt에서 원시 자료형이 아닌 모든 것은 참조 자료형 이다.
  • 대표적으로 Array, Object, Function이 있다.
  • 변수에 넣을 수 있는 데이터의 크기가 제한되었기 때문에 동적으로 데이터의 크기가 변하는 배열와 같은 자료구조의 구현이 필요했다.
  • Stack에 변수 a라는 이름을 갖는 공간에 heep 주소값을 저장한다. 주소를 참조하여 힙에 접근하므로 동적 입력이 가능하다.--> 주소가 들어가기 때문에 reference type 이라고 한다.
  • 참조 자료형은 주소를 복사하게 되므로, 기존의 값이 변경된다.
  • 참조 자료형을 변수에 할당 할 때는 변수에 값이 아닌 주소를 저장하므로 여러 가지 변수를 담을 수 있다.
  • 참조 자료형의 '===' (strict equality)는 주소값이 같은지를 확인한다.

2. 스코프(Scope)

Scope : 변수의 유효범위

Achievement Gials

  • 스코프의 의미와 적용 범위를 이해할 수 있다.
  • 스코프의 주요 규칙을 이애할 수 있다.
    • 중첩 규칙
    • 전역 스코프와 지역 스코프
    • 전역 변수와 지역 변수 간의 우선순위
    • let, const, var의 차이
    • 전역 객체(window)의 이해

스코프와 주요 규칙

  • Scope 의 정의 : 변수 접근 규칙에 따른 유효 범위
  • 첫 번째 규칙 : 바깥쪽 스코프에서 선언한 변수는 안쪽 스코프에서 사용이 가능하지만 안쪽에서 선언된 변수는 바깥쪽 스코프에서 사용이 불가능하다.

아래 코드를 보고 이해를 해보자

let username='sora';
if(username){
  let message=`Hi, $(username)!`;
  console.log((message);
              }
console.log(message);

첫 번째 console.log 결과 :"Hi sora!"
두 번째 console.log 결과 : ReferenceError
위의 코드에서 if { } 로 감싸져 있는 if 문이 안쪽 스코프 , if 을 뺀 나머지가 바깥 스코프이기 때문에 두 번째 console.log 에서 참조 애러가 발생하게 된다.

  • 두 번째 규칙 : 스코프는 중첩이 가능하다.
    • 가장 바깥쪽의 스코프는 전역(Global) 스코프라고 부른다.
    • 전역이 아닌 다른 스코프는 전부 지역(local scope)이다.
    • 지역 스코프에 선언한 변수는 지역 변수, 전역 스코프에 선언한 변수는 전역 변수이다.

  • 세 번째 규칙 : 지역 변수는 전역 변수보다 더 높은 우선순위를 가진다.

아래의 코드를 통해 확인해보자

1) 지역 스코프에서 let 키워드로 지역변수를 선언했을 경우

  • 스코츠 규칙에 의해 첫 번째 출력은 전역 변수로 선언된 name을 출력한다. 두 번째 출력은 전역 변수와 이름이 같지만, ** 지역 변수가 전역 변수보다 우선순위가 높으므로 ** 지역 변수의 name을 출력한다.
  • 이와 같이 동일한 변수 이름으로 인해 바깥쪽 변수가 안쪽 변수에 의해 가려지는 현상을 쉐도잉(variable shadowing) 이라고 한다.
let name='kangcoding';

function showName() {
  let name='eoheacker'; // 지역 변수
  console.log(name) // 두번째 출력
}
console.log(name); // 첫번쨔 출력
showName();
console.log(name); // 세번째 출력

// kangcoding
// eoheacker
// kangcoding

2) 지역 스코프에서 let 키워드로 선언하지 않았을 경우

  • let 으로 지역 스코프에서 변수를 선언하지 않았을 경우엔 전역 변수를 사용한다.
let name='kangcoding';

function showName() {
  name='eoheacker'; // 지역 변수
  console.log(name) // 두번째 출력
}
console.log(name); // 첫번쨔 출력
showName();
console.log(name); // 세번째 출력

// kangcoding
// eoheacker
// eoheacker

스코프의 종류와 let, const, var

스코프의 종류

스코프는 개발자 입장에서 유효범위 이다.

1) block scope : 블록 스코프

  • 중괄호를 기준으로 범위가 구분된다.
if(true){
  console.log('i am in the block');
}
for(let i=0;i<0;i++){
  console.log(i);
} // i는 중괄호 안에서만 사용이 가능하다
{
  consolg.log('it works');
}

2) 함수로 둘러싼 범위(function scope: 함수 스코프)

함수 선언식 및 함수 표현식은 함수 스코프를 만든다. (function 키워드를 사용하면 ** 함수 스코프 ** 이다)

function getName(user){
  return user.name;
}
let getAge=function(user){
  return user.age;
}

3) 화살표 함수로 둘러싼 범위(block scope: 블록 스코프)

화살표 함수는 함수 스코프가 아닌 블록 스코프로 취급된다.

let getAge=user =>{
  return user.age;
}

let, var 키워드

  • var 키워드는 블록 스코프를 무시하고, 함수 스코프만 따른다. (화살표 함수의 블록 스코프는 따른다)
  • 블록 단위로 스코프를 구분했을 때 예측 가능한 코드를 작성하기 위해 let 키워드의 사용이 권장된다.
    • var를 사용하지 않아도 함수 스코프는 let으로 선언된 변수의 접은 범위를 제한한다.
    • 보통 블록 기준으로 코드를 작성하므로 var 키워드는 다소 복잡해질 수 있다.
    • var 키워드는 재선언을 해도 아무런 error도 내지 않지만 let 키워드는 재선언을 방지한다.

const 키워드

  • 값이 변하지 않는 상수(constant)를 정의할 때 const를 사용한다.
  • let 키워드와 동일하게 블록 스코프를 따른다.
  • 값의 변경을 최소화하여 보다 안전한 프로그램을 만들 수 있기 때문에 const 키워드 사용이 권장된다
  • 값을 재할당 하는 경우 typeError를 내기 때문에 의도하지 않은 값의 변경을 막을 수 있다. --> 많이 쓰이는 이유이다.

변수 선언에서 주의할 점

(1) window 객체(브라우저 only)

var로 선언된 전역 변수 및 전역 함수는 window 객체에 속하게 된다.

  • window 객체란 브라우저 창을 의미하는 객체이다.
  • 브라우저 창과 관계없이 전역 항목도 담고 있다.
  • var 로 선언된 전역 변수와 전역 함수가 window 객체에 속한다.
var myName='sora kang';
console.log(window.myname); // sora kang

function foo() {
  console.log('bar');
}
console.log(foo===window.foo); //true
  • window 를 콘솔에 입력하면 아래와 같이 확인할 수 있다.

(2) 전역 변수는 최소화하자

전역 변수에 너무 많은 변수를 선언하지 말자

  • 전역 변수는 가장 바깥 스코프에 정의한 변수이므로 어디서든 접근이 가능하다.
  • 편리하지만 다른 함수 혹은 로직에 의해 의도되지 않은 변경이 발생할 수 있다.
    • side effect(부수 효과) 발생

(3) let, cons를 주로 사용하자

  • 이는 같은 스코프에서 동일한 이름의 변수를 재선 언 하여 버그를 유발할 수 있다
  • 전역 변수를 var로 선언하는 경우 문제가 발생할 수 있다*
  • var로 선언한 전역 변수가 window 기능을 덮어씌워서 내장 기능을 사용할 수 없게 만들 수 있다.

  • ** var는 블록 스코프를 무시하며, 재선언을 해도 Error를 내지 않는다.

(4) 선언 없는 변수 할당 금지

선언 키워드 let, const, var 없이 변수를 할당하면 안 된다.

  • 변수는 var로 선언한 전역 변수처럼 취급된다.

실수를 방지하기 위해 Strict Mode를 사용할 수 있다.

Checkpoint

스코프에 대해 더 이해하기 위해 아래의 문제를 풀어보자.

let x = 10;

function add (y) {
  return x + y;
}

function strangeAdd (x) {
  return add(x) + add(x);
}

let result = strangeAdd(5);


// result 는  15+15 = 30이 된다.
  • result는 strangeAdd 함수를 호출하고있고 매개별수의 값으로 5를 전달한다.
  • strangeAdd 함수의 definition 부분을 보면, 두 개의 add 함수를 호출하고 서로 덧샘 연산을 진행한 결과를 return 한다.
  • add 함수이 definition 부분을 보면, 매개변수 y와 전역변수 x를 더한 앖을 return 한다,
  • 즉, strangeAdd(5) = add(5) + add(5) = (10 + 5 ) + (10 + 5) 가 되어 최종 값은 30이 된다.
728x90
Comments