엘리스 15일차 금요일 온라인강의 javascript

치즈말랑이·2022년 4월 24일
0

엘리스

목록 보기
16/47
post-thumbnail
post-custom-banner

00

1) 자바스크립트 코드 실행 단계에서 발생하는 일

생성 단계 - 실행 컨텍스트 생성
실행 단계 - 변수 값 할당, 코드 실행

2)

console.log(callMe());
(?) x = 10;
console.log(callMe())

function callMe() {
    return x;
}

(?)에 let을 넣으면 에러가 발생한다.

01

js 코드 실행

  • 자바스크립트 엔진은 자바스크립트 코드를 읽어 실행하는 프로그램이다.
  • 작성한 자바스크립트 코드는 자바스크립트 엔진을 통해 파싱되고 실행된다.
  • Chrome 브라우저의 경우 V8 엔진을 사용한다.
  • node.js는 브라우저 외의 환경에서 자바스크립트 코드를 실행하도록 하는 프로그램이다.
  • node.js는 여러 프로그램으로 구성되며, 자바스크립트 코드를 읽는 프로그램으로 V8을 사용한다.
  • 브라우저 환경과 node.js환경은 같은 자바스크립트 코드를 작성해도 다르게 동작할 수 있다.
  • 자바스크립트 엔진은 코드 실행 전 실행 컨텍스트를 생성한다.
  • 실행 컨텍스트는 두 단계를 통해 생성된다.
  • 생성 단계에서 자바스크립트 엔진은 변수 선언을 읽는다.
  • 실행 단계에서 자바스크립트 엔진은 변수 값을 할당한다.

렉시컬 환경 (Lexical Environment)

  • 함수의 렉시컬 환경은 함수가 사용하는 변수들을 둘러싼 환경을 의미한다.
  • 특정 변수의 값은 함수의 렉시컬 환경 안에서 찾을 수 있다.
  • 렉시컬 환경은 실행 컨텍스트 안에 정의된 Variable Object로 이해할 수 있다.
  • 자바스크립트 엔진은 생성단계에서 함수 선언문, 함수 표현식, 변수 등을 읽어 실행 컨텍스트에 저장한다.
  • 변수의 경우 실행 컨텍스트의 렉시컬 환경을 구성한다.
  • 함수 선언문 외에 변수는 값이 저장되지 않는다.
  • 자바스크립트 엔진은 변수에 값을 할당하는 구문을 만나면 실행 컨텍스트에 값을 저장한다.

  • var 변수는 실행컨텍스트 생성단계에서 undefined로 초기화 된다.
  • let, const는 초기화되지 않는다.

실행 컨텍스트 생성 단계에서 자바스크립트 엔진은 변수 선언을 읽어 변수를 실행 컨텍스트에 저장한다.
실행 컨텍스트 실행 단계에서 자바스크립트 엔진은 변수 할당 구문을 읽어 실행 컨텍스트에 저장된 변수에 값을 저장한다.
함수 선언문은 생성 단계에서 함수명과 함수 전체가 저장된다.
실행 컨텍스트 실행 단계에서 자바스크립트 엔진이 변수명을 읽으면 렉시컬 환경에서 값을 읽는다.

Hoisting

console.log(callMe())
// undefined

var x = 10

console.log(callMe()) // 10

function callMe() {
	return x
}
  • Hoisting은 변수가 선언된 시점보다 앞에서 사용되는 현상이다.
  • 이는 var 변수가 생성 단계에서 undefined로 초기화되는 것이 원인이다.
  • 함수는 생성 단계에서 함수 전체가 저장되므로 뒤에서 선언되어도 호출이 가능하다.
// ReferenceError: Cannot access 'a'
// before initialization
console.log(callMe())
// undefined

let x = 10

console.log(callMe()) // 10

function callMe() {
	return x
}
  • let, const 변수는 생성 단계에서 초기화되지 않는다.
  • 선언문 이전에 접근 시 ReferenceError가 발생한다.
  • 이 경계를 Temporal Dead zone(TDZ) 라고한다.
  • 따라서 let, const는 hoisting이 발생하지 않는다.
  • var는 함수 스코프, let과 const는 블록 스코프 변수이다.
function varFor(){
	for (var i = 0; i < 3; ++i) {
    	setTimeout(() => console.log('i: ', i), 0);
    }
}

function letFor(){
	for (let i = 0; i < 3; ++i) {
    	setTimeout(() => console.log('i: ', i), 0);
    }
}

varFor(); // 3 3 3
letFor(); // 0 1 2
  • varFor에서 i는 varFor 함수 범위에 존재하는 변수이다.
  • 따라서 setTimeout이 호출될 때 i는 for 블럭이 끝난 시점에 소멸하지 않는다.
  • letFor에서 i는 for 블럭 안에 존재하는 변수이다.
  • 각 for block이 실행되고 i는 소멸한다. 다만, 이 경우 각 화살표 함수의 closure에 저장된다.

varFor에서 3 3 3 이 나온 이유는, 비동기방식으로 실행되어 setTimeout이 지연되는동안 for문이 다돌아서 그런거다
참고: https://velog.io/@yonyas/Javascript-for%EB%AC%B8%EA%B3%BC-setTimeout-%EB%8F%99%EC%8B%9C%EC%97%90-%EC%93%B8-%EB%95%8C-var%EC%99%80-let%EC%9D%98-%EC%B0%A8%EC%9D%B4

자바스크립트의 내장 객체들1

globalThis

  • 전역 객체
  • 환경에 따라 다르다.
  • 브라우저 환경은 window, node 환경은 global 객체를 지칭한다.
  • globalThis는 환경별 차이를 통일하여 하나의 변수로 서로 다른 전역 객체를 가리키게 한다.

window

  • DOM document를 포함하는 창을 나타내는 객체
  • 전역 스코프에 선언된 변수는 모두 window의 property가 된다.
  • 현재 창의 정보를 얻거나, 창을 조작한다.

document

  • 브라우저에 로드된 웹페이지
  • 문서의 title, URL 등의 정보를 얻는다.
  • element 생성, 검색 등의 기능 제공

자바스크립트의 내장 객체들2

Number, NaN

  • 자바스크립트의 number 원시타입을 감싸는 객체
  • 유의미한 상수값, 숫자를 반환하는 메서드 등을 제공한다.
  • NaN - Not a Number를 나타내는 객체
  • isNaN() - 전역 함수로 입력값을 숫자로 반환했을 때 NaN이 되는지를 검사
function changeToUsd(krw) {
	const rate = 1046;
  return (krw / rate).toFixed(2);
}

const krw = 1000000;
console.log(changeToUsd(krw));
  • Number.toFixed 메서드는 숫자의 소수점 자리수를 제어한다.
  • 반환된 값은 반올림된 문자열이다.
  • changeToUsd에서 변환된 krw를 소수점 둘째자리까지만 처리한다.
function formatNumber(n) {
	if (isNaN(n)) return '0';
  return Number(n).toFixed(2);
}

formatNumber('12.345') // 12.35
  • isNaN과 함께 활용하여 유저의 입력을 포맷팅할 수 있다.

Math

  • 기본적인 수학 연산 메서드, 상수를 다루는 객체
  • BigInt타입과 호환되지 않고, Number 타입만을 인자로 다룬다.
function getMaxDiff(nums) {
	return Math.max(...nums)-Math.min(...nums)
}

getMaxDiff([-1, -4, -7, 11]) // 18
  • Math.max, Math.min은 개별 숫자를 인자로 받아 각각 최대, 최소값을 리턴한다.
  • getMaxDiff는 배열의 최대값, 최소값의 차이를 계산한다.

Math.random()은 0에서 1사이의 float number를 구한다.
Math.floor는 소수점 이하 숫자를 버린다.

자바스크립트의 내장 객체들3

Date

  • 특정 시점의 날짜를 표시하기 위한 객체
function isWeekend(today) {
	let day = today.getDay();
  	return day === 0 || day === 6;
}

console.log(isWeekend(new Date('2021/9/12')));
  • Date.getDay()는 요일을 0(일요일)부터 6(토요일)로 구한다.
function addDays(date, days) {
	date.setDate(date.getDate() + days)
  	return date.toDateString()
}
addDays(new Date('2021/9/22'), 100) // Fri Dec 31 2021
  • setDate() 등의 메서드로 시간을 정한다.
  • 설정 시 월 변경 등의 시간 변환은 Date 객체가 처리한다.
  • toDateString() 메서드는 특정 포맷의 문자열을 반환한다.
function timeDiff(date1, date2) {
	return date2.getTime() = date1.getTime();
}
let dayTime = 60 * 24 * 60 * 1000
function fromNow(date) {
	let diff = timeDiff(date, new Date())
    return `${Math.floor(diff/dayTime)} days ago...`
}

fromNow(new Date('2021/9/1'))
  • getTime() 메서드는 시간을 밀리초 단위로 반환한다.
  • 이때 밀리초는 1970.1.1 시점부터 흐른 시간이다.
  • fromNow는 주어진 시간이 현재로부터 며칠이나 흘렀는지 계산한다.

문자열로 된 시간을 Date 객체로 변환하면 Date 객체가 생성된다.

	let year = date.getFullYear();
	let month = date.getMonth()+1; //(1월은 0, 2월은 1, ...)
	let day = date.getDate();
	let hour = date.getHours();
	let min = date.getMinutes();
	let sec = date.getSeconds();

String, JSON

  • 자바스크립트의 문자열 원시 타입의 래퍼 객체
  • includes() 메서드는 문자열 검색 성공시 true, 실패시 false를 리턴한다.
  • split()은 주어진 문자열에 따라 타겟 문자열을 나눈다.
  • replace()는 주어진 문자열을 검색하여 타겟 문자열로 변환한다.
  • indexOf()는 특정 문자열을 검색하여 시작점의 인덱스를 반환한다. 없을 시 -1을 리턴한다.
JSON.stringify({name: "Daniel", age:12})
// '{"name":"Daniel", "age":12}'
JSON.parse('{"name":"Daniel", "age":12}')
// {name: "Daniel", age:12}
  • JSON.stringify()는 주어진 객체를 JSON 문자열로 만든다.
  • JSON.parse()는 주어진 JSON문자열을 자바스크립트에 맞는 결과 객체로 만든다.
			.reduce((map, char) => {
				if (!map[char]) map[char] = 0
				map[char]++
				return map
              
        Object.entries(this.object)
			.reduce((acc, [key, value]) => `${acc} [${key}: ${value}]`,"")
			.trim()
const {a, b, c, d} = {
	a: 1,
  	b: 2,
  	c: 3,
  	d: 4
}

function parse(value) {
	return {
		1: "연별",
		2: "반기별",
		4: "분기별",
		12: "월별",
	}[value];
}
  // stocks 데이터를 이용해, tbody 안에 들어갈 태그를 동적으로 만드세요.
	const tableData = stocks.map( // stocks는 [{x:a, y:b}, {z:1, o:2}] 와 같은 형태
		({stockName, buyPrice, currentPrice, stockAmount}) => ({
			name: stockName,
			earningRate: ((currentPrice - buyPrice)/buyPrice * 100).toFixed(2),
			profit: (currentPrice - buyPrice) * stockAmount
		})
		
	)
    
    const [buyPriceSum, currentPriceSum] = [
		stocks.reduce((acc, cur) => acc+cur.buyPrice * cur.stockAmount, 0),
		stocks.reduce((acc, cur) => acc+cur.currentPrice * cur.stockAmount, 0)
	]
  up() {
  this.step += 1;
    return this;
  }
  return templates[id].replace(/{name}|{n}/g, function (val) {
    return val === "{name}" ? names.shift() : names.length;
  });
}
profile
공부일기
post-custom-banner

0개의 댓글