JavaScript 기초 문법(2)

경용·2022년 6월 23일
0

JavaScript

목록 보기
2/4

자료형

  • 목적에 따라 특별한 성질이나 정해진 범주를 갖고 있는 데이터의 종류
  • 자바스크립트에서는 6가지의 원시 타입 자료형과 1가지의 객체 타입 자료형으로 구성

typeof

  • typeof는 인수의 자료형을 반환하는 연산자
  • 연산자인 typeof x와 함수인 typeof(x)로 문법 지원
console.log(typeof undefined); // output: undefined
console.log(typeof 123); //output: number
console.log(typeof 456n); //output: bigint
console.log(typeof true); //output: boolean
console.log(typeof "hello"); //output: string
console.log(typeof Symbol("id")); //output: symbol
console.log(typeof Math); //output: object
console.log(typeof null); //output: object
console.log(typeof console.log); //output: function

boolean

  • 논리적인 값을 표현하는 자형
  • 참인 true와 거짓인 false, 두가지 값만 존재
  • 주로 조건문 등에서 동작 판단의 기준으로 사용
let name_check = true; // 네, name 입력이 확인되었습니다.
let age_check = false; // 아니오, age 입력이 확인되지 않았습니다.

let value_check = 10 > 3; // 비교 결과: 참 > true
console.log(value_check); // output: true

null & undefined

null

  • 값이 비어 있다는 의미로 표현되는 자료형
  • 존재하지 않는(nothing), 비어있는(empty), 알 수 없는(unknown) 값을 나타내는데 사용
console.log(typeof null); //output: object < 하위 버전 호환성으로 object로 표기

const null_check = null;
console.log(null_check === null); //output: true

undefined

  • 값이 할당되어 있지 않은 상태를 나타날 때 사용되는 자료형
  • 변수 선언 후 초기화 하지 않는다면, undefined가 자동으로 할당
let name; //할당 후 초기화 하지 않음

console.log(name); //output: undefined

number

  • number(숫자형)은 정수, 부동소수점(floating point) 숫자를 표현하는 자료형
  • number와 관련된 연산은 사칙연산이 대표적
  • 일반적인 숫자 외에 Infinity, -Infinity, Nan(Not a Number)같은 특수 숫자 값이 포함
  • 2⁵³ - 1 보다 큰 값을 사용할 수 없으며, 더 큰 정수를 다루고 싶다면 bigint 자료형 사용 필요
let num_1= 123.0;
let num_2= 123.456;
let num_3= 1 / 0;
let num_4= 123456n; // BigInt("123456")

console.log(num_1 - num_2); //output: -0.45600000000000307
console.log(num_1 - num_2).toFixed(3); //output: -0.456
console.log(num_3); //Infinity
console.log(num_1 / "hello"); // NaN
console.log(typeof num_4); // bigint

string

  • 문자, 문자열을 표현하는 자료형
  • 자바스크립트에서 문자열은 3가지 종류의 따옴표로 표현 가능
    -큰 따옴표: "hello"
    -작은 따옴표: 'hello'
    -역 따옴표(백틱,backtick): `hello
    ( 큰 따옴표와 작은 따옴표는 기능상의 차이가 없고, 역 따옴표의 경우 문자열 안에 변수를 넣을 때 쓰인다 )
let str_1 = "hello_1";
let str_2 = 'hello_2';

let num = 3;
let str_3 = 'hello_${num}';

console.log(str_1); // output: hello_1
console.log(str_2); // output: hello_2
console.log(str_3); // output: hello_3

object

  • 다수의 원시 자료형을 포함하거나 복잡한 개체(Entity)를 표현할 수 있는 자료형
  • Object() 혹은 중괄호 ({ })를 통해 생성
  • object의 개체는 key:value 형태로 표현하며, 접근은 object.key형태로 표현

↓ 객체 예제 코드(1)

let user = {
	name: "john", //key: name, value:"john"
    age: 27, //key: age, value: 27
};

console.log(typeof user); //output: object
console.log(typeof user.name); //output: string
console.log(typeof user.age); //output: number

console.log(user.name); //output: "john"
console.log(user.age); //output: 27

user.age = 30;
console.log(user.age); //output: 30

↓ 객체 예제 코드(2)
-객체(object)에 개체(entity) 추가는 obj.key = value, 삭제는 delete 명령어를 통해 수행

let user = {
	name: "john",
    age: 27,
};

console.log(user); //output: {name: 'john', age:27}

user.weight = 72, //or user ["weight"] = 72;
console.log(user); //output: {name: 'john', age:27, weight: 72}

delete user.age;
console.log(user); //output: {name: 'john', weight: 72}

객체 복사 문제점

let user = {
	name: "john",
    age: 27,
};

let admin = user;

admin.name = "park";

console.log(admin.name); //output: "park"
console.log(user.name); //output: "park"

user.age = 30;
console.log(user.age); //output: 30
console.log(admin.age); //output: 30

위의 코드를 보면 admin의 name을 바꿨는데 건들지도 않았던 user의 name도 바뀌었고, 마찬가지로 admin의 age를 바꿨더니 user의 age도 같이 바뀌었다. 문제가 무엇일까.

object 복사

  • object의 값을 복사할 때는 대상 전체가 아닌 object내 주소 값만 복사되기 때문에 문제 발생
  • 가리키는 대상 전체를 복사하는 방법은 얕은 복사(shallow copy), 깊은 복사(deep copy)를 통해 가능

얕은 복사(shallow copy)

  • 반복문 for문을 통한 객체 복사
let user = {
	name: "john",
    age: 23,
};

let admin = {};

//shallow copy
for (let key in user) {
	admin[key] = user[key];
}

admin.name = "park";

console.log(admin.name); // output: "park"
console.log(user.name); // output: "john"
  • Object.assign() 함수를 이용한 복사
let user = {
	name: "john",
    age: 23,
};

let admin_obj = Object.assign({}, user);

admin_obj.name = "park";
user.age = 30;

console.log(admin_obj.name); //output: "park"
console.log(user.name); //output: "john"
console.log(admin_obj.age); //output: "23"
console.log(user.age); //output: "30"
  • ES6에서부터 지원하는 전개 연산자(Spread Operator)를 이용한 복사
let user = {
	name: "john",
    age: 23,
};

let admin_spread = { ...user };

admin_spread.name = "park";
user.age = 30;

console.log(admin_spread.name); //output: "park"
console.log(user.name); //output: "john"
console.log(admin_spread.age); //output: "23"
console.log(user.age); //output: "30"

얕은 복사(shallow copy)의 문제점

  • 객체 내 또 다른 객체가 있다면 복사되지 않음
let user = {
	name: "john",
    age: 23,
    sizes. {
    	height: 180,
        weight: 72,
    },
};

let admin_obj = Object.assign({},user);

admin_obj.sizes.weight++;
--admin_obj.sizes.height; 

console.log(admin_obj.sizes.weight); //output: "73"
console.log(admin_obj.sizes.height); //output: "179"
console.log(user.sizes.weight); //output: "73"
console.log(user.sizes.height); //output: "179"

위 예제코드를 보면 객체 복사를 할 때와 마찬가지로 admin의 객체만 바꿨는데 user의 객체도 바뀌는 문제가 발생한다.
이런 문제를 해결하기 위해 나온 방법이 깊은 복사이다.

깊은 복사(deep copy)

  • 재귀 함수를 이용한 깊은 객체 복사
let user = {
	name: "john",
    age: 23,
    sizes: {height: 180, weight:72},
};

function copyObj(obj) {
	let result = {};
    for (let key in obj) {
    	if (typeof obj[key] === "object") result[key] = copyObj(obj[key]);
        else result[key] = obj[key];
    }
	return result;
}
let admin = copyObj(user);

admin.sizes.weight++;

console.log(admin.sizes.weight); //output: 73
console.log(admin.sizes.height); //output: 72
  • JSON 객체를 이용한 깊은 복사, stringify는 객체를 문자열로 변환하는데 이때 원본 객체와의 참조가 끊김
let user = {
	name: "john",
    age: 23,
    sizes: {height: 180, weight:72},
};
//stringify: js object > string, parse: string > js object
let admin_json = JSON.parse(JSON.stringify(user));

admin_json.sizes.weight++;
--admin_json.sizes.height;

console.log(admin_json.sizes.weight); //output: 73
console.log(admin_json.sizes.height); //output: 179
console.log(user.sizes.weight); //output: 72
console.log(user.sizes.height); //output: 180

위 예제코드를 보면 user의 객체를 string으로 변환하면서 참조가 끊기기 때문에 이후에 admin의 객체를 수정해도 user에는 영향을 끼치지 않는다.

정리하자면 얕은 복사는 "주소 값"을 복사한다는 의미이고, 깊은 복사는 "실제 값"을 새로운 메모리 공간에 복사한다는 의미이다.

profile
문제를 객관적으로. 그 후 true / false

0개의 댓글