[Javascript] 브라우저의 작동원리 , 기본문법
구글의 자바스크립트 엔진 v8으로 빌드된의 자바스크립트 런타임인 node.js의 등장!
웹브라우저에서 벗어나 서버사이드도 캐리가능한 범용언어개발로 성장하는데...
하지만 근본은 근본. 많이 사용되는 분야는 역시나 웹브라우저에서 동작하는 웹페이지/웹어플리케이션 이다.
대다수의 프로그래밍 언어 ? => java, spring 파인썬 고언어 등등 얘네는 운영체제위에서 움직인다.
하지만 웹어플리케이션의 자바스크립트는? 브라우저에서 HTML, CSS와 함께 실행된다.
이런 장점과 특수성? 때문에 결국 프론트엔드를 지망한다면 자바스크립트가 필수가 아닌가싶다.
1. 브라우저의 핵심기능은? 사용자가 요청한 정보를 서버에 요청 하고, 서버의 응답을 받아서 브라우저에 표시하는것.
2. 브라우저는 서버에게 HTML,CSS,JAVASCRIPT,IMG파일등을 응답으로 보내준다.
3. HTML을 읽어 => 파싱되어 => DOM트리 변환
4. CSS를 만나면 => 파싱하여 => CSSOM 트리 변환
5. DOM+ CSSOM 렌더 트리로 결합
이렇게 생성된 렌더 트리를 기반으로 브라우저는 웹페이지를 표시한다
그런데 중요한사실!
자바스크립트는 렌더링 엔진이 아닌 자바스크립트 엔진이 처리한다. HTML파일이 파싱되어 DOM트리를 막 만들다가 <sciprt></sciprt> 태그를 만나면?
중단하고 제어권을 자바스크립트 엔진에 넘겨준다.
자바스크립트의 실행이 완료되면 다시 HTML 파서로 제어 권한을 넘겨서 브라우저가 중지했던 시점부터 DOM 생성을 재개한다.
브라우저는 동기(Synchronous)적으로 HTML, CSS, Javascript을 처리한다.
이렇게 script파일을 만나면 어찌되엇든 실행하던일 이 중단되게되기에, sciprt의 위치가 중요하다.
body 요소의 가장 아래에 자바스크립트를 위치시키는 것은 좋은 아이디어라고 한다.
이유는?
- DOM이 완성되지 않은 상태에서 자바스크립트가 DOM을 조작한다면 에러가 발생한다.
- 페이지 로딩시간 단축. HTML 요소들이 스크립트 로딩 지연으로 인해 렌더링에 지장 받는 일이 발생하지 않는다.
변수
변수는 값을 저장하고 그 저장된 값을 참조 하기위해 사용한다.
한번쓰고 버리는게 아니고 유지해야한다면? 변수에 담아둔다.
변수의 이름을 통해 값의 의미를 알수있기에 => 변수사용은 가독성을 좋게 만든다.
변수는 위치를 기억하는 저장소다. 위치란 메모리상의 주소(address)를 의미한다.
변수란 메모리 주소(Memory address)에 접근하기 위해 사람이 이해할 수 있는 언어로 지정한 식별자(identifier)이다.
let myfirstpet ='bomba'
myfirstpet이라는 이름을 지정하고 bomba라는 값을 할당 했다.
자바스크립트의 모든 값은 데이터 타입을 갖는다. 2가지의 큰 타입으로 나눈다. 원시타입, 객체타입
- 원시 타입 (primitive data type)
- number
- string
- boolean
- null
- undefined
- symbol (New in ECMAScript 6)
- 객체 타입 (Object data type)
- object
자바스크립트는 변수를 선언할 때 데이터 타입을 미리 지정하지 않는다. => 타입을 지정해준게 타입스크립트
변수에 할당된 값의 타입에 의해 동적으로 변수의 타입이 결정된다. 이를 동적 타이핑이라 하며 자바스크립트가 다른 프로그래밍 언어와 구별되는 특징 중 하나이다.
그래서! 자바스크립트가 동적인 언어라고하며 타입스크립트를 정적 언어라고 한다.
프로그래밍은 변수를 통해 값을 저장하고 참조하며 연산자로 값을 연산, 평가하고 조건문과 반복문에 의한 흐름제어로 데이터의 흐름을 제어하고 함수로 재사용이 가능한 구문의 집합을 만들며 객체, 배열 등으로 자료를 구조화하는 것이다.
다시한번 말하자면 변수는 위치를 기억하는 저장소다. 위치란 메모리상의 주소(address)를 의미한다.
값을 저장하려면? 메모리의 크기를 알아야한다. 바이트바이트! 메모리의 크기 바이트!
이때 값의 종류, 즉 데이터의 종류를 데이터 타입(Data Type)
타입을 알면? 값의 크기를 아는것. 그래서 타입스크립트가 메모리절약이 된다는점이다.
자바스크립트에서 변수는 고정된 타입이 없다. 따라서 같은 변수에 여러 타입의 값을 자유롭게 할당할 수 있다.
타입을 좀더 들여다보자.
원시타입?
변경불가능한 값! immutable value
값에의한전달이다.
1. NUMBER
자바스크립트의 숫자 타입은 정수만을 위한 타입이 없고 모든 수를 실수를 처리한다. 정수로 표시된다해도 사실은 실수다. 따라서 정수로 표시되는 수 끼리 나누더라도 실수가 나올 수 있다.
특이한점은 3가지 특별한 값을 표현할 수 있다고한다.
- Infinity : 양의 무한대
- -Infinity : 음의 무한대
- NaN : 산술 연산 불가(not-a-number)
2.STRING
문자열은 작은 따옴표(‘’) 또는 큰 따옴표(“”) 안에 텍스트를 넣어 생성한다. 가장 일반적인 표기법은 작은 따옴표를 사용하는 것이다.
오..! 작은따옴표를 사용하도록해야겠다..
자바스크립트의 문자열은 원시 타입이며 변경 불가능(immutable)하다. 이것은 한 번 문자열이 생성되면, 그 문자열을 변경할 수 없다는 것을 의미한다. 아래의 코드를 살펴보자.
let myfirstpet = 'bomba';
myfirstpet = 'comong';
실행단계는
메모리에 문자열 봄바가 생성이되고 이 식.별.자 인 myfirstpet은 메모리에 생성된 문자열 'bomba'의 메모리주소 를 가르킨다.
두번째 구문이 실행되면 이전에 생성된 문자열 ‘bomba’를 수정하는 것이 아님
새로운 문자열 ‘comong’을 메모리에 생성하고 식별자 myfirstpet은 이것을 가리킨다.
그니까 쉽게 정리하자면, 변수는 그냥 메모리값을 가르키는것뿐이고 수정이아니고 메모리가 새로 생성되는것!
그래서 (내생각엔ㅋㅋ)가바지컬렉터가 이런 쓰이지않는 변수들을 처리해주는게 아닌가싶다..더이상 변수가 그 메모리를 참조하고있지않는다는것.. 가르키는 대상이 꼬몽으로 바뀌었기에
문자열은 배열처럼 인덱스를 통해 접근할 수 있다. 이와 같은 특성을 갖는 데이터를 유사 배열이라 한다.
알고리즘같은거 풀면 let myname = 'sophie' 면 myname[3] = 'h' 이런식으로 가능하기에 유사배열이라고 하는것
한번 생성된 문자열은 read only로서 변경할 수 없다. 이것을 변경 불가능(immutable)이라 한다.
그러나 새로운 문자열을 재할당하는 것은 물론 가능하다. 이는 기존 문자열을 변경하는 것이 아니라 새로운 문자열을 새롭게 할당하는 것이기 때문
즉. 재할당한다는말이 참조하는값이 바뀐다고 생각하면 된다.
immutable이라는 개념이 좀 헤갈리는데
쉽게정리해봤다.
결국 메모리를 큰땅이라고 생각하고
집이라는 변수를 만들고
집 = 채영집
이렇게 해놨는데
만약에 채영집이 mutable하다면...
채영집.조명 = 노랑 이런식으로 변경이가능하겟지만...
immutable하다면 새로운집을 지어서 조명을 노랑으로 변경해주고
집 = 새로운채영집 이렇게 바꿔야한다는것..
그러면 지금 집이 가르키고있는 주소는 새로운집이지만
채영집은 아직 그땅에 똑같이 있다.
가비지컬렉터는 공무원이라고 생각하고 큰땅을 돌면서 쓸모없어진 집들을 철거하는 놈이당
그러면 채영집 앞에 가서 보니까 아무도 안살아...ㅜㅜ 안쓰고있어..야! 철거해!
넵! 철거철거 => 그 땅을 다시 사용해야되니까!!!
3. boolean
논리적 참, 거짓을 나타내는 true와 false
중요한 사실은! 비어있는 문자열과 null, undefined, 숫자 0은 false로 간주된다.
1은 true다.
4. undefined
선언은 되었지만 값을 할당하지 않은 변수에 접근하거나 존재하지 않는 객체 프로퍼티에 접근할 경우 undefined가 반환된다.
변수를 처음 선언하면 자바스크립트가 빈값을 undefined라고 해버림.
let sophie;
console.log(sophie); // undefined
의도적으로 할당한 값이 아니라 자바스크립트 엔진에 의해 초기화된 값.
null과 다르다!!!
변수의 값이 없다는 것을 명시하고 싶은 경우 어떻게 하면 좋을까? => 그런 경우는 undefined를 할당하는 것이 아니라 null을 할당한다.
자바스크립트가 초기화한값이 Undefined
개발자가 의도를 가지고 값이없다고 명시한게 Null
5. null
위에서도 말했지만..
프로그래밍 언어에서 null은 의도적으로 변수에 값이 없다는 것을 명시할 때 사용한다.
이는 변수가 기억하는 메모리 어드레스의 참조 정보를 제거하는 것을 의미하며 자바스크립트 엔진은 누구도 참조하지 않는 메모리 영역에 대해 가비지 콜렉션을 수행할 것이다.
집 = null 이렇게 하면
이제 새로운집도 찾아오는 사람(참조하는 변수) 가 없으니까
공무원(가바지컬렉터)이 새로운 집도 철거 한다는거...
함수가 호출되었으나 유효한 값을 반환할 수 없는 경우, 명시적으로 null을 반환한다고한다. 예시는 아래에
let element = document.querySelector('.myElem');
// HTML 문서에 myElem 클래스를 갖는 요소가 없다면 null을 반환한다.
console.log(element); // null
약간 특이점이있다면
typeof 연산자로 null 값을 연산해 보면 null이 아닌 object가 나온다. 이는 자바스크립트의 설계상의 오류라고한다...
따라서~~
null 타입을 확인할 때 typeof 연산자를 사용하면 안되고 일치 연산자(===)를 사용하여야 한다.
typeof 마이로또 하면 object가 나온담요...
let 마이로또 = null;
console.log(typeof 마이로또 === null); // false
console.log(마이로또 === null); // true
객체타입
자바스크립트는 객체(object) 기반의 스크립트 언어로서 자바스크립트를 이루고 있는 거의 “모든 것”이 객체이다.
원시 타입(Primitives)을 제외한 나머지 값들(배열, 함수, 정규표현식 등)은 모두 객체이다. 또한 객체는 참조에의한 전달 방식으로 전달.
데이터는 메모리에저장되어있고
메모리에 저장된 값을 참조하려면 데이터가 저장된 메모리의 주소! address가 필요하다.
값을 할당하지 않은 변수 즉 선언만 되어 있는 변수는 undefined로 초기값을 갖는다.
선언하지 않은 변수에 접근하면 ReferenceError가 발생한다. (let, const만. var => undefined를 가진다.)
동적타이핑이란?
자바스크립트는 동적타입 언어이다!
동적타입언어란? 변수의 타입지정 없이 값이 할당되는 과정에서 값의 타입에 의해 자동으로 타입이 결정될거라는 뜻이다.
같은 변수의 여러타입이 할당가능. let a = '봄바', a = {name: '봄바'} 이렇게 바꿀수있듯이 타입이 바뀔수 있다.
이것을 동적타이핑라고한다.
변수 호이스팅
console.log(foo); // ① undefined
var foo = 123;
console.log(foo); // ② 123
{
var foo = 456;
}
console.log(foo); // ③ 456
let const 같은경우 console.log(foo)를 하면 참조에러가 나오겠지만
var같은경우는 호이스팅이 된다.
변수는 3단계에 의해 생성이된다.
var같은 경우 선언과 초기화단계가 한번에 이루어진다고한다. 스코프에 변수등록후 메모리공간을 확보하고 undefined값으로 초기화.
변수 선언문 이전에 변수에 접근하여도 Variable Object에 변수가 존재하기 때문에 에러가 발생하지 않는다.
이후 변수 할당문에 도달하면 비로소 값의 할당된다.
자세한것은 아래와 같은 프로세스를 가진다고 한다.
①이 실행되기 이전에 var foo = 123;이 호이스팅되어 ①구문 앞에 var foo;가 옮겨진다.(실제로 변수 선언이 코드 레벨로 옮겨진 것은 아니고 변수 객체(Variable object)에 등록되고 undefined로 초기화된 것이다.) 하지만 변수 선언 단계와 초기화 단계가 할당 단계와 분리되어 진행되기 때문에 이 단계에서는 foo에는 undefined가 할당되어 있다. 변수 foo에 값이 할당되는 것은 2행에서 실시된다.
함수레벨스코프와 블록레벨 스코프는 위와같은 차이가있는데
var => 함수레벨 스코프
let, cosnt => 블록레벨 스코프
var의 다양한 문제점때문에
호이스팅되어 undefined로 되는것.
중복 사용이 가능하다는점
함수레벨스코프라는점 등등
let const 키워드를 도입한것이다.