UI/UX 디자이너 성장기 _ JavaScript (1)

deenie·2024년 12월 5일

📖 6주차 수업기록

JavaScript

js는 웹페이지에서 복잡한 기능을 구현할 수 있도록 하는 스크립팅 언어 또는 프로그래밍 언어이다. 쉽게 말하자면 웹페이지에 생동감을 부여하는 작업이라고 할 수 있다.

참조 방식

  • 내장 방식 : <script> 태그 내에 내용을 입력하는 방식으로, HTML 내 어느 위치에서나 사용 가능하다. 단, js 파일 링크가 존재할 때는 링크 위에 작성해야 한다.
    1) 간단하게 만들 수 있음.
    2) 특정 페이지에서만 작동하는 기능일 경우 내장 방식으로 따로 구현 가능.

  • 링크 방식 : js 파일을 따로 만들어 <script src=" ">태그 src 속성의 값으로 링크를 작성해 사용하는 방식으로, HTML 내 어느 위치에서나 사용 가능하다.
    1) 많은 양의 js 코드는 파일로 관리하는 것이 편함.
    2) 동일한 기능을 다른 페이지에서도 사용하고 싶을 때, 링크 방식으로 활용 가능.
    3) 유지보수 용이성이 편리함.

js에서는 읽히는 순서에 따라 작동한다.

디버깅(Debugging)

디버깅이란 소프트웨어 프로그램에서 발생하는 코딩 오류를 찾아 수정하는 프로세스이다. 디버깅을 통해 오류의 원인을 파악하여, 소프트웨어의 성능을 개선하며, 기능 문제를 방지할 수 있다.

수업에서 자주 활용한 명령어는 아래와 같다.

  • console.log() : 대표적인 디버깅 방법으로 js가 활용해 웹페이지의 콘솔창에 출력되도록 함.
    하지만 강제적으로 출력하게 만드는 것이기 때문에 권장되는 방법은 아님.

  • alert() : 웹페이지 내 알림창에 출력되도록 하는 방법.

  • confirm() : 웹페이지 내 알림창에 출력되도록 하는 방법이며, 취소 버튼이 있어 값을 return하거나 조건문인 if문에서 사용 가능.

  • return : 값을 반환하는 명령어로 현업에서 사용되는 방법.

표기법

js에서의 표기법에는 4가지가 있는데, camelCase를 자주 사용한다. 각 표기법에 대한 설명은 welcometokorea를 예시로 사용해보겠다.

  • dash-case(kebab-case) : welcome-to-korea
  • snake_case : welcome_to_korea
  • camelCase : welcomeToKorea
  • PascalCase :WelcomeToKorea

변수 키워드 var, let, const

변수란 말 그대로 변할 수 있는 수를 뜻하며, 데이터 보관함이라고도 생각할 수 있다. 하나의 값을 저장하기 위해 확보한 메모리 공간 혹은 그 메모리 공간을 식별하기 위해 붙인 이름이다.

변수에 대한 이해도를 높이기 위해 미리 알아두면 좋은 개념들은 아래와 같다.

변수 선언 : 변수를 정의하는 것.
let a;

변수 할당 : 연산자 =을 사용해 변수에 값을 넣는 것.
a = 1;

초기화 : 변수에 값을 처음 할당하는 순간.

스코프 : 변수에 접근할 수 있는 범위.
- 전역 스코프
- 지역 스코프 = 함수 스코프
- 블록 스코프 : {}로 감싸진 내부

→ 함수 외부에서 선언
var testA = "outside of function";
console.log(testA); // "outside of function"

→ 함수 내부에서 선언
function newFunction() {
var testB = "inside of function";
console.log(testB); // "inside of function"
}

console.log(testB); // error: testB is not defined; 변수 testB를 함수 내부에서 선언했기 때문에 외부에서는 사용·접근 불가

var 변수

var 변수는 선언·할당·초기화 단계를 동시에 진행하며, 초기화에는 undefined 값이 들어간다. 재선언·중복선언·재할당이 가능하며, 예기치 못한 값을 반환할 수 있기 때문에 잘 사용되지 않는다. 값을 할당하지 않으면 undefined 값이 들어간다.

let 변수

let 변수는 재선언·중복선언이 불가능하지만, 재할당이 가능하다. 값을 할당하지 않으면 undefined 값이 들어간다.

const 변수

const 변수는 반드시 선언과 할당을 동시에 진행해야한다. 재선언·중복선언·재할당이 불가능하기 때문에 변하지 않는 값(상수 등)을 변수에 저장할 때 사용한다.

(상수 : 한 번 정의되면 프로그램이 실행되는 동안 값이 변하지 않는 데이터로 보통 대문자로 표기 (ex. PEACH, ORANGE))

재선언과 중복선언

이 둘은 엇비슷해 보이지만 스코프를 고려해보면 차이가 명확해진다.

  • 재선언 : 같은 스코프 내에서 동일한 변수 이름을 다시 선언하는 경우.
→ ex1) var
var y = 10;
var y = 20;
console.log(y); // 20 출력

→ ex2) let
let z = 40;
let z = 60; // 재선언 불가
console.log(z); // 40 출력
  • 중복선언 : 다른 스코프에서도 동일한 변수 이름을 다시 선언하는 경우.
→ ex1) var
if (true) {
    var s = 10; // 함수 스코프
}
if (true) {
    var s = 50; // 함수 스코프 (var는 블록 스코프를 따르지 않고, 함수 스코프를 따름)
}
console.log(s); // 50 (블록 밖에서도 접근 가능 = 예상치 못한 결과를 초래할 가능성이 있음)

→ ex2) let
if (true) {
    let e = 10;
}
if (true) {
    let e = 50;
}
console.log(e); // ReferenceError: e is not defined (다른 블록 스코프에서 호출했기 때문)

호이스팅

js에서 변수·함수 선언이 코드의 최상단으로 이동된 것처럼 동작하는 현상으로, 실제 코드가 이동한 것은 아니다. 변수·함수 선언이 실제 코드의 실행 전에 처리되므로, 코드를 이해하고 예측하는 데 혼란을 줄 수 있다.

→ 실제 작성 순서
console.log(x); // undefined
var x = 10;
console.log(x); // 10

→ js가 해석하는 순서
var x; // 변수 선언; (호이스팅 현상이 일어나 최상단으로 이동되어 해석됨)
console.log(x); // undefined
var x = 10;
console.log(x); // 10

변수 이름 규칙

식별자 규칙이라고도 불리는데 식별자는 변수, 함수, 클래스 등에 이름을 붙이는 단어를 의미한다. 규칙은 아래와 같다.

  • 공백과 키워드(예약어) 사용 불가
    키워드(예약어) : 이미 특별한 역할을 하고 있는 단어. (ex. let, const, void, return, for, while 등)
  • 특수문자는 _과 $만 사용 가능
  • 숫자로 시작할 수 없음

연산자

대입 연산자 ( = )

= : 똑같다가 아니라 'a는 b다'를 의미

비교 연산자 ( >, >=, <, <=, ==, !=, ===, !== )

< : a가 b보다 작으면 참
<= : a가 b보다 작거나 같으면 참
== : a와 b가 동일하면 참
!= : a와 b가 동일하지 않으면 참
=== : 일치연산자, 변수의 값 뿐만 아니라 자료형까지 같아야 참

논리 연산자 ( !, &&, || )

! : not, 부정을 의미
&& : and, 모든 값이 참이면 참
|| : or, 여러 개 중 하나라도 참이면 참

산술 연산자 ( +, -, *, /, **, % )

% : 나머지 연산자
ex. 홀수 판단 > num % 2 == 1; num을 2로 나눈 후 나머지가 1일 때
ex. 짝수 판단 > num % 2 == 0; num을 2로 나눈 후 나머지가 0일 때
** : 거듭제곱 연산자
ex. 2 ** 3 = 8

증가/감소 연산자 ( ++ / -- )

++ : 변수 값을 1 증가
-- : 변수 값을 1 감소

증가/감소 연산자는 붙이는 위치에 따라 결과가 다르다.

  • 후위 연산자(postfix operator) : 변수에 값을 먼저 대입한 후에 증가/감소 연산을 수행.
let result1;
let num1 = 10,

result1 = num++;
console.log(result1); // 10
console.log(num); // 11
  • 전위 연산자(prefix operator) : 증가/감소 연산을 먼저 수행하고 변수를 대입.
let result2;
let num2 = 20,

result2 = ++num2;
console.log(result2); // 21
console.log(num2); // 21

연산자 줄여 쓰기

코드를 간략하게 사용하기 위해 아래와 같이 줄여 쓰기도 가능하다.
num = num+5num += 5
num = num-5num -= 5
num = num*5num *= 5
num = num/5num /= 5

자료형(datatype)

언어 타입에는 강한 타입 언어와 약한 타입 언어가 있다.
강한 타입 언어는 타입 검사를 통화하지 못하면 실행 자체가 불가능하며 string, int, double 등과 같이 타입을 1 종류로만 명확히 지정한다. (ex. Java, C, C++, C# 등)
약한 타입 언어는 런타임 중 타입 오류를 만나더라도 실행을 막지 않는다. 때문에 타입이 여러 종류인 값들이 상관없이 지정된다. (ex. JavaScript, Python 등)

js는 약한 타입 언어에 속하므로, 강한 타입 언어와 달리 데이터 종류와 관계 없이 var·let·const 키워드로 변수를 선언하고 사용한다.

js의 자료형은 원시 타입(Primitive Type)과 참조 타입(Reference Type)으로 나뉜다.

원시 타입(primitive Type)

  • String : 문자형 데이터, ''(따옴표)를 사용.
  • Number : 숫자형 데이터, 정수 및 소수점 숫자를 표기.
  • Boolean :참/거짓 데이터, true/flase 두 가지 값만 가짐.
  • Null : 빈 데이터, 어떤 값이 의도적으로 비어 있음을 의미할 때 사용.
  • Undefined : 미할당 데이터, 값이 할당되지 않은 상태를 표기.
  • Symbol
  • BigInt

문자와 변수를 동시에 작성하고 싶을 때, 백틱 문자를 사용해 문자 ${변수}의 형식으로 작성하면 된다.

원시 타입은 1) 값 자체가 변수에 저장되고 2) 할당할 때 값이 복사되며 3) 변경이 불가능하다는 특징이 있다.

참조 타입(Reference Type)

원시 타입이 아닌 것은 참조 타입에 속한다. 자주 활용되는 객체는 아래와 같다.

  • Array : 배열 데이터, [ ] 내 인덱스를 가지는 데이터를 순차적으로 저장하는데, 다양한 타입의 값을 저장할 수 있으며 배열 내에 배열을 넣는 것도 가능. 인덱스는 0부터 시작됨.
  • Object : 객체 데이터, {} 내 key와 value 한 쌍의 데이터들을 저장.
  • Function : js에서는 함수도 객체로 취급.

참조 타입은 1) 값이 아닌 참조(메모리 주소)를 변수에 저장되고 2) 때문에 같은 참조를 가진 다른 변수들도 같은 데이터를 공유하며 3) 변경이 가능하다는 특징이 있다.

자료형을 확인하는 키워드, type of

type of 연산자를 사용해 값의 자료형을 확인할 수 있다.

console.log(typeof "hello"); // string
console.log(typeof 2025); // number

형변환

js에서는 자동 형변환이 적용되기 때문에 의도하지 않은 문제가 생길 가능성이 있다. 때문에 개발자가 직접 형변환을 시킬 수 있는데, 이를 명시적 형변환이라고 한다.

문자열로의 형변환

  • String() 함수 : 다양한 타입의 값을 문자열로 변환함.
  • toString() 메소드 : 주로 객체나 배열을 문자열로 변환할 때 사용. 값이 의도적으로 없는 null이나 값이 정의되지 않은 undefined는 toString() 메서드를 사용할 수 없음.
let str1 = true; // boolean
let str2 = 123; // number
let str3 = undefined; // undefined


→ ex) String() 함수
console.log(String(str1), typeof String(str1)); // true string
console.log(String(str2), typeof String(str2)); // 123 string
console.log(String(str3), typeof String(str3)); // undefined string

→ ex) toString() 메소드
console.log(str1.toString(), typeof str1.toString()); // true string
console.log(str2.toString(), typeof str2.toString()); // 123 string

숫자로의 형변환

  • Number() 함수 : 다양한 타입의 값을 숫자로 변환하는데, 숫자로 변환할 수 없는 경우 NaN(Not-a-Number)을 반환함.
  • parseInt() 함수 : 문자열을 정수로 변환하는데, 문자열의 앞부분이 숫자라면 숫자만 변환한 후 값을 반환함. 진법을 지정할 수 있으며, 기본값은 10으로 설정되어 있음.
  • parseFloat() 함수 : 문자열을 소수점 이하를 포함한 숫자로 변환하는데, 문자열의 앞부분이 숫자라면 숫자만 변환한 후 값을 반환함.
let n1 = true; // boolean
let n2 = false; // boolean
let n3 = 123.9; // number

→ ex) Number() 함수
console.log(Number(n1), typeof Number(n1)); // 1
console.log(Number(n2), typeof Number(n2)); // 0
console.log(Number(n3), typeof Number(n3)); // 123.9 - 실수

→ ex) parseInt() 함수
console.log(parseInt(n3, 10)); // n3 값을 10진수의 정수(int)로 바꾸겠다. // 123

→ ex) parseFloat() 함수
console.log(parseFloat(n3)); // n3 값을 실수(float)로 바꾸겠다. // 123.9

값이 의도적으로 없는 null을 숫자로 형변환하면 0을 반환하지만, 값이 정의되지 않은 undefined를 숫자로 형변환하면 NaN을 반환한다.

console.log(Number(null), typeof Number(null)); // 0, number
console.log(Number(undefined), typeof Number(undefined)); // NaN, number

함수(function)

js 함수는 특정 작업을 수행하기 위해 독립적으로 설계된 코드 집합을 의미한다.

함수의 구조

함수는 크게 함수 이름, 매개변수, 본문, 반환값으로 구성된다.

  • 함수 이름 : 함수를 호출할 때 사용되며, 일반적으로 camelCase로 작성함.
  • 매개변수 : 함수에서 전달받을 입력 값으로, 함수를 정의할 때 매개변수를 선언하고, 함수를 호출할 때 매개변수에 값을 전달함.
  • 함수 본문 : 함수가 실행할 때 실제 코드가 들어있는 부분으로, 함수의 동작을 정의. 스코프라고도 함.
  • 반환값 : 함수 내부 코드의 최종 결과 값을 저장하고 보관하기 위한 키워드로 return 키워드를 사용하여 결과를 반환할 수 있으며 생략될 수도 있음. return이 없을 때는 기본적으로 undefined를 반환함. return 키워드를 만나면 함수 실행이 중단됨.

함수 정의(선언)는 함수를 "생성"하는 것을 의미한다.
함수 호출은 함수를 "사용"하는 것을 의미한다.

함수 정의 방식

함수를 정의하는 방식에는 3가지가 있다.

1. 함수 선언문(Function Declaration)

가장 기본적인 함수 정의 방식으로 명시적 함수 선언이라고도 한다. "function" 키워드를 사용하여 함수를 선언하는 방식이며, 함수 이름과 매개변수를 명시하고 함수 본문을 {}로 감싸진 형태이다. 스크립트 어디에서든 호출할 수 있다.

→ ex1)
function helloWorld() {
    console.log('Hello, World!');
}
helloWorld(); // Hello, World!; 

해석 | 함수를 정의 > 반환값이 없으니 return 생략 > 함수 외부에서 함수를 호출(Hello, World! 출력)

→ ex2)
function helloWorld2() {
    return 'Hello, World! 2';
}
console.log(helloWorld2()); Hello, World! 2

해석 | 함수를 정의 > 반환값에 'Hello, World! 2'를 저장 및 보관 > 외부에서 함수를 디버깅(Hello, World! 출력)

2. 함수 표현식 (Function Expression)

"함수"가 변수에 할당되는 형태인데, js에서는 함수도 값이 있는 객체로 취급하기 때문에 가능하다. 익명 함수나 이름을 가진 함수 표현식으로 정의할 수 있고, 이름을 가진 함수의 경우 함수 이름은 내부에서만 사용 가능하다. 변수가 선언된 이후에만 호출 할 수 있다.

→ ex1)
const sayHello = function hello() {
    console.log('hello');
};

sayHello(); // hello;
hello(); // ReferenceError: hello is not defined

해석 | 함수:hello를 변수:sayHello에 할당 > 변수 호출(hello 출력) * 함수 외부에서 함수 호출(사용) 불가능


→ ex2)
const sayHello2 = function () {
    console.log('hello 2');
};

sayHello2(); // hello 2

해석 | return 생략 버전 함수 표현식 > 함수 호출(Hello, World! 3 출력)

→ ex3)
const sayHello3 = function () {
    return 'hello 3';
};

console.log(sayHello3()); // hello 3

해석 | return이 있는 함수 표현식 > 외부에서 함수를 디버깅(Hello, World! 4 출력)

매개변수가 있는 함수의 경우는 아래와 같다.

  • 매개변수가 1개일 때
function food(text) {
    return text;
}
console.log(food('pasta'));

const price = 20000;
console.log(food(price)); // 20000
  • 매개변수가 2개일 때
→ ex1) return 사용
function music(singer, song) {
    return `${singer} - ${song}`;
}

console.log(music('FLO', 'In My Bag')); // FLO - In My Bag

→ ex2) console.log() 사용
function music2(singer, song) {
    console.log(`${singer} - ${song}`);
}
music2('Little Simz', 'Gorilla');

3. 화살표 함수 (Arrow function)

ES6에서 도입된 문법으로 함수 표현식의 축약형으로 "함수명 쓰지 않는다". 단일 표현식의 경우에는 {}와 return 키워드를 생략할 수 있으며, 코드가 길어질 때는 {}와 return 키워드를 명시하는 것이 좋다.

→ ex1) 단일 표현식을 화살표 함수로 바꿔보기
// 단일 표현식
function square(x) {
    return x * x;
}

// 화살표 함수
const square = (x) => x * x;
console.log(square(3)); // 9;

→ ex2) 코드가 긴 표현식을 화살표 함수로 바꿔보기
// 코드가 긴 표현식
function triangle(base, height) {
    const area = (base * height) / 2;
    return area;
}

// 축약형
const triangle = (base, height) => {
    const area = (base * height) / 2;
    return area;
};
console.log(triangle(3, 64)); // 96;

주의점, 호이스팅 현상

앞서 말했던 것처럼 js에서는 변수 및 함수 정의가 해당 범위의 맨 위로 끌어올려지는 호이스팅 현상이 일어난다. "함수 선언문"은 호이스팅의 대상이 되기 때문에, 함수 코드의 가독성을 높이기 위해서는 선언을 가능한 상단에 위치 시키는 것이 좋다.
함수 선언문과 달리 함수 표현식은 호이스팅의 대상이 될 수 없는데, 함수가 변수에 할당되는 형태라 함수 정의 이후에 함수 호출이 가능하기 때문이다.

→ ex1) 함수 선언문
greet(); // welcome!
function greet() {
    console.log('welcome!');
}

→ ex2) 함수 표현식
greet2(); // ReferenceError
const greet2 = () => console.log('welcome! 2');

0개의 댓글