※ 책 [혼자 공부하는 자바스크립트]를 공부하며 기록, 정리해 놓은 노트이다.
목차
객체의 속성과 메소드 사용하기
기본 자료형, 객체 자료형, 기본 자료형의 승급, prototype
요약:
객체 자료형 object
: 속성과 메소드를 가질 수 있는 모든 것. 배열도, 함수도 객체다.
배열도 객체라는 건 배열을 하나 만들고 거기에 속성을 동적으로 부여할 수도 있다는 얘기!
> const a = []
undefined
> a.sample = 10
10
> a.sample
10
배열은: 객체 맞지만 typeof로 검사 ⇒ ‘object’ | Arrays.isArray()로 검사 ⇒ true
함수는: 객체 맞지만 typeof로 검사 ⇒ ‘function’(=’실행 가능한 객체’라는 특이한 자료형)
함수는 일급 객체에 속한다. 객체의 특성을 완벽하게 가지고 있어서.
일급 객체 first-class object(citizen)
…
기본 자료형 primitives(primitive types)
: 실체가 있는 것(undefined와 null 등이 아닌 것) 중에 객체가 아닌 것.
= 숫자, 문자열, 불.
기본 자료형은 속성과 메소드를 가질 수 없다.
(+ 추가)
원시값이란 객체가 아니면서 메서드도 가지지 않는 데이터를 말한다. 7종류가 있는데
string, number, bigint, boolean, null, undefined, symbol 이 바로 원시형이다.
불변하여 변할 수 없다는 특징을 지님.
예를 들면 한 번 만든 문자열은 대문자로 바꿀 수 없음.
let bar = 'bar';
bar.toUpperCase();
console.log(bar); // 'bar'
null과 undefined를 제외하면 모두가 래퍼 객체(String, Number, Bigint, Boolean, Symbol 객체)를 갖는다. 이 래퍼 객체의 valueOf() 메소드로 원시 값을 반환받을 수 있다.
(참고: MDN Web Docs )
기본 자료형을 객체로 선언하기
const 객체이름 = new 객체_자료형_이름()
예시:
new Number(10)
new String(’안녕하시오’)
new Boolean(true)
주의!
new 키워드를 사용하지 않으면 객체를 생성하는 게 아니라 형변환 기능으로 작동된다.
const age = new Number(32)
라고 쓸 것을
const age = Number(32)
라고 실수하지 않도록 주의할 것.
기본 자료형의 일시적 승급
자바스크립트에서 사용의 편리성을 위해서 기본 자료형의 속성과 메소드를 호출하려고 할 때 일시적으로 기본 자료형이 객체로 ‘승급’되도록 만들어 놓은 것. 그래서 ‘원숭이,닭,개’.split(’,’)
같이 쓸 수 있는 것이었다.
이렇게 ‘일시적’인 승급은 해당 문장이 종료되면 바로 사라진다. 결국 기본 자료형으로 속성과 메소드를 사용할 수는 있지만 추가해서 유지시킬 수는 없다는 말이 된다.
프로토타입으로 메소드 추가하기
기본 자료형인 숫자/문자열/불에도 속성과 메소드를 추가하여 사용할 수 있게 하기 위한 방법이 바로 객체의 prototype이라는 속성을 이용하는 것이다. 더 정확히는, “어떤 객체의 prototype이라는 속성에 속성이나 메소드를 추가하는 것”이다.
객체_자료형_이름.prototype.메소드나_속성_이름 = 값
프로토타입 객체 prototype object
: 객체의 틀. 목표 타입의 프로토타입 객체에 속성과 메소드를 추가하는 식이다. 프로토타입 객체에 저장된 속성과 메소드는 해당 객체(의 인스턴스) 전체에서 사용할 수 있게 된다.
예를 들어 Number.sample = 10 이렇게 하면 자바에서 ‘클래스 변수 - 인스턴스 변수’인 느낌이다. 즉, Number라는 클래스에는 sample이 속성으로 들어가는데 인스턴스를 생성하면 그게 조회가 안된다.
예를 들어 Number.prototype.sample = 10 이렇게 하면 자바에서 ‘인스턴스 변수 - 클래스 변수’인 느낌이다. 이번엔 인스턴스에서는 조회가 되는데 클래스로는 조회가 안된다.
> (function () {
Number.prototype.power = function (n=2) {
return this.valueOf() ** n;
}
}) ()
> console.log(12.power())
Uncaught SyntaxError: Invalid or unexpected token
> const num = 12
> console.log(num.power())
144
'일시적 승급' 후 '프로토타입 발 메소드'로 호출 ...될 줄 알았더니 이건 안되네.
=> 일시적 승급이 될래도 일단 ‘숫자’가 변수나 상수로 할당은 되어야 가능한가보다.
- 이상하다. 프로토타입으로 속성을 추가한 경우들 중, 배열, 문자열, 불은 그냥 “쌩 자료.추가속성”으로 조회가 가능한데, 유독 숫자형만 그게 안된다. 위의 예시처럼 12.power() 하면 에러가 나는 식이다. 꼭 new Number(12).power() 이렇게 인스턴스를 명시적으로 만들고 써줘야 작동한다. 다른 애들은 new String(’안녕’).contains(’안’)라고 호출하든지 그냥 ‘안녕’.contains(’안’)이라고 하든지 상관없이 잘만 되던데. 심지어 불도 프로토타입 지정해주고 나면 false.fire ⇒ ‘need water!!’ 식으로 잘만 작동한다. 그 모든 기본형과 객체형 중에 숫자형만 특별 취급인 것 같다.
- ⇒ 한 마디로, 다른 애들은(모든 객체와 문자형/불형 포함해서) 리터럴을 인스턴스로 인식해주는데 유독 숫자형만 리터럴을 인스턴스로 보지 않는 것 같다.
- =⇒ A. 헐헐 그게 아니다..! 20 뒤에 점을 찍으면 ‘또 숫자가 오겠지(소수점)’하고 기대하고 있는데 속성을 불러버려서 ‘기대를 벗어낫다 오류’를 내보내는 거였다..! 20.power()는 에러가 나지만 20.0.power()는 400을 잘 뱉어내는 것으로 알 수 있다. 뿐만 아니라 20[’power’]()도 400을 뱉어내며 잘 작동한다!
⇒ 결국 숫자형만 (리터럴을 인스턴스로 인정 안해주는)특별취급은 아니었던 걸로.
⇒ 결국 20.0.power()를 실행한다: 1. 기본형을 객체로 임시 승급 후 2. 프로토타입 발 메소드를 호출. 이렇게 처음 한 가정이 맞았다.
⇒ 결론: 그냥_리터럴 + 프로토타입으로_동적_추가해준_메소드나_속성 조합으로 호출이 가능하다. ex. [1,2,3].contains(1)
- =⇒ A. 헐헐 그게 아니다..! 20 뒤에 점을 찍으면 ‘또 숫자가 오겠지(소수점)’하고 기대하고 있는데 속성을 불러버려서 ‘기대를 벗어낫다 오류’를 내보내는 거였다..! 20.power()는 에러가 나지만 20.0.power()는 400을 잘 뱉어내는 것으로 알 수 있다. 뿐만 아니라 20[’power’]()도 400을 뱉어내며 잘 작동한다!
⇒ 결국 숫자형만 (리터럴을 인스턴스로 인정 안해주는)특별취급은 아니었던 걸로.
- ⇒ 한 마디로, 다른 애들은(모든 객체와 문자형/불형 포함해서) 리터럴을 인스턴스로 인식해주는데 유독 숫자형만 리터럴을 인스턴스로 보지 않는 것 같다.
블록 안에서(즉시 호출 함수 안에서) Number.prototype.power = function (n=2) { … }를 정의했는데도 블록 밖에서 만든 인스턴스에서 .power()를 호출할 수 있었다. 이로 보건데 분명히 .prototype으로 할당하는 속성은 블록에 종속되어 있지 않다. 다른 저장 공간이 따로 있는 듯.
⇒ 프로토타입으로 추가하는 속성(메소드)은 블록 안에서 정의해도 밖에서 쓸 수 있다.
대표 객체들 - Number, String, JSON, Math
Number 객체에서 자주 쓰는 메소드:
- 소수 자리에서 반올림하기: 20.789.toFixed(1) ⇒ 20.8 // 반올림
- 숫자가 NaN인지 체크: Number.isNaN(’숫자아님’) ⇒ true // m === NaN로는 false가 반환되어 체크할 수 없음.
- NaN을 양성하는 방법: const m = Number(’숫자가 아닌 걸 숫자형으로 형변환하기’) ⇒ m은 NaN이 됨(타입은 ‘number’).
- 숫자가 Infinity인지 체크: Number.isFinite(-10/0) ⇒ false
- 양의 무한대 만들기: const n = 10 / 0 ⇒ Infinity
- 음의 무한대 만들기: const m = -10 / 0 ⇒ -Infinity
- 양과 음 무한대는 비교 연산자로 비교가 가능하다: n === Infinity || n === -Infinity ⇒ true
String 객체에서 자주 쓰는 메소드:
- 양 끝 공백 없애기: ‘ \n줄바꿈이나 공백 다 없앰 ‘.trim() ⇒ ‘줄바꿈이나 공백 다 없앰’
- 특정 구분자를 기준으로 자르기: ‘원숭이,닭,개’.split(’,’) ⇒ [’원숭이’, ‘닭’, ‘개’]
- .length
- .indexOf()
JSON 객체에서 자주 쓰는 메소드:
JSON = JavaScript Object Notation : “자바스크립트의 객체처럼 자료를 표현하는 방식”이라는 뜻!! 딕셔너리 형식이 자바스크립트 발이었다니 충격.
JSON 형식의 규칙:
- 값을 표현할 땐 문자열, 숫자, 불만 사용 가능(함수 등은 사용 불가)
- 문자열은 반드시 큰따옴표로 만들 것
- 키에도 따옴표를 붙일 것
- 자바스크립트의 배열과 객체의 조합으로 표현한다 ex. 배열1[객체1, 객체2,…]
JSON 객체의 메소드는 두 가지뿐:
- 자바스크립트의 객체를 JSON 문자열로 변환할 때: JSON.stringify(javascript_object, null, 4)
- 반대로 JSON 문자열을 자바스크립트 객체로 변환할 때: JSON.parse(json_data)
Math 객체에서 자주 쓰는 메소드:
- Math.PI / Math.E
- Math.sin() / Math.cos() / Math.tan()
- 0 이상 1 미만의 랜덤 숫자 만들기: Math.random()
- -5 ~ 5 사이의 랜덤한 숫자: Math.random() * 10 - 5
- -5 ~ 5 사이의 랜덤한 정수: Math.floor( Mtah.random() * 10 - 5) )
참고:
[책] 혼자 공부하는 자바스크립트 - 윤인성
Uploaded by N2T