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

Eddy·2022년 7월 20일
1

Javascript

목록 보기
1/27
post-thumbnail

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

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

느슨한 타입이 무엇인지 느슨한 타입이 아닌 것은 무엇인지 둘 다 이해하는 것이 중요하다. 느슨한 타입은 타입 없이 변수를 선언하는 것이다. 반면에 강력한 타입(strong typing)을 사용하는 언어는 타입과 함께 변수를 선언해야만 한다. 다음의 예제를 살펴보자.

JavaScript 예제에서 a와 b 둘 다 var type으로 선언되었다는 걸 기억하자. 하지만 이것이 타입이 없다거나 var 타입이라는 뜻은 아니다. JavaScript의 변수는 타입을 가지고 있지만, 내부적으로 정해질 뿐이다. 위의 예제에서는, a의 타입은 Number, b의 타입은 String이 될 것이다. JavaScript는 모두 5개의 Primitive type을 가지고 있는데 위의 둘과 Boolean, Null, Undefined이다.

이와 같이 JavaScript의 변수는 어떤 특정 타입과 연결되지 않으며, 모든 타입의 값으로 할당 (및 재할당) 가능하다. 이것이 바로 동적 언어의 특징이다.


📎 정적언어와 동적언어의 차이

📌 정적 언어

  • 정적 언어란 컴파일 시간에 변수의 타입이 결정되는 언어. 타입 즉, 자료형을 런타임 이전에 결정하는 것이다. 대표적인 정적 언어로는 C, C++, Java 등이 있다.
  • 정적 언어는 변수에 들어갈 값의 형태에 따라 자료형을 지정해주어야 한다.
  • 컴파일 시에 자료형에 맞지 않는 값이 들어있을 경우 컴파일 에러가 발생한다. 만약 Type Error이 발생할 코드가 있다면 컴파일 하는 과정에서 오류를 출력한다.
  • 컴파일 시간에 변수의 타입을 체크하므로 사소한 버그들을 쉽게 체크할 수 있는 장점이 있다.
    즉 타입 에러로 인한 문제점을 초기에 발견할 수 있어 타입의 안정성이 올라간다.

📌 동적 언어

  • 런타임에 비로소 타입이 결정되는 언어. 소스가 컴파일, 빌드될 때 자료형을 결정하는 것이 아니라 실행할 때 결정된다. 언어 자체에서 타입을 추론해서 형을 변환해 주며 대표적인 동적 언어로는 JavaScript, Ruby, Python 등이 있다.
  • 변수를 생성할 때 마다 매번 타입을 써줄 필요가 없기 때문에 기본적으로는 편하고 빠르게 코드를 작성하기 좋다.
  • 하지만 실행 도중에 변수에 예상치 못한 타입이 들어와 Type Error가 발생하는 경우가 생길 수 있다. 정적 언어와 달리 실행되는 시점에서 오류를 출력한다. 특히 프로젝트의 크기가 크거나 협업을 하는 과정에서 변수의 타입이 일치하지 않는 경우가 생길 수 있으므로 주의를 기울여야 한다.
  • 자바스크립트가 가진 동적 언어의 단점을 보완하는 방법으로는 TypeScript를 사용하는 방법이 있다. 타입스크립트란 자바스크립트에서 코드를 입력할 때 타입을 미리 부여하는 기능을 추가한 정적 타입 언어이다.

📎 자바스크립트의 형변환

함수와 연산자에 전달되는 값은 대부분 적절한 자료형으로 자동 변환됩니다. 이런 과정을 "형 변환(type conversion)"이라고 합니다.
alert가 전달받은 값의 자료형과 관계없이 이를 문자열로 자동 변환하여 보여주는 것이나, 수학 관련 연산자가 전달받은 값을 숫자로 변환하는 경우가 형 변환의 대표적인 예시입니다.
이 외에, 전달받은 값을 의도를 갖고 원하는 타입으로 변환(명시적 변환)해 주는 경우도 형 변환이라고 할 수 있습니다.

📌 문자형으로 변환

문자형으로의 형 변환은 문자형의 값이 필요할 때 일어납니다.
alert메서드는 매개변수로 문자형을 받기 때문에, alert(value)에서 value는 문자형이어야 합니다. 만약, 다른 형의 값을 전달받으면 이 값은 문자형으로 자동 변환됩니다.
String(value) 함수를 호출해 전달받은 값을 문자열로 변환 할 수도 있습니다.

false는 문자열 "false"로, null은 문자열 "null"로 변환되는 것과 같이, 문자형으로의 변환은 대부분 예측 가능한 방식으로 일어납니다.

📌 숫자형으로 변환

숫자형으로의 변환은 수학과 관련된 함수와 표현식에서 자동으로 일어납니다.
숫자형이 아닌 값에 나누기 /를 적용한 경우와 같이 말이죠.

Number(value) 함수를 사용하면 주어진 값(value)을 숫자형으로 명시해서 변환할 수 있습니다.

숫자형 값를 사용해 무언가를 하려고 하는데 그 값을 문자 기반 폼(form)을 통해 입력받는 경우엔, 이런 명시적 형 변환이 필수입니다.
한편, 숫자 이외의 글자가 들어가 있는 문자열을 숫자형으로 변환하려고 하면, 그 결과는 NaN이 됩니다. 예시를 살펴봅시다.

아래는 숫자형으로 변환 시 적용되는 규칙입니다.

  • 예시

    null과 undefined은 숫자형으로 변환 시 결과가 다르다는 점에 유의하시기 바랍니다. null은 0이 되고 undefined는 NaN이 됩니다.

📌 불린형으로 변환

불린형으로의 변환은 아주 간단합니다.
이 형 변환은 논리 연산을 수행할 때 발생합니다(논리 연산에 관한 내용은 뒤 챕터에서 다루고 있습니다). Boolean(value)를 호출하면 명시적으로 불리언으로의 형 변환을 수행할 수 있습니다.
불린형으로 변환 시 적용되는 규칙은 다음과 같습니다.

1.숫자 0, 빈 문자열, null, undefined, NaN과 같이 직관적으로도 “비어있다고” 느껴지는 값들은 false가 됩니다.
2.그 외의 값은 true로 변환됩니다.

📌 요약

문자, 숫자, 논리형으로의 형 변환은 자주 일어나는 형 변환입니다.
문자형으로 변환 은 무언가를 출력할 때 주로 일어납니다. String(value)을 사용하면 문자형으로 명시적 변환이 가능합니다. 원시 자료형을 문자형으로 변환할 땐, 대부분 그 결과를 예상할 수 있을 정도로 명시적인 방식으로 일어납니다.
숫자형으로 변환 은 수학 관련 연산시 주로 일어납니다. Number(value)로도 형 변환을 할 수 있습니다.
숫자형으로의 변환은 다음 규칙을 따릅니다.
불린형으로 변환 은 논리 연산 시 발생합니다. Boolean(value)으로도 변환할 수 있습니다.
불린형으로의 형 변환은 다음 규칙을 따릅니다.
형 변환 시 적용되는 규칙 대부분은 이해하고 기억하기 쉬운 편에 속합니다. 다만 아래는 예외적인 경우이기 때문에 실수를 방지하기 위해 따로 기억해 두도록 합시다.
1.숫자형으로 변환 시 undefined는 0이 아니라 NaN이 됩니다.
2.문자열 "0"과 " "같은 공백은 불린형으로 변환 시 true가 됩니다.


📎 == , ===

📌 ==

JavaScript는 타입 변환에 대해 유연하게 동작합니다.
== 연산자는 두 피연산자의 값의 타입이 다를 경우 자동으로 일부 피연산자의 타입을 변환 후 값을 비교합니다.
타입을 비교하지 않으므로 === 연산자에 비해 느슨하다고 할 수 있습니다.

10 == '10'
두 피연산에서 하나가 숫자형이고 다른 하나가 문자열이면, 문자열을 숫자로 변환 후 값을 비교합니다. 
true == 1
두 피연산자에서 불리언 값이 존재하면, 불리언 값을 1로 변환 후 값을 비교합니다.
true == '1'
불리언 값을 1로 변환하면, 1 == '1'이 되는데, 문자열 '1'을 숫자로 변환 후 값을 비교합니다.
즉, 1 == 1로 비교되며, true를 반환합니다.
ture == 'true'
불리언 값을 1로 변환하면, 1 == 'true'가 되는데, 문자열 'true'는 숫자로 변환 불가능합니다.
즉, 1 == 'true'로 비교되며, false를 반환합니다.
null == undefined
null과 undefined는 엄연히 다르지만, == 연산자는 true를 반환합니다.

📌 ===

== 연산자는 값을 비교하기 전에 타입이 다를 경우 타입을 변환 후 값을 비교하였습니다. 
하지만, === 연산자는 타입을 변환하지 않으므로 == 연산자에 비해 비교하는 방식이 엄격합니다.
즉, === 연산자는 타입이 다르면, false를 반환합니다.

  • === 연산자의 특징
    NaN 값은 자기 자신을 포함하여 어떠한 값과도 일치하지 않습니다. 즉, === 연산자에 NaN 값이 존재하는 경우 항상 false입니다.
    정확한 문자열을 비교하기 위해서는 localeCompare 메서드를 사용하는 것이 좋습니다. 문자열은 눈으로 보았을 때, 동일하더라도 인코딩 방식이 다르게 되어있을 수 있기 때문입니다.

📎 undefined와 null

📌 undefined

undefined은 변수를 선언하고 값을 할당하지 않은 상태, null은 변수를 선언하고 빈 값을 할당한 상태(빈 객체)이다. 즉, undefined는 자료형이 없는 상태이다.
따라서 typeof를 통해 자료형을 확인해보면 null은 object로, undefined는 undefined가 출력되는 것을 확인할 수 있다.

#undefined
undefined는 원시값(Primitive Type)으로, 선언한 후에 값을 할당하지 않은 변수나 값이 주어지지 않은 인수에 자동으로 할당된다. 이 값은 전역 객체의 속성 중 하나로, 전역 스코프에서의 변수이기도 하다. 따라서 undefined 변수의 초기 값은 undefined 원시 값이다.
undefined는 예약어가 아니기 때문에, 전역 범위 외에서 변수 이름으로 사용할 수 있다. 그러나 유지보수와 디버깅에 어려움을 겪을 수 있으므로 피하는 것이 좋다.
아래의 경우에 변수가 undefined를 반환한다.
값을 할당하지 않은 변수
메서드와 선언에서 변수가 할당받지 않은 경우
함수가 값을 return 하지 않았을 때

📌 null

null은 원시값(Primitive Type) 중 하나로, 어떤 값이 의도적으로 비어있음을 표현한다. undefined는 값이 지정되지 않은 경우를 의미하지만, null의 경우에는 해당 변수가 어떤 객체도 가리키고 있지 않다는 것을 의미한다.
null은 undefined처럼 전역 객체의 속성 중 하나가 아니라 리터럴 값이다.
#알아두면 좋은 것
typeof undefined는 출력하면 undefined이다.
typeof null은 출력하면 object이다. 하지만 이는 여전히 원시 타입(primitive value)로, JavaScript에서는 구현 버그로 간주한다.
undefined == null은 true이다


📎 JavaScript 객체와 불변성이란?

Immutability(변경불가성)는 객체가 생성된 이후 그 상태를 변경할 수 없는 디자인 패턴을 의미한다.
Immutability은 함수형 프로그래밍의 핵심 원리이다.

불변 객체를 사용하면 복제나 비교를 위한 조작을 단순화 할 수 있고 성능 개선에도 도움이 된다.
하지만 객체가 변경 가능한 데이터를 많이 가지고 있는 경우 오히려 부적절한 경우가 있다.

ES6에서는 불변 데이터 패턴(immutable data pattern)을 쉽게 구현할 수 있는 새로운 기능이 추가되었다.

📌 불변한 값 vs 변경 가능한 값

아래 Javascript의 원시 타입(primitive data type)은 변경 불가능한 값(immutable value)이다.

  • Boolean
  • null
  • undefined
  • Number
  • String
  • Symbol (New in ECMAScript 6)

원시 타입 이외의 모든 값은 객체(Object) 타입이며 객체 타입 은 변경 가능한 값(mutable value)이다.
즉, 객체는 새로운 값을 다시 만들 필요없이 직접 변경이 가능하다는 것이다.

💡 객체는 변할 수 있는 값이고 원시 타입은 불변한 값이다.

예를 들어 살펴보자. C 언어와는 다르게 Javascript의 문자열은 변경 불가능한 값(immutable value) 이다. 이런 값을 “primitive values” 라 한다. (변경이 불가능하다는 뜻은 메모리 영역에서의 변경이 불가능하다는 뜻이다. 재할당은 가능하다)

아래 예시들을 보면 쉽게 이해할 수 있다.

첫번째 줄이 실행되면 메모리에 문자열 'Hello'가 생성되고, 변수 str은 'Hello'의 메모리 주소를 가리킨다. 그리고 두번째 줄이 실행되면 이전에 생성되었던 문자열 'Hello'를 수정하는 것이 아니라 새로운 문자열 ‘world’를 메모리에 생성하고 식별자 str은 이것을 가리킨다. 이때 문자열 ‘Hello’와 ‘world’는 모두 메모리에 존재하고 있다. 변수 str은 문자열 ‘Hello’를 가리키고 있다가 문자열 ‘world’를 가리키도록 변경되었을 뿐이다. *(원시 타입은 불변한 값이기 때문)

2행에서 Stirng 객체의 slice() 메소드는 statement 변수에 저장된 문자열을 변경하는 것이 아니라 사실은 새로운 문자열을 생성하여 반환하고 있다. 문자열은 변경할 수 없는 immutable value이기 때문이다.

위 예시를 보면 arr는 배열의 요소가 없다가, 생겼다.
결과의 복사본을 리턴하는 문자열의 메소드 slice()와는 달리 배열(객체)의 메소드 push()는 배열 원본 자체를 변경한다.
배열은 객체이고, 객체는 불변한 값이 아닌 변경 가능한 값이기 때문이다.

💡 원시 값의 메소드는 복사본을 리턴하고, 배열(객체)의 메소드는 기존 배열 자체를 변경한다!

그래서 객체는 아래와 같은 일이 발생할 수 있어요.

위 코드를 보면 user2.name 값을 변경하니 user1의 값도 똑같이 변경된 것을 알 수 있다.
user1 와 user2는 값이 변할 수 있는 객체이며 동일한 값을 가리키는 메모리 주소(변수)이기 때문이다.

만약 의도적으로 하나의 값에 2개의 변수를 지정한 것이 아니라면 이 사실을 인지하고 적절히 대응해야 한다.

📌 위와 같은 일을 방지하려면?

객체를 불변객체로 만들어 값의 변경을 방지하거나, 객체의 변경이 필요한 경우에는 객체의 방어적 복사(defensive copy)를 통해 새로운 객체를 생성한 후 변경한다. 얕은 복사가 아닌 깊은 복사를 하는 것!

얕은 복사인 경우 안에 또다른 참조형 데이터가 있을경우 문제발생

  • 객체의 방어적 복사(defensive copy) //얕은복사
    Object.assign 또는 전개연산자 ...
  • 불변객체화를 통한 객체 변경 방지 // 깊은복사
    lodash 패키지를 이용 _.cloneDeep()

📎 JavaScript 호이스팅이란?

공식문서에서는 호이스팅을 아래와 같이 정의한다.

JavaScript에서 호이스팅(hoisting)이란, 인터프리터가 변수와 함수의 메모리 공간을 선언 전에 미리 할당하는 것을 의미합니다. var로 선언한 변수의 경우 호이스팅 시 undefined로 변수를 초기화합니다. 반면 let과 const로 선언한 변수의 경우 호이스팅 시 변수를 초기화하지 않습니다.
호이스팅을 설명할 땐 주로 "변수의 선언과 초기화를 분리한 후, 선언만 코드의 최상단으로 옮기는" 것으로 말하곤 합니다. 따라서 변수를 정의하는 코드보다 사용하는 코드가 앞서 등장할 수 있습니다. 다만 선언과 초기화를 함께 수행하는 경우, 선언 코드까지 실행해야 변수가 초기화된 상태가 됨을 주의하세요.
쉽게 말해 스코프 안에 있는 선언들(변수명, 함수명)을 최상단으로 끌어올려두는 것을 의미한다. 호이스팅은 자바스크립트 인터프리터가 코드를 해석할 때 '변수, 함수의 선언 처리' & '실제 코드 실행' 두 단계로 나누어 처리하기 때문에 발생하는 현상이다.

호이스팅은 변수의 선언과 초기화를 분리하여, 선언만 코드의 최상단으로 끌어올려주기 때문에 변수를 정의하는 코드보다 사용하는 코드가 앞서 등장할 수 있다.

JavaScript는 실행 컨텍스트를 생성하면서 코드에 관련한 식별자, 환경 정보 등을 수집한다.
따라서, 코드가 실행되지 않았어도 JavaScript 엔진은 환경에 속한 변수명들을 모두 알 수 있는데 이러한 특징을 지닌 것이 바로 호이스팅(hoisting)이다.

📌 Function의 호이스팅

함수는 코드를 실행하기 전에 함수 선언에 대한 메모리부터 할당되어 함수를 호출하는 코드를 함수 선언 앞에 배치할 수 있다.
그러나 예상치 못한 에러가 발생할 수 있으므로 const를 사용한 화살표형 함수 선언 방식을 사용하는 것이 좋다.

📌 변수 선언 방식(var)의 호이스팅

변수 선언 시 초기화를 제외한 선언만 호이스팅한다.
변수를 먼저 사용하고 그 후에 선언 및 초기화가 나타나면 사용하는 시점의 변수는 undefined = 기본 초기화 상태가 된다.

let 과 const로 선언한 변수도 호이스팅이 되긴 하지만, var와 달리 undefined로 변수를 초기화하지 않기 때문에, 변수 선언 전에 먼저 사용하면 오류가 발생한다. 리터럴 값은 호이스팅이 되나 특별한 이유로 인해 '초기화가 필요한 상태'로 관리되는 것이다. 이는 '선언은 되어있지만 초기화가 되지 않아 변수에 담길 값을 위한 메모리에 할당되지 않은 상태'라고도 말할 수 있다.


📎 javaScript TDZ란?

TDZ는 Temporal Dead Zone의 약자로 일시적인 사각지대라는 뜻이다. 이 일시적인 사각지대는 스코프(Scope)의 시작지점부터 초기화 시작지점까지의 구간을 TDZ라고 일컫는다.

자바스크립트에서 변수는 선언, 초기화, 할당 3가지의 단계를 거쳐 생성된다.

  • 선언 단계(Declaration phase): 변수를 실행 컨텍스트의 변수 객체에 등록하는 단계를 의미하며 이 변수 객체는 스코프가 참조하는 대상이 된다.

  • 초기화 단계(Initialization phase): 실행 컨텍스트에 존재 하는 변수 객체에 선언 단계의 변수를 위한 메모리를 만드는 단계로 이 단계에서 할당된 메모리에는 undefined로 초기화 된다.

  • 할당 단계(Assignment phase): 사용자가 undefined로 초기화된 메모리의 다른 값을 할당하는 단계.

이 3가지 단계의 순서는 var와 let/const에 차이를 준다.

1) var: var키워드 변수는 변수 선언 전 선언 단계와 초기화 단계를 동시에 진행한다. 자바스크립트는 실행 컨텍스트 변수 객체의 변수를 등록하고 메모리를 undefined로 만들어 버리는데 그 때문에 변수를 선언하기 전에 호출을 해도 undefined로 호출이 되는 호이스팅이 발생하게 되는 것이다.

2) let: let으로 선언된 변수는 var 키워드와는 다르게 선언단계와 초기화 단계가 분리되어서 진행이 된다. 그렇기 때문에 실행 컨텍스트에 변수를 등록했지만, 메모리가 할당이 되질 않아 접근할 수 없어 참조 에러(ReferenceError)가 발생하게 된다.
사람들은 이런 현상을 보고 '호이스팅이 되질 않는다'고 생각하게 된 것이다.
let 또한 선언 전 실행 컨텍스트 변수 객체에 등록이 되어 호이스팅이 되지만 이 TDZ 구간에 의해 메모리가 할당되지 않아 참조 에러(ReferenceError)가 발생한다.


📎 JavaScript Scope란?(스코프의 의미와 적용 범위)

📌 스코프의 의미

  • 변수 접근 규칙에 따른 유효 범위
  • 중괄호(블록) 안쪽에 변수가 선언되었는가, 바깥쪽에 변수가 선언었는가에 따라 안쪽 스코프, 바깥쪽 스코프 구분
  • 바깥쪽 스코프에서 선언한 변수는 안쪽 스코프에서 사용이 가능하지만 안쪽에서 선언한 변수는 바깥쪽 스코프에서는 사용 불가능

📌 스코프의 적용 범위

  • let으로 선언된 message가 if문 안에 위치 : 안쪽 스코프에 선언
  • 바깥쪽에선 message에 접근 불가 : ReferenceError 발생

📎 스코프의 주요 규칙

📌 1.중첩 규칙

  • 스코프는 중첩이 가능
  • scope1만 전역 스코프(Global Scope)
  • scope2-3은 지역 스코프(local scope)

📌 2.block scope와 function scope

1) 블록 스코프

  • 블록 스코프(block scope) : 중괄호로 둘러싼 범위
    *화살표 함수는 블록 스코프로 취급
  • 블록 범위를 벗어나는 즉시 접근할 수 없게 되어 ReferenceError 발생
  • var 키워드 사용시 블록 스코프를 무시하고 함수 스코프만을 따름

2) 함수 스코프

  • 함수 스코프(function scope) : 함수로 둘러싼 범위로 fuction키워드를 사용해야 함
    *화살표 함수는 블록 스코프로 취급

📌 3.전역 스코프와 지역 스코프

  • 가장 바깥쪽의 스코프는 전역 스코프(Global Scope)
  • 전역의 반대말은 지역(local)으로 전역이 아닌 다른 스코프는 전부 지역 스코프(local scope)

📌4. 전역 변수와 지역 변수간의 우선 순위

  • 지역 스코프에 선언한 변수는 지역 변수, 전역 스코프에서 선언한 변수는 전역 변수
  • 전역 변수는 가장 바깥 스코프에 정의한 변수이므로 어디서든 접근 가능
  • side effect를 최소화하기 위해 전역 변수 최소화
    *side effect: 의도되지 않은 변경
  • 지역 변수는 전역 변수보다 더 높은 우선순위를 가짐
    = 함수의 파라미터도 함수 안에서 선언된 지역변수

1) 지역변수 선언

  • 첫번째 출력 : showName 함수 안쪽에 선언된 지역 변수 name은 애초에 스코프 규칙에 의해 접근할 수 없기 때문에 전역 변수로 선언된 name을 가져옴
  • 두번째 출력 : 함수 안에서 선언한 name이라는 지역 변수에 접근 가능, 지역 변수가 전역 변수보다 우선순위가 높으므로 지역 변수 name이 출력
    *쉐도잉(variable shadowing) : 동일한 변수 이름으로 인해 바깥쪽 변수가 안쪽 변수에 의해 가려지는 현상
  • 세번째 출력 : 첫번째 출력과 마찬가지로 전역 변수 name을 출력

2) 전역변수 선언

  • 첫번째 출력 : showName함수가 실행되기 전이므로 처음 할당된 값이 출력
  • 두번째 출력 : showName함수가 실행된 후이므로 함수 내에서 재할당된 값이 출력
  • 세번째 출력 : showName함수가 실행된 후이므로 함수 내에서 재할당된 값이 출력

📌 5. let, const, var 의 차이

1) let

  • 유효 범위 : 블록 스코프, 함수 스코프
  • 값 재할당 : 가능
  • 재선언 : 불가능
    *재선언을 방지해줌

2) const

  • 유효 범위 : 블록 스코프, 함수 스코프
  • 값 재할당 : 불가능
    *값을 재할당할 경우 TypeError 발생(의도하지 않은 값의 변경을 막을 수 있음)
  • 재선언 : 불가능
    *변하지 않는 값, 곧 상수(constant)를 정의할 때 이용

3) var

  • 유효 범위 : 함수 스코프
    *블록 스코프를 무시하고 함수 스코프만을 따름
  • 값 재할당 : 가능
  • 재선언 : 가능
    *재선언을 해도 에러를 내지 않음, 선언 없이 변수를 할당할 경우 해당 변수는 var로 선언한 전역 변수처럼 취급
    *전역 변수를 var로 선언하는 것은 브라우저의 내장 기능을 사용하지 못하게 만들 수도 있으므로 let과 const를 주로 사용

💡"선언 없는 변수 할당"의 경우 Strict Mode를 사용하면 에러로 판단해줌
: js 파일 상단에 'use strict'; 라고 입력하면 적용 가능

📌6. 전역 객체(window)의 이해

  • 브라우저에는 window라는 객체가 존재 : 브라우저 창을 대표하는 객체이지만 이와 별개로 전역 영역도 담고 있음
  • var로 선언된 전역 변수 및 전역 함수(함수 선언식으로 함수를 선언)는 window 객체에 속하게 됨

📎 실습과제

콘솔에 찍힐 b 값을 예상해보고, 어디에서 선언된 “b”가 몇번째 라인에서 호출한 console.log에 찍혔는지, 왜 그런지 설명해보세요.
주석을 풀어보고 오류가 난다면 왜 오류가 나는 지 설명하고 오류를 수정해보세요.

  • //console.log(a);
    주석처리를 풀 경우 밖에서 함수안쪽인 지역변수 a에 접근할 수 없기 때문에 에러가 난다.
    에러를 해결하기 위해 전역변수로 const a = 1; 을 넣는다.
  • console.log(b);
    1 전역변수인 첫째줄 을 불러온다.
  • hi();
    1,101함수를 호출하여 함수안의 console.log(a,b)를 부르며 지역변수로 함수 안의 a,b를 불러온다.
  • console.log(b);
    1지역 변수인 블럭 안으로 접근하지 못하고 전역변수인 첫째 줄 b를 불러온다.

0개의 댓글