상세 컨텐츠

본문 제목

[리액트 스타터2] 1장. 자바스크립트 기초

23-24/React.js 2

by YUZ 유즈 2023. 9. 29. 10:00

본문

728x90

1. 함수(Function)

 

< 함수 선언 >

  •  'function' 키워드를 사용해 함수 선언한다.
fuction 함수 이름 (매개변수) {
	함수가 수행하는 명령
}
  • 인수: 함수를 호출하면서 넘겨주는 값이다.
  • 매개변수: 넘겨받은 인수를 저장할 변수이다.

 

< 함수 호출 >

fuction 함수 이름 (매개변수) {
	함수가 수행하는 명령
}
함수 이름(); //함수 호출문

 

< 함수 반환 >

  • return문으로 수행한 결과 반환한다.
  • 함수 내에서 return문을 만나면 함수는 종료한다.
function getArea(width, height) {
	let area = width * height;
	return area; // 수행한 결과 반환
}
let result = getArea(10, 20);
console.log(result);

 

< 중첩 함수 >

  • 자바스크립트는 함수 내에 또 다른 함수를 선언할 수 있다.
  • 중첩 함수: 특정 함수 내부에서 선언된 함수이다.
  • 단점: 가독성을 헤치는 경향이 있다
  • 장점: 적절히 활용하면 함수 내에서 서로 역할 분담이 가능하다. 그 결과 중복 코드 방지에 도움이 된다.
function greeting() {
	function greetingWithName(name) { //중첩 함수
		console.log('hello! ${name}'); //이름을 전달받아 템플릿 리터럴을 이용해 인사말 출력
	}
    let name = "김덕성";
    greetingWithName(name);
}
greeting();

 

< 호이스팅 >

  • 호이스팅(hoisting): 프로그램에서 변수나 함수를 호출하거나 접근하는 코드가 함수 선언 코드보다 위에 있으매도 불구하고, 마치 선언 코드가 위에 있는 것처럼 동작하는 자바스크립트만의 독특한 기능이다.
  • 이러한 기능이 존재하는 이유는 자바스크립트의 내부 알고리즘 때문이다. 자바스크립트는 코드 실행 전 준비 단계를 거친다. 준비 단계에서 중첩 함수가 아닌 함수들은 모두 찾아 미리 생성해 둔다. 따라서 함수 선언 코드를 호출보다 늦게 작성해도 자연스럽게 호출 가능하다.
  • 호이스팅은 코드 내에서 함수 선언의 위치를 강제하지 않기 때문에 더 유연한 프로그래밍 작성에 도움이 된다.
func(); //선언하기 전에 호출해도 오류 발생 x
function func() {
	console.log("hello");
}

 

< 함수 표현식 >

  • 함수 표현식: 함수 선언 외에 함수를 만드는 방법이다. 함수를 생성하고 변수에 값으로 저장한다.
  • 자바스크립트에서는 함수를 숫자나 문자열처럼 취급한다. 따라서 변수에 함수를 저장할 수 있다. 변수에 함수를 저장하면 변수 이름으로 함수를 호출할 수 있다.
let greeting = function () { //변수의 이름인 greeting으로 호출 -> 이름 없어도 됨.
	console.log("hello");
};
greeting();
  • 익명 함수: 이름을 정의하지 않은 함수이다.
function greetFunc() {
	console.log("hello");
}
greetFunc();
let greeting = greetFunc; //선언한 함수를 변수에 저장. 저장 시 호출과 달리 소괄호 x
greeting();
funcA(); //output: "hello"
funcB(); //error: funcB는 정의되지 않았으며 함수가 아님.
function funcA() {
	console.log("func A");
}
let funcB = function () {
    console.log("func B");
};
  • funcA는 함수 선언으로 만들었기 때문에 호이스팅 대상이므로 함수 선언 전에도 호출 가능하다. 하지만 funcB에 저장한 함수는 호이스팅 불가하다. 왜냐하면 함수표현식을 사용하여 저장한 함수는 선언이 아닌 '값'으로 취급하기 때문이다. 이에 주의해야 한다.

 

< 콜백 함수 >

  • 콜백 함수: 다른 함수의 인수로 전달하는 함수이다.
  • 고차 함수: 콜백 함수를 인수로 받는 함수이다.
function parentFunc(callBack) { //고차함수. 매개변수 callback에 함수 childFunc 저장
	console.log("parent");
	callBack();
}
function childFunc() { //이 코드에서 콜백함수
	console.log("child");
}
parentFunc(childFunc);

 

< 화살표 함수 >

  • 화살표 함수: 익명 함수를 매우 간결하게 작성할 때 사용하는 함수 표현식의 단축 문법이다.
let funcA = (매개변수) => 반환값;
  • ex: 화살표 함수를 콜백 함수로 작성하는 경우이다.
let isConfirm = true;
function confirm(onYes, onNo) {
    if (isConfirm) onYes();
    else onNo();
}
confirm(
    () => console.log("승인"), 
    () => console.log("거부") 
);
// 출력: 승인

 

2. 스코프(Scope)

 

< 전역 스코프와 지역 스코프 >

  • 전역 스코프: 코드 어디에서나 접근 가능하다.
    • ex1: 변수가 조건문이나 반복문, 함수의 중괄호 내부가 아닌 곳에 선언되었다면 함수 외부의 변수라도 함수 내부에서 접근 가능하다.
    • 전역 변수: 전역 스코프를 갖는 변수이다.
  • 지역 스코프: 특정 영역에서만 접근 가능하다.
    • ex2: 변수가 조건문이나 반복문, 함수 내부에 선언되었다면 함수 외부에서 그 변수에 접근할 수 없다.
    • 지역 변수: 지역 스코프를 갖는 변수이다.
  • 변수가 아닌 함수도 같은 논리로 스코프를 갖는다.

 

< 블록 스코프와 함수 스코프 >

  • 블록(Block): 중괄호롤 둘러싸인 부분이다.
  • 자바스크립트의 변수나 함수는 블록을 기준으로 지역 스코프가 결정된다.
  • 블록 스코프(Block scope): 블록을 기준으로 지역 스코프를 정한다. 블록 내부에서 선언한 변수가 갖는 스코프이다. let이나 const 키워드로 선언한 변수의 경우 블록 스코프를 갖는다.
  • 함수 스코프(Fucntion scope): 함수를 기준으로 지역 스코프를 정한다. 함수 내부에서 선언한 변수가 갖는 스코프이다. var 키워드로 선언한 변수의 경우 함수 스코프를 갖는다.

 

3. 객체

 

  • 객체: 숫자형이나 문자형과 같은 원시 자료형과 달리 다양한 값을 담는 자료형이다.

< 객체 생성과 프로퍼티 >

  • 객체 리터럴 문법: 빈 중괄호를 할당해 객체를 생성한다.
  • 객체 생성자 문법: new Object();를 이용해 객체를 생성한다.
let objA = {}; // '객체 리터럴' 문법
let objB = new Object(); // '객체 생성자' 문법
  • 프로퍼티: 속성이라는 뜻으로 객체를 설명하는 정보이다. key와 value 쌍으로 이루어진다. 객체는 프로퍼티를 여러 개 가질 수 있으며 각각은 콤마로 구분한다.
  • 프로퍼티의 value 값은 여러 자료형으로 구현 가능하다. 하지만 key는 반드시 문자형만 사용한다.
  • 하나의 key가 하나의 프로퍼티에 해당한다. 보통 key 이름으로 프로퍼티를 구별한다. 만약 복수의 단어로 이루어진 key를 사용하려면 반드시 따옴표로 묶어 주어야 한다.  (key가 중복돼도 오류가 발생하지는 않지만 객체에 마지막에 작성한 프로퍼티만 남는다.)

< 객체의 프로퍼티 다루기 >

  • 프로퍼티 접근
    • key를 이용하면 객체의 프로퍼티에 접근 가능하다.
    • 점 표기법: 객체 이름 뒤에 점(.)을 찍고 프로퍼티의 key를 명시해 해당 프로퍼티의 value에 접근한다.
    • 괄호 표기법: 객체 이름 뒤에 대괄호([])를 열고, 그 안에 원하는 프로퍼티의 key를 문자열로 명시하여 해당 프로퍼티의 value에 접근한다.
  • 프로퍼티 추가
    • 점 표기법과 괄호 표기법을 이용해 새로운 프로퍼티 추가 가능하다.
    • 추가하려는 프로퍼티의 key가 고정적이라면 점 표기법을 이용하는 것이 간단하다.  key가 변수에 저장된 값처럼 유동적이라면 괄호 표기법을 이용한다.
  • 프로퍼티 수정
    • 프로퍼티의 value를 수정할 때에도 점 표기법이나 괄호 표기법을 이용한다.
  • 프로퍼티 삭제
    • 프로퍼티를 삭제할 때에는 delete를 사용하 점 표기법이나 괄호 표기법을 이용한다. 

 

< 상수 객체의 프로퍼티 >

  • const로 선언한 상수는 값을 변경할 수 없다. 하지만 상수로 선언한 객체는 객체 자체를 없애지 않는 한, 프로퍼티를 추가하거나 수정하는 등의 내용 조작이 가능하다.

 

< in 연산자 >

  • 객체에 존재하지 않는 프로퍼티에 접근하면 undefined를 반환한다. 이러한 객체의 특징을 이용해 특정 프로퍼티의 존재 여부를 확인할 수 있다. 
let person = {
	age: 10
};
let isNameExist = "name" in person; // in 연산자
console.log(isNameExist); // 출력: false
  • in 연산자 왼쪽에 존재 여부를 확인하려는 프로퍼티의 key를 문자열로 명시하고, 오른쪽에 객체를 명시하면 존재를 확인할 수 있다.

 

< 메서드 >

  • 메서드: 객체에서 값(value)이 함수인 프로퍼티이다. 메서드는 데이터가 아니라 객체의 동작을 정의한다.

 

4. 배열

  • 배열: 순서가 있는 요소의 집합이자 여러 개의 항목을 담는 리스트이다.

< 배열 선언 >

  • 배열 생성자, 배열 리터럴 2가지 방법이 있다.
let arrA = new Array(); // 배열 생성자
let arrB = []; // 배열 리터럴
  • 배열을 생성하면서 값도 할당할 경우, 대괄호 안에서 콤마로 값을 구분해 입력한다.
  • 배열의 값으로 어떤 자료형도 사용 가능하다. 배열은 다른 배열은 물론 객체나 함수 등 모두 저장한다.
  • 자바스크립트의 배열은 다른 언어와 달리 길이가 고정되어 있지 않아서 배열 요소를 추가 또는 삭제함에 따라 길이가 늘거나 줄어든다.

 

< 배열 인덱스 >

  • 배열과 객체는 둘 다 여러 데이터를 저장할 수 있고, 저장할 데이터의 자료형에 아무런 제약이 없다. 배열과 객체의 한 가지 차이점은 객체는 key가 있지만 배열은 없다.
  • 배열은 데이터의 위치를 key처럼 사용할 수 있는 인덱스가 있다. 배열에서 특정 데이터에 접근하려면 데이터의 위치를 나타내는 인덱스를 객체의 괄호 표기법처럼 사용한다.
  • 인덱스: 배열 요소의 위치를 0부터 시작하는 숫자로 순서대로 표현한 것이다. 인덱스를 이용하면 배열 요소를 수정 또는 추가 가능하다.

 

5. truthy&falsy

  • truthy&falsy: 자바스크립트의 불리언 자료형의 참이나 거짓이 아닌 값도 상황에 따라 참, 거짓으로 평가하는 특징을 의미한다.

< truthy & falsy 한 값 >

  • falsy 한 값: 불리언 자료형의 거짓(false)은 아니지만 거짓과 같은 의미로 쓰이며, 조건식에서 거짓으로 평가한다.
    • undefined, null, 0, -0, NaN, "", 0n 7가지가 있다.
      • 0n: BigInt 자료형의 값. BigInt는 길이 제약 없이 정수를 다룰 수 있는 숫자 자료형.
  • falsy 한
    • falsy한 값을 제외한 모든 값은 truthy한 값이다.

 

< truthy & falsy 응용하기 >

  • truthy 또는 falsy한 값은 조건식을 간결하게 만든다.

 

  • undefined나 null 값 모두 falsy 하기 때문에 조건문에서 특정 변수에 값이 있는지 없는지 확인할 때 사용한다.
let varA; //undefined값이므로 falsy한 값 -> 조건문에서 거짓으로 평가
if (varA) {
	console.log("값이 있음");
} else {
	console.log("값이 없음"); // 출력: 값이 없음
}

 

  • 숫자 자료형에서는 0과 -0 그리고 NaN을 제외한 모든 값은 truthy 하므로 조건문에서 특정변숫값이 0, -0 또는 NaN인지 확인할 때 사용한다.
const num = -0;
if (num) {
	console.log("양수이거나 음수입니다.");
} else {
	console.log("0이거나 -0이거나 NaN입니다."); // 출력: 0이거나 -0이거나 NaN입니다.
}

 

  • 빈 문자열을 제외한 모든 문자열은 truthy한 값이므로 문자열이 공백인지 아닌지 확인하는 용도로 자주 사용한다.
const str = "";
if (str) {
	console.log("공백 아님");
} else {
	console.log("공백임"); // 출력: 공백임
}

 

6. 단락 평가

  • 단락 평가(Short-Circuit Evaluation)(=지름길 평가): 논리 연산에서 첫 번째 피연산자의 값만으로 해당 식의 결과가 확실할 때, 두 번째 값은 평가하지 않는 것을 의미한다.
    •  true || false와 같은 비교식은 첫 번째 피연산자의 값이 true이므로 두 번째 피연산자의 값이 무엇이든 연산 결과는 true이다.
    • false && true와 같은 식은 첫 번째 피연산자의 값이 false이므로 두 번째 피연산자가 무엇이든 연산 결과는 false이다.

< AND 단락평가 >

  • AND를 의미하는 && 연산자는 피연사자의 값이 하나라도 거짓이면 거짓을 반환한다. 따라서 왼쪽에 위치한 첫 번째 피연산자의 값이 flase면, 단락 평가를 해서 두 번째 피연산자는 계산하지 않는다.
  • AND 단락 평가를 이용해 오류 방지하기
    • 단락 평가는 불리언이 아닌 truthy & falsy한 값을 사용할 때도 적용 가능하다.
    • 아래 코드의 경우, 매개변수 person의 값이 false 또는 falsy 한 값이라면 단락 평가를 수행한다. 따라서 매개변수 person이 객체가 아닌 경우  person.name처럼 점 표기법으로 접근하면 생기는 오류를 방지할 수 있다.
function getName(person) {
	return person && person.name;
}
let person = { name: "김덕성" };
let name1 = getName(undefined); // undefined
let name2 = getName(null); // null
let name3 = getName(person); // 김덕성
console.log(name1);
console.log(name2);
console.log(name3);

 

< OR 단락평가 >

  • OR 연산을 의미하는 || 연산자는 피연산자의 값이 하나라도 참이면 참을 반환한다. 왼쪽에 위치한 첫 번째 피연산자의 값이 true면, 단락 평가가 이루어져 두 번째 피연산자 값은 계산하지 않는다.
  • AND처럼 OR 단락 평가 역시 불리언이 아닌 truthy & falsy한 값을 사용할 때도 적용 가능하다.
  • OR 단락 평가와 null 병합 연산자
    • ||의 단락 평가는 null 병합 연산자와 유사한 듯 보이지만 혼동해서는 안 된다. null 병합 연산자는 값이 null이나 undefined가 아닌 피연산자를 찾는다. 따라서  truthy와 falsy로 동작하는 || 연산자와는 엄밀히 다른 동작을 수행한다.

 

7. 객체 자료형

< 배열과 함수가 객체인 이유 >

  • 자바스크립트의 자료형은 원시 자료형과 객체 자료형으로 구분된다. 원시 자료형을 제외한 모든 자료형(배열과 함수 포함)은 객체 자료형이다.
  • 자바스크립트의 배열은 객체 자료형에 몇 가지 기능을 추가해 다른 언어의 배열처럼 동작하는 특수한 객체라 할 수 있다. 따라서 자바스크립트의 배열에는 일반 객체에 있는 프로퍼티와 메서드가 있다.
    • ex: 자바스크립트의 배열에는 길이를 나타내는 length 프로퍼티가 있다.
  • 자바스크립트의 함수 또한 객체이다. 함수는 값으로 취급한다. 따라서 함수를 값으로 저장하는 함수 표현식이 가능하고, 다른 함수에 인수로 전달 가능하다.
    • ex: 함수에도 함수의 이름을 저장하는 name 프로퍼티가 있다.

 

< 객체와 참조 >

  • 원시 자료형은 하나의 값을 저장하지만 함수와 배열 같은 객체 자료형은 여러 개의 값을 저장한다.
  • 원시 자료형은 값을 크기가 일정한 공간에 저장하지만 객체 자료형은 값이 동적으로 늘어나거나 줄어들기 때문에 일정한 크기의 공간에 저장할 수 없다.
    • 객체 자료형은 값의 크기가 유동적으로 변하기 때문에 자바스크립트는 참조라는 기능을 이용한다.
      • 참조(Reference): 실제로 값을 저장하는 것이 아니라 값을 저장한 곳의 주소만 저장하는 방식이다.
  • 원시 자료형과 객체 자료형의 저장 방식 비교
    • 원시 자료형: 값을 변수에 저장할 때 값 그대로 저장한다.
    • 객체 자료형(=참조 자료형): 객체가 메모리 어딘가에 저장되고 변수가 객체를 참조할 수 있는 주솟값(=참좃값)을 저장한다.
  • 참조에 의한 비교
    • 객체 자료형은 원시 자료형과 저장 방식이 다르기 때문에 값을 비교하는 방법도 다르다.
    • 참조에 의해 객체를 비교할 때는 값이 아닌 참좃값을 비교한다.
    • 배열이나 함수도 객체이므로 아래 코드와 동일한 결과가 나타난다.
let person = {
	name: "김덕성"
};
let man = {
	name: "김덕성"
};
console.log(person === man); // false: 각 객체의 참좃값은 고유하므로 내부적인 값이 같지만 참좃값이 다르기 때문.

 


 

8. 반복문 응용

  • 반복문을 이용하면 배열과 객체에 저장한 값에 쉽게 접근할 수 있다.

< 배열과 반복문 >

  • 배열은 순서대로 데이터를 저장하는 특징이 있어 웹 서비스 게시판이나 피드의 게시물 리스트를 생성할 때 반복문과 결합해 자주 사용한다.
  • 인덱스를 이용한 순회
    • 배열의 인덱스를 0부터 1씩 증가하며 차례대로 데이터에 접근하면 배열의 모든 요소에 접근 가능하다
    • 자바스크립트의 배열은 저장 요소의 개수에 따라 길이가 자동으로 늘어나고 줄어드는 동적인 특징이 있다. 따라서 프로그램을 실행하는 과정에서 배열의 길이를 가늠하기가 어렵다. → 프로퍼티 length를 이용하면 쉽게 배열의 현재 길이를 알아내서 더 안전하게 for 문과 결합해 사용할 수 있다.
    • for 문과 프로퍼티 length를 이용해 배열을 순회할 때 주의할 점: 프로퍼티 length는 배열의 길이를 반환할 뿐, 마지막 인덱스 번호는 반환하지 않는다. 자바스크립트에서 인덱스는 항상 0부터 시작하므로 마지막 요소의 인덱스는 배열의 길이보다 1 작다. 따라서 반복문의 종료 조건은 i <= food.length가 아니라 i < food.length로 설정해야 한다.
let food = ["짜장면", "피자", "치킨"];
for (let i = 0; i < food.length; i++) {
	console.log(food[i]);
}
// 짜장면
// 피자
// 치킨
  • for...of 문을 이용한 순회
    • 프로퍼티 length를 사용하지 않고 배열을 순회하는 방법이다. for 문의 특수한 형태인 for... of 문은 배열을 더 간결하게 순회한다.
    • for... of 문은 for 문과 달리 of 뒤의 배열에서 요소를 하나씩 순서대로 꺼내 변수에 저장한다.
let food = ["짜장면", "피자", "치킨"];
for (let item of food) {
	console.log(item);
}
// 짜장면
// 피자
// 치킨

< 객체와 반복문 >

  • Object.keys를 이용한 key 순회
    • 객체 메서드인 Object.keys는 객체 프로퍼티의 key를 배열로 반환한다.
    • Object.keys를 이용해 만든 key 배열을 for...of 문으로 순회한다.
    • 괄호 표기법으로 프로퍼티의 key뿐만 아니라 value도 가능하다.
let person = {
	name: "김덕성",
	age: 103,
	location: "서울"
};
const keyArr = Object.keys(person); //person 객체의 key를 배열로 반환
for (let key of keyArr) { //for...of 문으로 순회
	let value = person[key];  //괄호 표기법으로 value 접근
	console.log(key, value);
}
// name 김덕성
// age 103
// location 서울
  • Object.values를 이용한 value 순회
    • Object.values 메서드는 프로퍼티의 value만 배열로 반환한다.
let person = {
	name: "김덕성",
	age: 103,
	location: "서울"  
};
const valueArr = Object.values(person); //객체 프로퍼티의 value만  배열로 반환
for (let value of valueArr) { //for...of문으로 순회
	console.log(value);
}
// 김덕성
// 103
// 서울
  • for...in 문을 이용한 순회
    • 배열을 순회할 때의 for...of 문처럼, 객체를 순회할 때는 for...in 문을 사용한다. for...in 문으로 객체를 순회하면, for 문보다 더 간결한 코드를 작성 가능하다.
    • for...in 문은 in 오른쪽에 있는 객체에서 프로퍼티의 key를 하나씩 순서대로 변수 key에 저장한다. 즉, 객체 프로퍼티의 key를 순회한다.
    • for...in 문을 사용하면 Object.keys 메서드보다 더 간단하게 객체를 순회.
let person = {
	name: "김덕성",
	age: 103,
	location: "서울"
};
for (let key in person) { //for...in문이 프로퍼티의 key를 변수에 하나씩 저장
	const value = person[key];
	console.log(key, value);
}
// name 김덕성
// age 103
// location 서울


 

Quiz

  1.            )이란 프로그램에서 변수나 함수를 호출하거나 접근하는 코드가 함수 선언 코드보다 위에 있으매도 불구하고, 마치 선언 코드가 위에 있는 것처럼 동작하는 자바스크립트만의 독특한 기능이다.
  2. 블록 스코프를 갖는 변수는      )이나          ) 키워드로 선언한 변수이다. 함수 스코프를 갖는 변수는 (      ) 키워드로 선언한 변수이다.
  3. (               )의 왼쪽에 존재 여부를 확인하려는 프로퍼티의 key를 문자열로 명시하고, 오른쪽에 객체를 명시해서 객체의 존재를 확인할 수 있다.
  4. 배열의 요소를 수정 또는 추가할 때에는         )를 이용하면 된다.
  5. falsy한 값은                ), null, 0, -0, NaN,      ), 0n 7가지이다.
  6. 단락 평가는 불리언이 아닌                        )을 사용할 때도 적용 가능하다.
  7. 객체 자료형은 객체가 메모리 어딘가에 저장되고 변수가 객체를 참조할 수 있는 (          )을 저장한다.
  8.                 ) 메서드는 인수로 전달한 객체에서 프로퍼티의 key만 배열로 만들어 반환한다.
        

  1. 함수 표현식으로 작성한 콜백 함수를 이용해 원하는 횟수만큼  짝수만 출력하는 함수를 작성해보세요. (output: 2 4 6 8...)
  2. 자유롭게 객체를 생성하고 Object.keysfor...of문을 이용해 key와 value를 하나씩 출력하는 코드를 작성해 보세요. (output: key1 value1, key2 value2, key3 value3...)

 


호이스팅 / let / const / var / in 연산자 / 인덱스 / undefined / " "(빈 문자열) / truthy & falsy 한 값 / 참좃값(주솟값) / Object.keys

 

function repeat(count, callBack) {
    for (let idx = 0; idx < count; idx++) {
        callBack(idx + 1);
    }
}
const double = function (count) { 
    console.log(count * 2); // 출력 : 2 4 6 8 10
};
repeat(5, double);

 

let person = {
    name: "김덕성",
    age: 103,
    location: "서울"
};
const keyArr = Object.keys(person);
for (let key of keyArr) {
    let value = person[key]; 
    console.log(key, value);
}
// name 김덕성
// age 103
// location 서울

출처: 이정환, 『한 입 크기로 잘라먹는 리액트』, 프로그래밍인사이트(2023), p2-67.

Editor: minyong

728x90

관련글 더보기