서론
어제도 많았는데 오늘도 많다. 이러다가 줄줄이 밀릴지도 모르겠다. 그래도 의미없는 내용은 아닌 것 같다. 어제가 기초였다면 오늘은 프로젝트의 핵심이 되는 요소들이 많기 때문이다.
기초가 없는 사람으로서 이런 건 확실하게 익히고 가는 게 맞다. 물론 그렇다고 해도 너무 많다. 아무래도 파트1, 2가 분리되어서 올라가지 않을까 싶다.
이번 일자는 자바스크립트 기초 - 객체와 빌트인 객체 그리고 매커니즘이다.
객체 (Object)
자바스크립트는 객체(object) 기반의 스크립트 언어이며 자바스크립트를 이루고 있는 거의 모든 것이 객체이다. 원시 타입을 제외한 나머지 값들(함수, 배열, 정규표현식 등)은 모두 객체이다.
또한, 객체는 키(Key)과 값(Value)으로 구성된 프로퍼티(속성)들의 집합이다. 프로퍼티의 값으로 자바스크립트에서 사용할 수 있는 모든 값을 사용할 수 있다. 자바스크립트의 함수는 일급 객체이므로 값으로 취급할 수 있다. 그렇기에 프로퍼티 값으로 함수를 사용할 수도 있다. 그리고 프로퍼티 값이 함수일 경우, 일반 함수와 구분하기 위해 '메서드'라 부른다. (메소드보다는 메서드가 맞는 표기라고 한다.)
이와 같이 객체는 데이터를 의미하는 프로퍼티와 데이터를 참조하고 조작할 수 있는 동작을 의미하는 메서드로 구성된 집합이다. 객체는 데이터(프로퍼티)와 그 데이터에 관련되는 동작(메서드)을 모두 포함할 수 있기 때문에 데이터와 동작을 하나의 단위로 구조화할 수 있어 유용하다.
자바스크립트의 객체는 객체지향의 상속을 구현하기 위해 '프로토타입'를 통해 객체의 프로퍼티와 메소드를 상속받을 수 있다. 이 프로토타입은 타 언어와 구별되는 아주 중요한 개념이다.
프로퍼티 (Property)
let people = {
name: 'Park', // 이 한줄이 프로퍼티
age: 20, // 이 한줄이 프로퍼티
level: 99 // 이 한줄이 프로퍼티
};
// 마침표 표기법(점)
console.log(people.name);
// 대괄호 표기법(문자열로 접근)
console.log(people['age']);
// 대괄호 표기법(변수로 접근)
let objValue = 'level';
console.log(people[objValue]);
프로퍼티 혹은 속성은 프로퍼티 키(이름)와 프로퍼티 값으로 구성된다. 프로퍼티는 프로퍼티 키로 식별할 수 있다. 즉, 프로퍼티 키는 프로퍼티를 식별하기 위한 식별자(identifier)다. 프로퍼티 키의 명명 규칙과 프로퍼티 값으로 사용할 수 있는 값은 아래와 같다.
- 프로퍼티 키 : 빈 문자열을 포함하는 모든 문자열 또는 심볼(symbol) 값
(위에서 name, age, level) - 프로퍼티 값 : 모든 값
(위에서 'park', 20, 99)
또한 이러한 프로퍼티는 크게 2가지의 방법으로 접근할 수 있다.
- 마침표 표기법: objectName.프로퍼티 이름
- 대괄호 표기법(문자열 접근): objectName["프로퍼티 이름"]
대괄호 표기법(변수 접근): objectName[프로퍼티 이름을 담고 있는 변수명]
프로퍼티 키에 문자열이나 심볼 값 이외의 값을 지정하면 암묵적으로 타입이 변환되어 문자열(string)이 된다. 이미 존재하는 프로퍼티 키를 중복 선언하면 나중에 선언한 프로퍼티가 먼저 선언한 프로퍼티를 덮어쓴다. 배열과는 달리 객체는 프로퍼티를 열거할 때 순서를 보장하지 않는다.
메소드 (Method)
프로퍼티 값이 함수일 경우, 일반 함수와 구분하기 위해 메소드라 부른다.
즉, 메소드는 객체에 제한되어 있는 함수를 의미한다.
함수와의 차이가 모호할 수도 있다. 그러나 함수를 호출하는 객체가 있는 경우 메서드이며, 함수를 호출하는 객체가 없는 경우 함수라고 한다.
let e_object = {
e_property: 12345, // 프로퍼티
e_method: function() {
console.log('e_method 메서드');
}
}
function e_fun() {
console.log('e_fun 함수');
}
e_object.e_method(); // 메서드 호출
e_fun(); // 함수 호출
여기서 e_property가 프로퍼티, function e_fun()이 함수, e_method: function()가 메서드가 된다.
정확하게는 e_method는 본래 함수이나, e_object 객체를 통해 호출한 상황이다. 이는 'e_object.e_method();' 점(.)을 찍어서 호출한 부분에서 알 수 있다. 즉, 이런 식으로 함수를 호출하는 객체가 있기에(혹은 객체에 제한된 상황) e_method은 메서드가 된다. 반면 e_fun은 객체 생성없이 바로 호출되었으므로 그냥 함수이다.
객체 생성법
객체는 아래와 같은 5가지의 방법으로 생성할 수 있다.
객체 생성자 방식 (Object constructor)
// 객체 생성자 방식(Object constructor)
var CON_People = function(name, age, level) {
this.name = name;
this.age = age;
this.level = level;
this.talk = function(){
console.log(`constructor. ${this.name}님은 ${this.age}살이며, ${this.level} 레벨입니다.`);
}
}
var people1 = new CON_People('Park', 20, level=99);
people1.talk();
함수를 통해서 객체를 생성하는 방식이다.
클래스 패턴 방식 (Class pattern)
// 클래스 패턴 방식(Class Pattern) - 생성자 방식과는 거의 비슷
class CLA_People {
constructor(name, age, level) {
this.name = name;
this.age = age;
this.level = level;
}
get peopleName() { //해당 값만 빼오기 가능
return this.name;
}
set peopleName(value) { //해당 값만 재설정 가능
this.name = value;
}
talk() {
console.log(`Class Pattern. ${this.name}님은 ${this.age}살이며, ${this.level} 레벨입니다.`);
}
}
var people2 = new CLA_People('Park', 20, level=99);
people2.talk();
people2.peopleName = 'Kim'; // setter 사용으로 이름 변경
console.log(`Class Pattern. 변경한 이름만 따로 출력: ${people2.peopleName}.`);
people2.talk();
class 키워드를 이용해 클래스를 정의하고, new 키워드로 클래스를 호출하면 생성자(constructor)가 호출되는 방식이다.
객체 리터럴 방식(Object literal)
// 객체 리터럴 방식(Object literal)
var people = {
name: 'Park',
age: 20,
level: 99,
talk: function(){
console.log(`literal. ${this.name}님은 ${this.age}살이며, ${this.level} 레벨입니다.`);
}
};
people.talk();
변수처럼 객체를 생성하는 방식이다.
new Object() 방식
var people = new Object();
people.name = 'Park';
people.age = 20;
people.level = 99;
people.talk = function(){
console.log(`new Object(). ${this.name}님은 ${this.age}살이며, ${this.level} 레벨입니다.`);
}
people.talk();
자바스크립트에 내장되어 있는 new Object() 생성자 함수를 사용하는 방식이다.
Object.create(프토토타입) 방식
// Object.create(프토토타입) 방식
var people = Object.create(null, {
name: { value: 'Park', writable: true },
age: { value: 10, writable: true }
}); //value 속성으로 초기값 설정, writable 설정으로 값을 수정할 수 있도록 설정.
people.age = 20; //값 수정
people.level = 99; //값 추가
var child = Object.create(people);
console.log(`Object.create(). ${child.name}님은 ${child.age}살이며, ${child.level} 레벨입니다.`);
prototype 키워드를 직접적으로 이용하진 않지만, 지정된 프로토타입 객체 및 속성(property)을 갖는 새 객체를 만든다.
다만, class 추가 이후로는 extends로 상속 구현이 가능해진지라 지금은 잘 쓰이지 않는다.
객체 속성 조작 (Control)
객체는 원시 타입과 다르게 변경 가능한 값(mutable)이다.
이러한 객체는 전달하는 과정에서 참조 형태로 전달된다.
문제가 있다면 객체의 변경이 일어날 때 참조된 객체들도 같이 변경이 되는 사태가 벌어질 수도 있다.
- 객체의 속성 동적 생성
- 객체의 속성들 나열하기.
- 객체의 속성 삭제하기.
이 때문에 의도한 동작이 되기 위해서는 위와 같은 조작을 적절히 사용해야 한다.
동적 생성
var people = {
name: 'Park',
age: 20,
}
people.level = '99';
console.log(people);
객체에 존재하지 않는 속성을 참조하고 할당문을 통해 값을 할당하면 속성이 동적으로 생성되고 추가한다.
나열하기
객체의 속성을 나열하는 몇 가지 방법이다.
for ~ in
var obj1 = {
a: 1, b: 3, c: 5
};
for (var i in obj1) {
console.log(i, obj1[i]);
// a 1, b 3, c 5
}
모든 열거 가능한 속성을 순회한다.(객체의 프로토타입 체인의 속성까지)
다만, 객체의 key값에 접근할 수 있지만, value값에 접근하는 방법은 제공하지 않는다.
for ~ of
반복가능한 객체에 (Array, Map, Set, String, TypedArray, arguments 등) 대해서 반복하고 각 개별 속성값에 대해 실행되는 문이 있는 사용자 정의 반복 후크를 호출하는 루프를 생성한다.
var obj4 = [10, 20, 30];
for (var value of obj4) {
console.log(value);
// 10, 20, 30
}
Object.keys(객체)
var obj2 = {
a: 123,
c: true,
b: '텍스트임'
};
console.log(Object.keys(obj2));
// [ 'a', 'c', 'b' ]
주어진 객체의 속성 이름들을 일반적인 반복문과 동일한 순서로 순회되는 열거할 수 있는 배열로 반환한다.
Object.values(객체)
var obj3 = {
a: 123,
c: true,
b: '텍스트임'
};
console.log(Object.values(obj3));
// [ 123, true, '텍스트임' ]
전달된 파라미터 객체가 가지는 열거 가능한 속성의 값들로 이루어진 배열을 리턴합니다. 이 배열은 for ~ in 구문과 동일한 순서를 갖지만 배열로 리턴한다는 특징을 갖는다.
Object.getOwnPropertyNames(객체)
var obj5 = {
a: 123,
c: true,
b: '텍스트임'
};
var propertyName = Object.getOwnPropertyNames(obj5);
console.log(propertyName);
// [ 'a', 'c', 'b' ]
객체 자신만의 모든 속성을 배열로 반환한다.
삭제하기
var obj6 = {
a: 123,
b: '텍스트임',
c: true,
d: '삭제될 데이터',
e: 5
};
console.log(Object.getOwnPropertyNames(obj6));
// [ 'a', 'b', 'c', 'd', 'e' ]
delete obj6.d;
console.log(Object.getOwnPropertyNames(obj6));
// [ 'a', 'b', 'c', 'e' ]
delete 연산자로 객체 속성을 삭제할 수 있다.
기본적인 구조는 'delete 속성이름'이며, 반환값으로 true가 나온다.
객체간 비교와 복사
객체는 참조 타입(Reference Type)이다. 즉, 모든 연산이 참조값(메모리 주소)로 처리한다.
그리고 객체는 서로 비교할 경우, 객체 속성과 값이 같은 객체여도 참조값이 다르므로 서로 다르다고 나온다.
자기 자신과의 비교에서만 true가 나온다.
그리고 객체 타입에는 얕은 복사(shallow copy)와 깊은 복사(deep copy)라는 개념 또한 존재한다.
- 얕은 복사(shallow copy)
- 객체를 프로퍼티 값으로 가질 때, 1단계까지만 완전 복사하는 것을 말한다.
- 2단계부터는 참조값 복사가 이뤄진다. (해당 참조값 내용물 변경 시 영향 받음)
- 객체에 중첩되어 있는 객체의 경우 참조 값을 복사한다.
- 그렇기에 객체의 속성 중 참조타입이 없는 경우에만 얕은 복사가 권장된다.
- 얕은 복사는 object.assian 혹은 spread 연산자를 이용해 복사할 수 있다.
- 깊은 복사(deep copy)
- 객체를 프로퍼티 값으로 가질 때, 객체에 중첩되어 있는 객체까지 모조리 완전 복사하는 것을 말한다.
- 객체에 중첩되어 있는 객체까지 모두 복사해서 원시 값처럼 완전한 복사본을 만든다.
- 깊은 복사는 재귀함수를 이용해 복사하거나, JSON.stringify로 객체->문자열 변환->객체의 과정을 거쳐서 복사하는 방법이 있다.
둘 다 복사인 만큼 원본과는 참조 값마저 다른 객체라고 할 수 있다. 그저 얕은 복사는 참조 값 주소를 가져오기에, 다른 객체인데도 영향을 받는 것이다. 깊은 복사에는 이러한 문제가 존재하지 않는다.
해당 내용은 9일차 TIL에 나와있었으니 필요하면 더 참고하도록 하자.
객체의 종류
객체는 아래와 같이 분류할 수 있다.
- Standard Built-in Objects (표준 빌트인 객체) / Global Objects (글로벌 객체) / Native Object (네이티브 객체)
표준 빌트인 객체는 ECMAScript 사양에 정의된 객체를 말하며, 웹페이지 등을 표현하기 위한 공통의 기능을 제공한다. ECMAScript 사양에 정의된 객체이므로 자바스크립트 실행 환경(브라우저 또는 Node.js)과 관계없이, 웹페이지가 브라우저에 의해 로드되자마자 별다른 행위없이 바로 사용이 가능하다. - Host Object (호스트 객체)
실행 환경에서 제공하는 객체로, 브라우저나 node.js 같은 곳에서 제공하는 객체이다.- BOM (Browser Object Model; 브라우저 객체 모델)
- DOM (Document Object Model; 문서 객체 모델)
- Canvas, XMLHttpRequest, fetch, rquestAnimationFrame, SVG, Web Storage, Web Component, Web Worker 같은 이외의 다양한 호스트 객체들.
- User-defined Objects (사용자 정의 객체)
사용자 정의 객체는 표준 빌트인 객체와 호스트 객체처럼 기본 제공되는 객체가 아닌 사용자가 직접 정의한 객체를 말한다.
표준 빌트인 객체 (Standard Built-in Objects)
표준 빌트인 객체는 글로벌 객체(Global Objects) 혹은 네이티브 객체(Native Object)라고도 불린다. 이는 명세에 정의된 객체를 말하며 애플리케이션 전역의 공통 기능을 제공한다. 네이티브 객체는 애플리케이션의 환경과 관계없이 언제나 사용할 수 있다.
- 기초 객체 : Object, Function, Boolean, Symbol
- 오류 객체: Error
- 숫자 및 날짜: Number, BigInt, Math, Date
- 텍스트 처리: Regex(정규표현식), String(문자열)
- 컬렉션(Collection)
- 인덱스 기반의 컬렉션: 배열
키 기반의 컬렉션: Map, Set
- 인덱스 기반의 컬렉션: 배열
- 구조화된 데이터 : JSON
- 제어 추상화 객체 : Promise, Generator, AsyncFunction
기본적으로 표준 빌트인 객체는 Object(위에서 설명했으므로 생략), Function(10일차 데브코스), Boolean, Number, String, Array, RegExp, Date, Math와 같은 객체 생성에 관계가 있는 함수 객체와 메소드로 구성된다. 또한, 글로벌 객체(Global Objects)라고 부르기도 하는데 이것은 전역 객체(Global Object)와 다른 의미로 사용되므로 혼동에 주의하여야 한다.
생성자 함수 객체인 표준 빌트인 객체는 프로토타입 메서드와 정적 메서드를 제공한다.
반면, 생성자 함수 객체가 아닌 표준 빌트인 객체는 정적 메서드만 제공한다.
참고로 본 글에서 [prototype]라고 앞에 표시되어 있는 메서드는 '빌트인 프로토타입 메서드'이다. 이는 표준 빌트인 객체의 prototype 프로퍼티에 바인딩된 객체만 가질 수 있다. 또한, 인스턴스 없이도 호출 가능한 빌트인 정적 메서드를 제공받는다. 해당 메서드는 '객체.prototype.메서드'와 같은 형태를 갖게 된다.
Boolean
var bo1 = new Boolean(true); // true
var bo2 = new Boolean('false'); // true
var bo3 = new Boolean(false); // false
var bo4 = new Boolean(); // false
원시 타입 boolean을 위한 레퍼 객체이다. Boolean 생성자 함수로 Boolean 객체를 생성할 수 있다. 다만, Boolean 객체와 원시 타입 boolean을 혼동하기 쉽다 Boolean 객체는 true/false를 포함하고 있는 객체이다.
Number
var nu1 = new Number(123); // 123
var nu2 = new Number('123'); // 123
var nu3 = new Number('str'); // NaN
원시 타입 number를 다룰 때 유용한 프로퍼티와 메소드를 제공하는 원시 래퍼 객체이다. 함수로 바로 사용할 수 있다. 변수 또는 객체의 프로퍼티가 숫자를 값으로 가지고 있다면 Number 객체의 별도 생성없이 Number 객체의 프로퍼티와 메소드를 사용할 수 있다.
- 정적 프로퍼티
- Number.EPSILON
자바스크립트에서 표현할 수 있는 가장 작은 수를 반환. 1과 1보다 작은 숫자와의 차이이다. 부동소수점 오차를 해결하고자 도입되었다. - Number.MAX_VALUE
자바스크립트에서 사용 가능한 가장 큰 숫자를 반환 - Number.MIN_VALUE
자바스크립트에서 사용 가능한 가장 작은 숫자를 반환. 즉, 0에 가장 가까운 양수값. - Number.POSITIVE_INFINITY
양의 무한대, Infinity를 반환. - Number.NEGATIVE_INFINITY
음의 무한대, -Infinity를 반환. - Number.NaN
숫자가 아님(Not a Number)을 나타내는 값.
- Number.EPSILON
- 메서드
- Number.isFinite(number)
매개변수에 전달된 값이 정상적인 유한수인지를 검사하여 그 결과를 Boolean으로 반환한다. - Number.isInteger(number)
매개변수에 전달된 값이 정수인지 검사하여 그 결과를 Boolean으로 반환한다. - Number.isNaN(number)
매개변수에 전달된 값이 NaN인지를 검사하여 그 결과를 Boolean으로 반환한다. - Number.isSafeInteger(number)
매개변수에 전달된 값이 안전한(safe) 정수값인지 검사하여 그 결과를 Boolean으로 반환한다. - Number..toExponential(number)
[prototype] 대상을 지수 표기법으로 변환하여 문자열로 반환한다. 지수 표기법이란 매우 큰 숫자를 표기할 때 주로 사용하며 e(Exponent) 앞에 있는 숫자에 10의 n승이 곱하는 형식으로 수를 나타내는 방식이다. - Number.toFixed(number)
[prototype] 매개변수로 지정된 소숫점자리를 반올림하여 문자열로 반환한다. - Number.toPrecision(number)
[prototype] 매개변수로 지정된 전체 자릿수까지 유효하도록 나머지 자릿수를 반올림하여 문자열로 반환한다. - Number.toString(number)
[prototype] 숫자를 문자열로 변환하여 문자열을 반환한다. 단, 정수 리터럴과 함께 메소드를 사용 시(123.toString()처럼) 오류가 발생한다. 이는 숫자(정수 리터럴) 뒤에 붙어있는 것이 소숫점인지 뭔지 구분을 못하기 때문이며, 이때는 이와(
(123).toString())같이 처리를 해둬야 한다. - Number.valueOf()
[prototype] Number 객체의 원시 타입 값(number)을 반환한다.
- Number.isFinite(number)
변수 또는 객체의 속성이 숫자를 갖고 있으면, Number 객체 인스턴스 생성없이 Number의 인스턴스 속성과 메서드를 사용할 수 있다.
String
var st1 = new String(123); // [String: '123']
var st2 = new String('123'); // [String: '123']
var st3 = new String('str'); // [String: 'str']
var st4 = new String(undefined); // [String: 'undefined']
원시 타입인 문자열을 다룰 때 유용한 프로퍼티와 메소드를 제공하는 래퍼 객체이다. 변수 또는 객체 프로퍼티가 문자열을 값으로 가지고 있다면 String 객체의 별도 생성없이 String 객체의 프로퍼티와 메소드를 사용할 수 있다.
- 정적 프로퍼티
- String.length
문자열 내의 문자 갯수를 반환한다. 참고로 String 객체는 length 프로퍼티를 갖고 있기에 유사 배열 객체라고 할 수 있다.
- String.length
- 메서드
- String.at(number)
[prototype] 인수로 전달한 인덱스를 사용하여 인덱스에 해당하는 위치의 문자를 반환한다. 인덱스가 문자열의 범위를 벗어날 경우 undefined를 반환한다. - String.charAt(number)
[prototype] 인수로 전달한 인덱스를 사용하여 인덱스에 해당하는 위치의 문자를 반환한다.인덱스가 문자열의 범위를 벗어나면 빈 문자열을 반환한다. - String.charCodeAt(number)
[prototype] 해당 문자열의 지정한 인덱스에 대한 0부터 65535 사이의 정수(UTF-16)를 반환합니다. - String.codePointAt(number)
[prototype] 해당 문자열의 지정한 인덱스에 대한 10진법 기반의 유니코드를 반환합니다. - String.concat(string[])
[prototype] 전달받은 1개 이상의 문자열과 서로 연결하여 새로운 문자열을 반환한다. - String.indexOf(string, fromIndex)
[prototype] 인수 문자열을 특정 문자열에서 검색하여 '처음'으로 발견된 곳의 index를 반환하거나, 발견하지 못하면 -1를 반환한다. - String.lastIndexOf(string, fromIndex)
[prototype] 인수 문자열을 특정 문자열에서 검색하여 '마지막'으로 발견된 곳의 index를 반환하거나, 발견하지 못하면 -1를 반환한다. - String.replace(string, string)
[prototype] 1번째 인수로 전달한 문자열 또는 정규표현식을 대상 문자열에서 검색하여 2번째 인수로 전달한 문자열로 대체한다. 원본 문자열은 변경되지 않는다. - String.split(string, number)
[prototype] 1번째 인수로 전달한 문자열 또는 정규표현식을 대상 문자열에서 검색하여 문자열을 구분한 후 분리된 각 문자열로 이루어진 배열을 반환한다. 원본 문자열은 변경되지 않는다. - String.substring(number, number)
[prototype] 1번째 인수로 전달한 start 인덱스에 해당하는 문자부터 2번째 인자에 전달된 end 인덱스에 해당하는 문자의 바로 이전 문자까지를 모두 반환한다. 참고로 이때 1번째 인수가 2번째 인수보다 작아야 한다는 공식이 성립됨을 알 수 있다. - String.slice(number, number)
[prototype] 위의 메서드인 String.prototype.substring와 비슷하다. 단, 이건 음수의 인수를 전달할 수 있다. - String.toLowerCase()
[prototype] 문자열의 모든 문자를 소문자로 변경한다. - String.toUpperCase()
[prototype] 문자열의 모든 문자를 대문자로 변경한다. - String.trim()
[prototype] 문자열 양쪽 끝에 있는 공백 문자를 제거한 문자열을 반환한다. - String.repeat(number)
[prototype] 문자열을 인수로 전달한 숫자만큼 반복하고, 여러 개가 연결된 새로운 문자열을 반환한다. - String.includes(string, number)
[prototype] 인수로 전달한 문자열이 포함되어 있는지를 검사하고 결과를 boolean 값으로 반환한다. 참고로 두번째 인수는 옵션으로 검색할 위치를 나타내는 정수이다. - String.startsWith(string, number)
[prototype] 어떤 문자열이 특정 문자로 시작하는지 확인하고 boolean을 반환한다. - String.endsWith(string, number)
[prototype] 어떤 문자열이 특정 문자로 끝나는지 확인하고 boolean을 반환한다. - String.localeCompare(string)
[prototype] 문자열과 문자열을 비교하여 어느 것이 정렬 순서에서 우선인지 파악한다. 일종의 오름차순, 내림차순 기능을 위한 메서드이다. 앞 String이 뒷 string보다 앞에 있는 문자이면 -1을 반환, 그 반대이면 1을 반환, 서로 같으면 0을 반환한다.
- String.at(number)
이외에도 다양한 메서드가 있다.
이러한 문자열은 백틱(`) 문자를 사용하여서 만들어낼 수도 있다. 또한, 이스케이프(\n) 문자로 줄바꿈 문장을 표현하거나 백틱에서 말 그대로 개행을 함으로써 줄을 바꿀 수 있다.
참고로 데이터 보관시 문자열 형태로 저장하는 것이 유용하다. 이는 객체 형태를 JSON.stringify로 변환하여 저장하는 것이다.
Math
Math 객체는 숫자를 표현하고 다룰 때 사용하는 원시 래퍼 객체이다. 다만, Math 객체는 생성자 함수가 아니다. 따라서 Math 객체는 정적 프로퍼티와 메소드만을 제공한다.
- 정적 프로퍼티
- Math.PI
파이(π ≈ 3.141592653589793)를 반환한다.
- Math.PI
- 메서드
- Math.abs(number)
인수의 절댓값을 반환한다. 절댓값은 반드시 0 또는 양수이어야 한다. - Math.round(number)
인수의 소수점 이하를 반올림한 정수를 반환한다. - Math.ceil(number)
인수의 소수점 이하를 올림한 정수를 반환한다. - Math.floor(number)
인수의 소수점 이하를 내림한 정수를 반환한다. Math.ceil의 반대이다. - Math.sqrt(number)
인수의 제곱근을 반환한다. - Math.random()
임의의 부동 소수점을 반환한다. 즉, 반환값은 0에서 1 사이이다 - Math.pow(number, number)
첫번째 인수는 밑이고, 두번째 인수는 지수이다. 거듭제곱을 반환한다. - Math.max(number)
여러 개의 인수 중에서 가장 큰 수를 반환한다. - Math.min(number)
여러 개의 인수 중에서 가장 작은 수를 반환한다.
- Math.abs(number)
이외에도 다양한 프로퍼티와 메소드가 있다.
Date
var date1 = new Date();
console.log(date1); // 2024-01-01T01:01:01.001Z
var date2 = Date();
console.log(date2); // Wed Jan 03 2024 01:02:03 GMT+0900 (대한민국 표준시)
Date 객체는 1970년 1월 1일 0시 0분 UTC 자정과의 시간 차이를 밀리초(ms; 천분의 1초) 단위로 나타낸 빌트인 객체 겸 생성자 함수이다.
- 생성자
- new Date()
가장 기본이다. 현재 날짜와 시간을 가지는 인스턴스를 반환한다. - new Date(number)
정수 밀리초를 인수로 전달하면 1970년 1월 1일 자정을 기점으로 인수로 전달된 밀리초만큼 경과한 시간을 반환한다. - new Date(String)
날짜와 시간을 나타내는 문자열을 전달하면 지정된 날짜와 시간을 가지는 인스턴스를 반환한다. 다만, Date.parse 메소드가 해석 가능한 형태여야 한다. - new Date(year, month, day, hour, minute, second, millisecond)
년, 월, 일, 시, 분, 초, 밀리초를 의미하는 숫자를 인수로 전달하면 지정된 날짜와 시간을 가지는 인스턴스를 반환한다. 이때 년, 월은 반드시 지정하여야 한다. 그리고 기본적으로 일을 제외한 모든 값들은 0부터 시작한다. 다르게 말하자면 0월, 0시, 0분, 0초가 존재하고, 12월, 24시, 60분, 60초는 없다는 것이다. 즉, 배열처럼 0부터 시작이라고 보면 된다.(일은 유일하게 1부터 31까지이다.) - new 연산자없이 Date 호출 (var date2 = Date())
다른 방식으로 표시해주는 것으로 보이나, 실제로는 Date값이 아니라 문자열 값으로 반환되는 것이다.
- new Date()
- 메서드
- Date.now()
1970년 1월 1일 00:00:00을 기점으로 현재 시간까지 경과한 밀리초를 숫자로 반환한다. - Date.parse(string)
new Date(dateString)의 인수와 동일한 형식까지의 밀리초를 숫자로 반환한다. - Date.UTC(string or date)
1970년 1월 1일 00:00:00(UTC)을 기점으로 인수로 전달된 지정 시간까지의 밀리초를 숫자로 반환한다. - Date.getFullYear()
[prototype] 년도를 나타내는 4자리 숫자를 반환한다. - Date.setFullYear(year, month, day)
[prototype] 년도를 나타내는 4자리 숫자를 설정한다. 년도 외에 월, 일도 추가로 설정할 수 있다. - Date.getMonth()
[prototype] 월을 나타내는 0 ~ 11의 정수를 반환한다. - Date.setMonth(month, day)
[prototype] 월을 나타내는 0 ~ 11의 정수를 설정한다. 월 외에 일도 설정할 수 있다. - Date.getDate()
[prototype] 날짜를 나타내는 1~31의 정수를 반환한다. - Date.setDate(day)
[prototype] 날짜를 나타내는 1~31의 정수를 설정한다. - Date.getDay(week)
[prototype] 요일을 나타내는 0~6의 정수를 반환한다. 일(0), 월(1), 화(2), 수(3), 목(4), 금(5), 토(6) 순서이다. - Date.getHours()
[prototype] 시간을 나타내는 0~23의 정수를 반환한다. - Date.setHours(hour, minute, second, ms)
[prototype] 시간을 나타내는 0~23의 정수를 설정한다. 시간 이외 분, 초, 밀리초도 설정할 수 있다. - Date.getMinutes()
[prototype] 분을 나타내는 0~59의 정수를 반환한다. - Date.setMinutes(minute, second, ms)
[prototype] 분을 나타내는 0~59의 정수를 설정한다. 분 외에 초, 밀리초도 설정할 수 있다. - Date.getSeconds()
[prototype] 초를 나타내는 0~59의 정수를 반환한다. - Date.setSeconds(second, ms)
[prototype] 초를 나타내는 0~59의 정수를 설정한다. 초 외에 밀리초도 설정할 수 있다. - Date.getMilliseconds()
[prototype] 밀리초를 나타내는 0~999의 정수를 반환한다. - Date.setMilliseconds(ms)
[prototype] 밀리초를 나타내는 0~999의 정수를 설정한다. - Date.getTime()
[prototype] 1970년 1월 1일 00:00:00를 기점으로 현재 시간까지 경과된 밀리초를 반환한다. - Date.setTime(time)
[prototype] 1970년 1월 1일 00:00:00를 기점으로 현재 시간까지 경과된 밀리초를 설정한다. - Date.getTimezoneOffset()
[prototype] UTC와 현지 시간대 간의 차이를 분 단위로 반환한다. - Date.toDateString()
[prototype] 사람이 읽기 편한 형식의 문자열로 '날짜'를 반환한다. - Date.toTimeString()
[prototype] 사람이 읽기 편한 형식의 문자열로 '시간'을 반환한다.
- Date.now()
UTC(Coordinated Universal Time; 협정 세계시)는 GMT(Greenwich Mean Time; 그리니치 평균시)로 불리기도 하는데 UTC와 GMT는 초의 소숫점 단위에서만 차이가 나기 때문에 일상에서는 혼용되어 사용된다. 다만, 협정 세계시가 공식 표인인 관계로 기술적인 표기에서는 UTC가 사용된다.
참고로 대한민국의 시간대(KST)는 UTC +9이다. 즉, UTC 0인 영국의 런던 시간이 0시일 때 한국은 9시간이 빠른 오전 9시가 된다. 다른 예로는 한국이 오후 5시(17:00)일 때, 런던은 아침 8시(08:00)이 된다.
이러한 시간은 본인 컴퓨터(혹은 서버) 시스템 시계의 설정에 기반한다.
RegExp (Regular Expression; 정규표현식)
var n = '0101234567팔구';
var tRegExp = /^[0-9]+$/;
console.log(tRegExp.test(n)); // false
정규표현식은 문자열에서 특정 내용을 찾거나 대체 또는 발췌하는데 사용한다.
기본적으로 패턴 작성하는 방법은 다음과 같다.
- 단순 패턴 사용
- 특수 문자 사용:어서션, 문자 클래스, 그룹과 범위, 수량자, 유니코드 속성 이스케이프
또한, flag(d, g, l, m, s, u, y)를 활용하여 탐색할 수도 있다.
정규표현식 생성 방법은 다음과 같다.
- 리터럴 표기법
- 평가할 때 정규 표현식을 컴파일한다.
- 정규식이 변하지 않으면 리터럴 표기법을 사용한다.
- /pattern/flag
- RegExp 객체
- 런타임 때 컴파일 된다
- 패턴이 변할 가능성이 있거나,알 수 없는 데이터에서 가져오는 정규식의 경우 생성자 함수 사용한다.
- 객체 선언법: new RegExp(/pattern/, flag)
- 정적 속성 : lastIndex
- 생성자 함수 : RegExp.prototype
- 인스턴스
- 속성
- 적용된 플래그 반환 : flag
- 적용된 플래그 여부 반환: dotAll, global, ignoreCase, multiline, source, sticky, unicode
- 메서드: compile(), exec(), test(), toString()...
- 속성
이러한 RegExp 객체는 문자열 인스턴스 메서드 중 '찾는' 과정이 있는 메서드에서 주로 사용한다.
찾아서 일치하는지 확인: match(정규 표현식), matchAll(정규 표현식)
찾는: search(정규 표현식)
찾아서 교체: replace(정규 표현식), replaceAll(정규 표현식)
찾아서 분리: split(정규 표현식)
참고로 정규 표현식의 경우에는 도식 및 테스트를 해볼 수 있는 사이트가 존재한다.
그리고 해당 정규 표현식은 추후 다른 글에서 보강하겠다.
Collection
컬렉션은 구조 또는 비구조화된 형태로 프로그래밍 언어가 제공하는 값을 담을 수 있는 공간이다.
즉, 데이터 항목들의 그룹이다. 이러한 컬렉션에는 list, set, tree, graph 등이 존재한다.
자바스크립트에는 크게 2 종류의 컬렉션이 존재한다. 바로 Index based collection와 Key based collection이다.
Index based collection
인덱스 값을 기준으로 정렬된 컬렉션이다. 이는 배열(Array)을 뜻하는 말이기도 하다. 인덱스로 배열 내 값을 참조할 수 있다.
배열은 이름과 인덱스(색인)로 참조되어 정렬된 값들의 집합이다. 이를 통해 여러 개의 변수에 여러 개의 값을 순차적으로 저장할 때 사용할 수 있다.
다른 언어들과 다르게 자바스크립트는 명시된 배열 데이터 타입이 없다. 또한, 배열 객체를 사용할 수 있다. 리스트(List)와 비슷한 객체이며 순회와 변경 작업을 수행하는 메서드를 가지고 있다.
Array 객체는 다음과 같은 특징이 있다.
- 0개 이상의 식 expression(배열 요소) 목록
- 배열 생성 시
- 각 요소로 지정된 값이 초기화된다.
- 배열의 길이(length)는 지정된 요소의 갯수로 결정된다.
- 길이가 고정되어 있지 않다.
- 각 요소의 data type도 고정되어있지 않다.
- 모든 요소는 필수값이 아니다. (undefined로 지정해도 된다.)
예시. ['apple', undefined,' banana']
- 배열 생성 시
- 배열 요소의 참조
- 인덱스로 참조, 인덱스는 0부터 시작.
- 인덱스 값을 속성 이름으로 사용하여, 표준 객체의 속성처럼 저장.
- 인덱스로 문자열 값 사용할 수 없음, 무조건 정수로만 참조하여 저장.
- 배열에 값 저장
- 인덱스로 참조하지 않으면 객체의 속성으로 저장.
- 배열의 길이는 마지막 인덱스에 +1한 값이다.
- 길이를 지정하는 것 가능
- 원래 길이보다 작게 지정하면 배열이 잘린다.
- 반면 원래 길이보다 크게 지정하면 배열의 길이는 늘어난다.
- 길이를 지정하는 것 가능
- 배열의 반복 처리
- for문 혹은 forEach문을 활용한다.
이는 10일차 TIL의 반복문에서 다루었다.
- for문 혹은 forEach문을 활용한다.
이러한 Array 객체는 여러 방법으로 생성할 수 있다. 대표적으로는 배열 리터럴로 단순히 대괄호([ ])로 묶어서 생성하는 방법이 있다.
혹은 Array 객체 생성자를 사용하는 방법도 있다. 이 경우에는 new Array(arrayLength)처럼 하여서 길이를 지정한 배열을 생성하거나, new Array(element0, element1...)처럼 하여서 요소를 직접 지정한 배열을 만들어낼 수 있다.
이러한 Array 객체의 요소는 다음과 같다.
- Array 객체
- 정적 메소드: from, isArray, of
- 생성자: Array.prototype
- 인스턴스
- 속성: length
- 메서드: (일반/순회하며)
- 요소 체크(get): 접근, 찾기, 포함 여부 , 판별
- 요소 변경(set): 추가, 제거, 변경
- 배열 변경(set): 추가, 분리, 변경, 재배치
- 반환 타입 변경하기
- 인스턴스 메서드
- 요소 체크
- 요소 접근: at()
- 요소 찾기: indexOf(), lastIndexOf()
- 요소 포함 여부: includes()
- 순회함
- 요소 확인하기: forEach()
- 요소 판별하기: every(), some()
- 요소 찾기: find(), findIndex()
- 요소 조작
- 요소 추가하기: push(), unshift()
- 요소 제거하기: pop(), shift()
- 순회함
- 요소 변경하기: flatMap(), map()
- 요소 제거하기: filter()
- 반환 타입 변경
- 문자열로 변경: join(), toLocaleString(), toString(),
- iterator로 변경: entries(), values()
- 순회함
- 타입 변화하기: reduce(), reduceRight()
- 기타
- 배열 합치기, 추가하기: cocat(), fill()
- 배열 분리하기: slice(), splice()
- 배열 요소 변경하기: copyWithin(), flat()
- 배열 재배치하기: reverse()
- 순회하면서 재배치하기: sort()
- 요소 체크
Key based collection
키 값을 기준으로 하는 컬렉션이다. 키와 값을 매핑하여 저장한다. 또한, 저장된 순서대로 각 요소들을 반복적으로 접근할 수도 있다.
키 기반의 컬렉션은 저장된 순서대로 각 요소들을 반복적으로 접근할 수 있으며, 키와 값을 매핑하여 저장한다. 또한, 해당 컬렉션 에는 Map과 Set이 포함되어 있다.
Map & WeakMap
이러한 키 기반 컬렉션에는 Map과 WeakMap이라는 객체가 있는데. 이 둘은 키와 값을 매핑시키고, 해당 키가 유니크하다는 공통점이 있다.
그리고 맵 객체는 다음과 같은 요소로 이뤄져 있다.
- Map 객체
- 생성자 함수: Map.prototype
- 인스턴스
- 속성: size
- 메서드
- 요소 체크(get): 접근, 포함 여부 - get, has
- 요소 변경(Set): 추가, 제거, 변경 - clear, delete, set
- 순환 관련 - keys, values, entries, forEach
- 인스턴스
Map 객체는 간단한 키와 값을 매핑시켜 저장하고, 저장된 순서대로 요소를 반복적으로 접근할 수 있다. 그리고 [key, value]의 형태로 구성되며 삽입된 순서대로 추가된다.
그리고 Map은 Object와 다소 차이가 존재한다.
Object | Map | |
속성의 데이터 타입 | string, Symbol 데이터 타입만 삽입 가능. | 모든 값을 키로 활용 가능. |
default 속성과의 충돌 | Object prototype의 기본속성과 동일한 키를 생성시 충돌. | Map은 기본적으로 가지고 있는 속성이 없다. 따라서 기본 속성들과 충돌이 없다. |
객체의 크기 | 수동으로 추적해야 함. | size 인스턴스 속성으로 얻을 수 있다. |
iterable 여부 | Object는 iterable이 아님. | Map은 iterable임. |
순서 보장 | Object는 순서 보장이 안 됨. | map은 추가된 순서대로 반복된다. |
퍼포먼스 | 키 및 값 쌍의 번번한 추가-제거에는 퍼포먼스가 나쁘다. | 키 및 값 쌍의 번번한 추가-제거에는 퍼포먼스가 좋다. |
직렬화와 구문분석 제공 여부 | 직렬화와 구문분석 제공 (JSON, stringify, JSON.parse) |
map에서는 제공하지 않고 있다. (커스텀으로 구현은 가능) |
WeakMap이라는 객체도 존재한다. 이는 키에 대한 강력한 참조를 생성하지 않는 키 및 값 쌍의 모음이다. 해당 WeakMap에서 키는 Object만 허용된다.
- WeakMap 객체
- 생성자 함수: WeakMap.prototype
- 인스턴스
- 속성: size
- 메서드:
- 요소 체크(get): 접근, 포함 여부 - get, has
- 요소 변경(Set): 추가, 제거 - delete, set
- 순환관련 - 없음
- 인스턴스
또한, 객체 정보를 비노출하는 특징이 있다. 이러한 특징을 이용해 객체의 사적인 정보를 저장하거나, 상세 구현 내용을 숨길 때 사용되기도 한다.
Set & WeakSet
이러한 컬렉션에는 Set과 WeakSet이라는 것이 존재한다. 둘은 공통적으로 중복된 값을 허용하지 않으며, 값이 같은지 검사를 수행한다.
또한, 배열을 인자로 받을 수 있다. 배열의 요소는 Set 객체의 요소로 저장되며, 중복된 요소가 제거된다는 공통 속성도 있다.
그리고 Set은 모든 값들의 집합(값 콜렉션)이다. 입력된 순서에따라 저장된 요소를 반복 처리할 수 있다. 특정 값은 Set내에서 하나만 존재하며,. NaN은 Set에서 같은 것으로 간주된다. 심지어 배열 -> Set으로 Set -> 배열로 변환이 가능하다. for ~ of로 순회도 가능하고 말이다.
이러한 배열과 많이 비슷해보이는 Set은 다음과 같은 차이점이 있다.
Set | 배열 | |
포함여부 확인 퍼포먼스 | has 메서드를 사용한다. | indexOf를 사용하여 포함여부 확인은 퍼포먼스가 느리다. |
요소 제거 | delete method을 사용한다. | 배열은 요소를 제거할 때 배열을 잘라내야 한다. |
요소 찾기 | NaN 포함여부를 확인할 수 있다. | NaN은 indexOF로 포함여부 확인이 불가능하다. |
중복여부 확인 | set은 값의 유일성을 보장하기에, 중복성을 확인할 필요가 없다. | 순회하며 확인해야 한다. |
- Set 객체
- 생성자 함수: Set.prototype
- 인스턴스
- 속성: size
- 메서드:
- 요소 체크(get): 접근, 포함 여부 - has
- 요소 변경(Set): 추가, 제거, 변경 - clear, delete, add
- 인스턴스
WeakSet은 Set과 다르게 객체 컬렉션이다. 인자로 Object 값만 허용된다. 약한 참조를 가진다. Set과 비슷하게 new 키워드로 WeakSet 생성자를 호출할 수 있다.
- WeakSet 객체
- 생성자 함수: WeakSet.prototype
- 인스턴스
- 메서드:
- 요소 체크(get): 포함 여부 - has
- 요소 변경(Set): 추가(변경), 제거 - add, delete
- 순환 관련 - 없음
- 메서드:
- 인스턴스
JSON (JavaScript Object Notation)
JSON은 Javascript 객체 문법으로 구조화된 데이터를 표현하기 위한 문자 기반의 표준 포맷이다.
파일 확장자는 .json으로, 인터넷에서 자료를 주고받을 때 자료를 표현하는 방법으로 알려져있다. 키-값 쌍, 배열 자료형, 기타 모든 직렬화 가능한 값 또는 키-값 쌍으로 이루어진 데이터 객체를 전송할 때, 문자열을 사용하는 Open Standard 포맷이다.
기본 자료형으로는 자바스크립트 문법을 차용한 number, string, boolean, array, object, null가 있다. 이는 객체와 비슷하다. 이러한 JSON은 직렬화 가능한 값을 전송하는 포맷이다.
여기서 말하는 직렬화는 다양한 환경 간에 데이터를 주고 받기 위한 작업이다. 정확하게는 직렬화는 객체를 문자열로 변환하는 것이다. 그리고 반대인 역직렬화는 문자열을 객체로 변환하는 것이다.
- JSON 객체: 값을 JSON으로 변경하는 메서드 제공
- 생성자 함수 아님
- 함수로서 사용 불가능
- 정적 메서드
- JSON.stringify: 직렬화 하는 구문
- JSON.parse: JSON 형태로 파싱하는 구문 (역직렬화)
- 주의사항 : 문자열이 객체형태가 아닐 경우 오류가 발생한다.
- try ~ catch 문으로 에러 핸들링 권장
JSON 객체에는 위와 같은 요소들이 있다.
국제화 (Intl)
국제화는 Intl(internationalization)라고도 불린다. 각 언어에 맞는 문자, 숫자, 시간, 날짜 비교를 제공하는 국제화 API를 위한 네임스페이스이다.
국제화에는 정적 메서드로 'Intl.supportedLocalesOf()'라는 것이 존재한다. 그리고 내부 속성들은 생성자 함수들로 구성되어있다. 대표적으로는 DateTimeFormat와 NumberFormat이 있다.
- DateTimeFormat 생성자 함수
언어에 맞는 날짜, 시간 서식을 적용하기위한 객체- 생성자 : Intl.DateTimeFormat.prototype
- 인스턴스
- 메서드
- 포맷 결과: Format, FormatRange
- 포맷결과를 각 단위별로 분해하여 객체화: formatToParts, formatRangeToParts
- 메서드
- NumberFormat 생성자 함수
언어에 맞는 숫자 서식을 적용하기위한 객체- 생성자 : Intl.Numberformat.prototype
- 인스턴스
- 메소드
- 포맷 결과: format, formatRange
- 포맷결과를 각 단위별로 분해화여 객체화:formatToParts, formatRangeToParts
- 메소드
Symbol
ES6에서 도입된 원시 타입으로, 유일무이한 값, 고유한 값을 지정하기 위해 사용된다.
자세한 내용은 9일차 데브코스의 심볼 타입을 확인하자.
Error
try {
throw new Error('에러!');
} catch (er) {
console.log(er.name + ': ' + er.message);
}
Error 생성자는 error 객체를 생성한다. error 객체의 인스턴스는 런타임 에러가 발생하였을 때 throw된다.
사족
문자열까지는 어째저째 열심히 찾아보며 적었는데, 정규 표현식부터는 힘이 쫙 빠져버려서 사실상 강의 자료와 별반 다를 바가 없게 되었다. 일단, 해당 내용들은 추후 다른 글로 새로이 작성을 해볼 생각이다. 내가 봐도 너무 대충했기 때문이다.
또한, 이건 파트1이다. 파트2 부분까지 적기에는 지금 12시간이 넘게 프로그래머스 데브코스 TIL 정리만 하고 있었는지라, 너무 힘들어서 못할 것 같다. 나머지 내용은 내일 올리고, 겸사겸사 12일차도 올리겠다. 그래도 12일차 내용은 대충 하기는 했어도 꽤 재미있었기에, 정리가 그리 힘들 것 같지는 않다.
그리고 사족을 쓰면서 말하는 거지만, 거의 다 쓰다가 한 번 날려먹을 뻔했다. 심장이 덜컹했다. 😨
'💻 종합 개발 주제 > 📚 웹앱 데브코스' 카테고리의 다른 글
11일차 데브코스 pt.3 - 클라우딩 어플리케이션 엔지니어링 TIL (3) | 2024.01.13 |
---|---|
11일차 데브코스 pt.2 - 클라우딩 어플리케이션 엔지니어링 TIL (0) | 2024.01.12 |
10일차 데브코스 - 클라우딩 어플리케이션 엔지니어링 TIL (4) | 2024.01.09 |
9일차 데브코스 - 클라우딩 어플리케이션 엔지니어링 TIL (6) | 2024.01.09 |
8일차 데브코스 - 클라우딩 어플리케이션 엔지니어링 TIL (2) | 2024.01.06 |