[자바스크립트 문법] 변수, 데이터, ES6 문법

김형빈·2024년 4월 30일
0

자바스크립트 언어의 특징?

  1. 객체지향 프로그램
    • 절차 지향: 순서대로 실행되는 과정을 기술하여 프로그램을 만드는 방법
    • 객체 지향: 데이터와 함수를 객체라는 그룹으로 묶어서 처리하는 방법
  2. 동적 타이핑
    • 런타임 시점에 변수에 할당되는 값에 따라 자동으로 데이터 타입 결정
  3. 함수형 프로그래밍 지원
  4. 비동기 처리
  5. 클라이언트 측 및 서버 측 모두에서 사용가능

변수 선언

  1. var
var myVar = "Hello";
var myVar = "World"; // 재선언 가능
myVar = "!"          // 재할당 가능
console.log(myVar); // "!"
  1. let
let myLet = "Hello";
let myVar = "World";// 오류 발생, 재선언 불가능
myLet = "!";        // 재할당 가능
console.log(myLet); 
  1. const
const myConst = "Hello";
const myConst = "Worle"; // 오류 발생 
myConst = "!";           // 오류 발생
console.log(myConst);

암시적 형변환

  • 암시적 형 변환은 자바스크립트에서 자동으로 수행되는 형 변환이며, 일반적으로 연산자를 사용할 때 발생한다.
  1. 문자열
console.log(1 + "2");   // "12"
console.log("1" + true);   // "1true"
console.log("1" + {});   // "1[object Object]"
console.log("1" + null);   // "1null"
console.log("1" + undefined);   // "1undefined"
  1. 숫자
console.log(1 - "2");   // -1
console.log("2" * "3");   // 6
console.log(4 + +"5");   // 9
  1. 불리언
console.log(Boolean(0));   // false
console.log(Boolean(""));   // false
console.log(Boolean(null));   // false
console.log(Boolean(undefined));   // false
console.log(Boolean(NaN));   // false
console.log(Boolean("false"));   // true
console.log(Boolean({}));   // true

객체

  1. 객체 메소드
    a. Object.keys()

    let person = {
    	name: "홍길동",
    	age: 30,
    	gender: "남자"
    };
    let keys = Object.keys(person);
    console.log(keys);   // ["name", "age", "gender"]

    b. Object.values()

    let person = {
    	name: "홍길동",
    	age: 30,
    	gender: "남자"
    };
    let values = Object.values(person);
    console.log(values);   // ["홍길동", 30, "남자"]

    c. Object.entries()

    let person = {
    	name: "홍길동",
    	age: 30,
    	gender: "남자"
    };
    let entries = Object.entries(person);
    console.log(entries);

    d. Object.assign()

    let person = {
    	name: "홍길동",
    	age: 30,
    	gender: "남자"
    };
    let newPerson = Object.assign({}, person, { age: 35 });
    console.log(newPerson);   // { name: "홍길동", age: 35, gender: "남자" }
  2. 객체비교

  • 객체를 비교할 때는 일반적으로 === 연산자를 사용할 수 없다
  • JSON.stringify() 함수를 사용하여 객체를 문자열로 변환한 후, 문자열 비교를 할 수 있다
let person1 = {
  name: "홍길동",
  age: 30,
  gender: "남자"
};

let person2 = {
  name: "홍길동",
  age: 30,
  gender: "남자"
};

console.log(person1 === person2);   // false
console.log(JSON.stringify(person1) === JSON.stringify(person2));   // true

데이터 타입

기본형과 참조형을 나누는 기준: "불변성"


(이미지 출처: https://velog.io/@imjkim49/자바스크립트-데이터-타입-정리)

기본형 데이터의 변수 선언과 데이터 할당

1. 변수 선언

/** 선언과 할당을 풀어 쓴 방식 */
var str;
str = 'test!';

/** 선언과 할당을 붙여 쓴 방식 */
var str = 'test!';

2. 데이터 할당


(이미지 출처: 스파르타 코딩 클럽, JavaScript 문법 종합반)

  1. 변수 영역에서 빈 공간(@1002) 확보
  2. 확보한 공간의 식별자를 str로 지정
  3. 데이터 영역의 빈 공간(@5004)에 문자열 'test' 저장
  4. 변수영역에서 a라는 식별자를 검색한다(@1002)
  5. 앞서 저장한 문자열의 주소(@5004)를 @1002의 공간에 대입한다.

3. 값을 바로 변수에 대입하지 않는 이유

자유로운 데이터 변환

  • 이미 입력한 문자열이 길어진다면?
    • 예시 속 1002번에 있는 데이터가 1004번까지 길어진다면??
    • 기존의 1003, 1004번에 있는 데이터까지 이동해야 한다...
  • 숫자는 8byte로 고정이지만, 문자는 고정이 아님(영문: 1byte, 한글: 2byte)

메모리의 효율적 관리
메모리 주소 공간의 데이터는 자료형 중 작은 편인다.

  • 똑같은 데이터를 여러번 저장해야 한다면?
  • Ex) 1만개의 변수를 생성해서 모든 변수에 숫자 1(8byte)을 할당하는 상황
    • 바로 대입하는 경우:
      • 1만개 * 8byte = 8만 byte
    • 변수 영역 + 데이터 영역:
      • (1만개 * 2byte) + (8byte) = 2만 8byte

etc. 변수 vs 상수

변수 영역에서 변경 가능 여부에따라

변수상수
변경 가능변경 불가능

etc. 불변하다 vs 불변하지 않다

데이터 영역에서 변경가능 여부에 따라

불변하지 않다불변하다
변경 가능변경 불가능

참조형 데이터의 변수 선언과 데이터 할당

1. 할당 예시

// 참조형 데이터는 별도 저장공간(obj1을 위한 별도 공간)이 필요합니다!
var obj1 = {
	a: 1,
	b: 'bbb,
};


(이미지 출처: 스파르타 코딩 클럽, JavaScript 문법 종합반)

2. 기본형 데이터의 변수 할당 과정과 차이점

- 객체의 변수(프로퍼티) 영역의 별도 존재 여부

3. 참조형 데이터가 불변하지 않다(가변하다)라고 하는 이유!

// 데이터를 변경!
obj.1.a = 2;

  • 데이터 영역에 저장된 값은 계속 불변값이지만, obj1을 위한 별도 영역은 얼마든지 변경 가능하다

4. 중첩 객체의 할당

  • 중첩 객체:
    • 객체 안에 또 다른 객체가 들어가는 것을 말한다
  • 객체는 배열, 함수 등을 모두 포함하는 상위개념이긴 때문에 배열을 포함하는 객체도 중첩 객체이다
var obj = {
	x: 3,
	arr: [3, 4, 5],
}

5. 참조 카운트가 0인 메모리 주소의 처리

  • 참조카운트란?
    • 객체를 참조하는 변수나 다른 객체의 수를 나타내는 값이다
    • 객체가 0인 객체는 더 이상 사용되지 않으므로, 가비지 컬렉터에 의해 메모리에서 제거된다
  • 가비지컬렉터
    • 더 이상 사용되지 않는 객체를 메모리에서 제거하는 역할

변수 복사의 비교

// STEP01. 선언 
var a = 10; //기본형
var obj1 = { c: 10, d: 'ddd' }; //참조형

// STEP02. 복사
var b = a; //기본형
var obj2 = obj1; //참조형

// STEP03. 복사 이후 값 변경
b = 15;
obj2.c = 20;

변수 복사 시 주요한 절차의 차이점

  • 기본형
    • 숫자 15라는 값을 데이터 영역에서 검색 후 없다면 생성
    • 검색한 결과주소 또는 생성한 주소를 변수 영역 b에 갈아끼움
    • a와 b는 서로 다른 데이터 영역의 주소를 바라보고 있기 때문에 영향 없음
  • 참조형
    • 숫자 20이라는 값을 데이터 영역에서 검색 후 없다면 생성
    • 검색한 결과주소 또는 생성한 주소 obj2에게 지정되어 있는 별도 영역(7103~)에 갈아끼움
    • obj1도 똑같은 주소를 바라보고 있기 때문에 obj1까지 변경이 됨
    		// 기본형 변수 복사의 결과는 다른 값!
    		a !== b;
    		// 참조형 변수 복사의 결과는 같은 값!(원하지 않았던 결과😭)
    		obj1 === obj2;

복사 이후 값 변경(객체 자체를 변경)

  • obj2 변수는 참조형 데이터이고, 참조형 데이터의 값을 변경한 것임에도 불고하고 이전 케이스와는 다르게 obj1과는 바라보는 데이터 메모리 영역의 값이 달라졌다

불변 객체

  • 객체 데이터 자체를 변경(새로운 데이터를 할당)하고자 한다면 기존 데이터는 변경되지 않는다

객체 가변성에 따른 문제점

// user 객체를 생성
var user = {
	name: 'wonjang',
	gender: 'male',
};
// 이름을 변경하는 함수, 'changeName'을 정의
// 입력값 : 변경대상 user 객체, 변경하고자 하는 이름
// 출력값 : 새로운 user 객체
// 특징 : 객체의 프로퍼티(속성)에 접근해서 이름을 변경했다 -> 가변
var changeName = function (user, newName) {
	var newUser = user;
	newUser.name = newName;
	return newUser;
};
// 변경한 user정보를 user2 변수에 할당
// 가변이기 때문에 user1도 영향을 받게 된다
var user2 = changeName(user, 'twojang');
// 결국 아래 로직은 skip하게 된다
if (user !== user2) {
	console.log('유저 정보가 변경되었습니다.');
}
console.log(user.name, user2.name); // twojang twojang
console.log(user === user2); // true

해결책 1 (얕은 복사)

var copyObject = function (target) {
	var result = {};

	// for ~ in 구문을 이용하여, 객체의 모든 프로퍼티에 접근할 수 있습니다.
	// 하드코딩을 하지 않아도 괜찮아요.
	// 이 copyObject로 복사를 한 다음, 복사를 완료한 객체의 프로퍼티를 변경하면
	// 되겠죠!?
	for (var prop in target) {
		result[prop] = target[prop];
	}
	return result;
}
var user = {
	name: 'wonjang',
	gender: 'male',
};
//
var user2 = copyObject(user);
user2.name = 'twojang';
//
if (user !== user2) {
	console.log('유저 정보가 변경되었습니다.');
}
//
console.log(user.name, user2.name);
console.log(user === user2);
  • 그러나 중첩된 객체의 경우 참조형 데이터가 저장된 프로퍼티를 복사할 때, 주소값만 복사하게 된다

해결책2 (깊은 복사)

var copyObjectDeep = function(target) {
	var result = {};
	if (typeof target === 'object' && target !== null) {
		for (var prop in target) {
			result[prop] = copyObjectDeep(target[prop]);
		}
	} else {
		result = target;
	}
	return result;
}
//결과 확인
var obj = {
	a: 1,
	b: {
		c: null,
		d: [1, 2],
	}
};
var obj2 = copyObjectDeep(obj);
//
obj2.a = 3;
obj2.b.c = 4;
obj2.b.d[1] = 3;
//
console.log(obj);
console.log(obj2);

undefined와 null

1. undefined
  • 일반적으로는 자바스크립트 엔진에서 값이 있어야 할 것 같은데 없는 경우, 자동으로 부여한다

    var a;
    console.log(a); // (1) 값을 대입하지 않은 변수에 접근
    //
    var obj = { a: 1 };
    console.log(obj.a); // 1
    console.log(obj.b); // (2) 존재하지 않는 property에 접근
    // console.log(b); // 오류 발생
    var func = function() { };
    var c = func(); // (3) 반환 값이 없는 function
    console.log(c); // undefined
  1. null
  • 용도 : ‘없다’를 명시적으로 표현할 때

  • 주의 : typeof null object인 것은 유명한 javascript 자체 버그이다

    var n = null;
    console.log(typeof n); // object
    //동등연산자(equality operator)
    console.log(n == undefined); // true
    console.log(n == null); // true
    //일치연산자(identity operator)
    console.log(n === undefined);
    console.log(n === null);

do ~ while문

  • do...while문은 일단 한 번은 코드를 실행하고, 그 후에 조건식을 체크하여 반복 여부를 결정한다
let i = 0;

do {
  console.log(i);
  i++;
} while (i < 10);

es6 문법

  1. let, const

  2. 화살표 함수

  3. 삼항 연산자

  4. 구조분해 할당

  5. 단축 속성명

    • 객체의 key와 value 값이 같다면, 생략 가능하다
    const name = "nbc"
     const age = "30"
     const obj = {
    	name,
    	age: newAge
    }
     const obj = {
    	name,
    	age
    }
  6. spreadOperator

  7. 나머지 매개 변수

  8. 템플릿 리터럴

profile
The secret of getting ahead is getting started.

0개의 댓글