23.01.09(Js)

MH S·2023년 1월 9일

Js

목록 보기
4/5

자바스크립트

  • 브라우저에서 Jsp 사용
  • vscode에서 Jsp 사용
  • 주석
  • 변수, 함수, 배열, 객체

인터프리터에 의해서 동작하는 언어인 스크립트 언어이다.

HTML: 웹페이지의 구조
CSS: 웹페이지의 디자인
JavaScript: 웹페이지의 기능


개발 가능 영역

  1. 서버
  2. 윈도우, 맥, 리눅스 프로그램 + 게임
    등 Node.js 등장이후 대부분 영역에서 사용 가능.

- 자바스크립트 자료형 종류

Boolean 타입
Null 타입
Undefined 타입
Number 타입
BigInt 타입
String 타입
Symbol 타입


- 자바스크립트 변수 선언방법

  1. var (function scope)
var i;  // 선언, "undefined"가 저장됨
var sum = 0;  // 선언과 초기화
var i, sum; // 한 번에 여러 개의 변수를 함께 선언할 수 있음
var i=0, sum=10, message=”Hello”;  // 선언과 초기화를 동시에 해줄 수 있음
name = "javascript";  // 선언되지 않은 변수는 전역 변수가 됨

- 자바스크립트 함수 선언방법

  1. named function declaration (명명 함수 선언)
function hello() {
  // ...
}

가장 대중적인 방법이다. 함수의 이름이 hello가 된다. 이미 여러차례 싸질러 놨듯, 호이스팅 되기 때문에 이 함수는 어느 스코프에서든 호출 할 수 있는 함수가 된다.

  1. anonymous function expression (익명 함수 표현)
var hello = function () {
  //...
}

이름이 없는 함수를 변수에 담은 방식이다. 이름이 없는 함수긴 한데, 자바스크립트 엔진이 이름을 변수명으로 추정하여 넣는다.

var hello = function () {
  //...
}

hello.name

//  > "hello"
hello

// > ƒ () {
//   //...
// }

변수 할당은 호이스팅 되지 않으므로, 할당 된 이후에만 실행 가능하다.

  1. arrow function (화살표 함수) ** 많이 쓰이는 방식
var hello = () => {
  //...
}

그리고 요즘들어 많이 쓰이고 있는 화살표 함수다. 몇가지 다른게 있다면

  • constructor로 쓰일 수 없다.
  • prototype을 가지고 있지 않는다.
  • yield 키워드를 허용하지 않으므로 generator를 쓸 수 없다.
  • this도 다르다.
  1. named function expression (명명 함수 표현)
var hello = function originalName() {
  // ...
}

2와 거의 동일하다. 다른 점은 함수 이름이 명확하게 선언되어 있으므로 JS 엔진에 의해 추론되지 않는 다는 것이다.

  1. Immediately-invoked expression (즉시 실행 표현)
var hello = (function () {
  //...
})()

즉시 실행 함수로, 클로져를 활용할 수 있다. 내부 함수는 변수나 다른 함수등을 쓸 수 있지만,이 함수 밖에서는 완전히 캡슐화되어 접근 할 수 없다. 가장 흔해 빠진 예제 중 하나로는 카운터가 있다.

var myCounter = (function (initialValue = 0) {
  let count = initialValue
  return function () {
    count++
    return count
  }
})(1)

myCounter() // 2
myCounter() // 3
myCounter() // 4

외부 함수에서 넘겨준 1을 가지고, 내부에서 처리를 하여 리턴하고 있다.

  1. function constructor
var hello = new Function()

아마도 이런식으로 함수를 쓸일은 거의 없을 것이다.

const adder = new Function('a', 'b', 'return a + b')
adder(2, 6)
// 8

이는 eval()을 사용하는 것과 같기 때문에 굉장히 위험하다. 그리고 이 생성자는 전역 범위로 한정된 함수만 생성할 수 있다.


- JSON 이란?

  • JavaScript Object Notation라는 의미의 축약어로 데이터를 저장하거나 전송할 때 많이 사용되는 경량의 DATA 교환 형식
  • Javascript에서 객체를 만들 때 사용하는 표현식을 의미한다.
  • JSON 표현식은 사람과 기계 모두 이해하기 쉬우며 용량이 작아서, 최근에는 JSON이 XML을 대체해서 데이터 전송 등에 많이 사용한다.
  • JSON은 데이터 포맷일 뿐이며 어떠한 통신 방법도, 프로그래밍 문법도 아닌 단순히 데이터를 표시하는 표현 방법일 뿐이다.

JSON 특징

  • 서버와 클라이언트 간의 교류에서 일반적으로 많이 사용된다.
  • 자바스크립트 객체 표기법과 아주 유사하다.
  • 자바스크립트를 이용하여 JSON 형식의 문서를 쉽게 자바스크립트 객체로 변환할 수 있는 이점이 있다.
  • JSON 문서 형식은 자바스크립트 객체의 형식을 기반으로 만들어졌다.
  • 자바스크립트의 문법과 굉장히 유사하지만 텍스트 형식일 뿐이다.
  • 다른 프로그래밍 언어를 이용해서도 쉽게 만들 수 있다.
  • 특정 언어에 종속되지 않으며, 대부분의 프로그래밍 언어에서 JSON 포맷의 데이터를 핸들링 할 수 있는 라이브러리를 제공한다.

- 자바스크립트 스코프란?

Scope를 우리말로 번역하면 ‘범위’라는 뜻을 가지고 있습니다. 즉, 스코프(Scope)란 ‘변수에 접근할 수 있는 범위’라고 할 수 있습니다.

자바스크립트에선 스코프는 타입 2가지

global(전역), local(지역)

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

모든 변수는 스코프를 갖는다. 변수의 관점에서 스코프를 구분하면 다음과 같이 2가지로 나눌 수 있다.

  • 전역 변수 (Global variable)
    전역에서 선언된 변수이며 어디에든 참조할 수 있다.
  • 지역 변수 (Local variable)
    지역(함수) 내에서 선언된 변수이며 그 지역과 그 지역의 하부 지역에서만 참조할 수 있다.

변수는 선언 위치(전역 또는 지역)에 의해 스코프를 가지게 된다. 즉, 전역에서 선언된 변수는 전역 스코프를 갖는 전역 변수이고, 지역(자바스크립트의 경우 함수 내부)에서 선언된 변수는 지역 스코프를 갖는 지역 변수가 된다.

전역 스코프를 갖는 전역 변수는 전역(코드 어디서든지)에서 참조할 수 있다. 지역(함수 내부)에서 선언된 지역 변수는 그 지역과 그 지역의 하부 지역에서만 참조할 수 있다.


- var let const 스코프 차이

  1. var let const

  2. var : 변수 재선언 가능
    const, let : 변수 재선언 불가능

  3. const : 변수 재할당 불가능 (상수)
    let : 변수 재할당 가능

  4. var : functional-scope 로 호이스팅됨
    const, let : block-scope 로 호이스팅됨

console.log(a)
var a = "hi"

출력 : undefined

console.log(b)
const b = "hi"

출력 : 에러!

즉, let const는 변수를 선언과 초기화 후, 참조해야한다.


- 1급 객체란 ?(자바, 자바스크립트 비교)

일급객체(First-class Object)란 다른 객체들에 일반적으로 적용 가능한 연산을 모두 지원하는 객체를 가리킨다.

1급 객체의 세가지 조건

  1. 변수나 데이터에 할당 할 수 있어야 한다.
  2. 객체의 인자로 넘길 수 있어야 한다.
  3. 객체의 리턴값으로 리턴 할 수 있어야 한다.

위에 대한 조건으로 인해 알 수 있는 것은 함수를 데이터(string, number, boolean, array, object) 다루 듯이 다룰 수 있다는 점이다.

JAVA에서는 위의 조건에 해당되지 않습니다. 하지만 java의 Lambda는 메서드가 1개만 존재하는 인터페이스/클래스를 통해, 마치 함수를 전달하는 것처럼 여겨서, 함수를 1급 객체로 취급하지 않는 java의 단점을 어느정도 해결한 것이라 볼수 있습니다.

const a = () => {
 doSomething(); 
}

데이터를 다룬다는건 변수에 할당이 가능하다는건데, 위의 정의에 의해서 함수 역시 변수에 할당 가능하다.

자바스크립트에서는 함수가 일급객체이다.


- 콜백

파라미터로 함수를 전달하는 함수

콜백함수(Callback Function)란 파라미터로 함수를 전달받아, 함수의 내부에서 실행하는 함수이다.

let number = [1, 2, 3, 4, 5];

number.forEach(x => {
    console.log(x * 2);
});

<output>
2
4
6
8
10

콜백함수는 이미 우리의 코드 속에서 자주 사용되고 있다.
예를 들어, forEach 함수의 경우 함수 안에 익명의 함수를 넣어서 forEach 문을 동작시킨다.


- 호이스팅

  • 호이스팅은 코드를 실행하기 전 변수선언/함수선언을 해당 스코프의 최상단으로 끌어올리는 것이 아니다.
  • 호이스팅은 코드가 실행하기 전 변수선언/함수선언이 해당 스코프의 최상단으로 끌어 올려진 것 같은 현상을 말한다.
  • 자바스크립트 엔진은 코드를 실행하기 전 실행 가능한 코드를 형상화하고 구분하는 과정(실행 컨텍스트를 위한 과정)을 거친다.
  • 자바스크립트 엔진은 코드를 실행하기 전 실행 컨텍스트를 위한과정에서 모든 선언(var, let, const, function, class)을 스코프에 등록한다.
  • 코드 실행 전 이미 변수선언/함수선언이 저장되어 있기 때문에 선언문보다 참조/호출이 먼저 나와도 오류 없이 동작한다.
    (정확히는 var 키워드로 선언한 변수와 함수 선언문일 경우 오류 없이 동작한다. 이는 선언이 파일의 맨 위로 끌어올려진 것 처럼 보이게 한다.)
  • 실행 컨텍스트는 실행 가능한 코드가 실행되기 위해 필요한 환경을 의미하고 실행되기전 이러한 실행 컨텍스트 과정(코드를 구분하는 과정)을 거친다.

- window 객체/DOM/BOM

전역객체이며 JavaScript의 최상위객체이기도 합니다. DOM, BOM, JavaScript 모두 window 객체의 프로퍼티가 됩니다.

  • DOM(Document Object Model) : 문서 객체 모델 - HTML 파일인 웹 문서를 브라우저가 렌더링하려면 브라우저가 이해할 수 있는 구조로 메모리에 올려야합니다. 그것을 구조화하여 표현한 것을 DOM tree, 이런 전체적인 컨셉, 모델을 DOM이라고 합니다.
  • BOM(Browser Object Model) : 브라우저 객체 모델 - DOM과 달리 W3C의 표준 객체 모델은 아니지만 웹 브라우저와 관련된 객체의 집합으로써 JavaScript가 웹 브라우저의 기능적인 요소들을 직접 제어하고 관리할 방법을 제공해 줍니다.

- (부동소수점이란?) 자스에서 1.1 + 1.3 이 2.4가 아닌 이유

자바스크립트에서 소수점 숫자 연산을 하면, 생각지도 못한 오류가 발생한다. 아래처럼 콘솔창에 1.1 + 1.3를 입력하면, 2.4이 아니라 2.40000000000000004 가 나오는 걸 확인해볼 수 있다. 이렇게 소수점 계산 오류가 발생하는 이유와 어떤 방법으로 해결할 수 있는지에 대해 알아보려고 한다. Javascript를 다루다보면 한번쯤은 마주칠 수 있는 오류이기 때문에 나중에 또 당황하지 않도록 기억하고 넘어가자! (Javascript에서만 있는 오류는 아님)

원인

왜 이런 오류가 생기는걸까? 우리는 보통 계산을 할 때 '10진법'을 사용하지만, 우리와 다르게 컴퓨터는 계산을 할 때 0과 1만 사용하는 '2진법'을 사용한다. 그래서 10진법을 2진법으로 바꾸는 변환과정이 필요한데, 소수 중 일부는 이 과정에서 무한소수가 되어버린다. 하지만 컴퓨터 메모리에는 한계가 있어서 무한 소수를 다 담지 못하고 중간에 잘라서 유한 소수로 저장해버린다. 바로 이 과정에서 미세한 오차가 발생하는 것이다.


- 얕은 복수, 깊은 복사

얕은 복사는 객체의 참조값(주소 값)을 복사하고, 깊은 복사는 객체의 실제 값을 복사합니다.

  • 얕은 복사
const obj1 = { a: 1, b: 2};
const obj2 = obj1;
console.log( obj1 === obj2 ); // true

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

const obj1 = { a:1, b:2 };
const obj2 = obj1;
obj2.a = 100;
console.log( obj1.a ); // 100

위 두 객체는 같은 데이터(주소)를 가지고 있고, 그래서 같은 주소를 참조하고 있다.
때문에 obj2의 property를 수정하고, obj1를 출력해도 obj2 값과 동일하다.

  • 깊은 복사

    Object.assign() 메소드를 통한 복사

const obj1 = { a:1, b:2 };
const obj2 = Object.assign({}, obj1);
obj2.a = 100;
console.log( obj1 === obj2 ) // false
console.log( obj1.a ) // 1

Object.assign() 메소드를 통해 첫 번째 인자로 빈 { } 객체를, 두 번째 인자로 obj1 넣고 obj2 에 할당하였다.
이제 obj1과 obj2는 다른 주소를 갖게되었다. (그러나 딱, 1 depth 까지만)

0개의 댓글