Language/JavaScript

JavaScript 공부정리 - 객체 - 기본편

Tarel 2022. 9. 28. 21:12

시작하기 전에......

 

이번엔 객체를 중심적으로 다룬다.

 

1. 객체란?

2. 속성과 메소드(this)

3. 화살표함수와 메소드

4. 객체의 속성과 메소드(new)

5. 일반 자료형의 일시적 승급

6. 일반자료형을 위한 새로운 속성 또는 메소드 정의

7. Number의 속성과 메소드

8. String의 속성과 메소드

 


1. 객체란?

객체란 사물이라고 할 수 있고 이름과 값으로 구성된 속성을 가진 기본 데이터 타입이라 할 수 있다.

 

이게 뭔 소리냐?

 

게임 캐릭터를 예시로 설명해보자

 

사진은 오리와 눈 먼숲 시리즈에 등장하는 주인공 오리라는 캐릭터다

이름 오리
종족 가디언
나이 알 수 없음
능력 1 삼단점프()
능력 2 튕겨내기()
능력 3 올가미()
능력 4 파고들기()

 

 

여기서 오리는 객체에 해당한다.

 

그리고 이름, 종족, 나이, 능력 등은 속성에 해당한다.

 

여기서 능력 1~4은 메소드(동작 가능한 함수)라고 할 수 있다.

 

즉 속성은 해당 객체의 특징을 나타내는 것이고

메소드는 해당 객체가 할 수 있는 것들 이라고 할 수 있다.

 

배열 또한 객체의 일종이다.

배열 또한 여러 자료를 다룰 수 있었다.

배열도 객체이기 때문이다.

당장 배열을 typeof로 자료형을 출력해보면 object라고 나오는 것을 알 수 있다.

 

배열과 객체는 유사하지만 배열은 인덱스를 이용해 접근했다면

객체는 키를 이용하여 접근한다.

객체는 중괄호를 사용해 생성하며 쉼표를 연결하여 입력한다.

 

위의 오리를 예시로 만들어보자

const character = {
  name: 'ORI',
  race: 'Guardian',
  age: undefined,
  ability_1: 'tripleJump()',
  ability_2: 'bash()',
  ability_3: 'Grapple()',
  ability_4: 'Burrow()'
}

console.log(character)

// 결과
// name:"ORI"
// race:"Guardian"
// age:undefined
// ability_1:"tripleJump()"
// ability_2:"bash()"
// ability_3:"Grapple()"
// ability_4:"Burrow()"

어빌리티의 tripleJump() 등은 선언된 함수가 아니기 때문에 오류가 발생한다.

때문에 여기선 스트링으로 처리했다.

 

객체 요소에 접근해보자

위의 코드에서 이어진다.

onsole.log(character['name'])
console.log(character.name)

// 결과
// ORI
// ORI

보시다시피 두 가지 접근 방법이 있다.

대괄호에 따옴표로 이름을 가져오는 것과

점을 써서 가져오는 방법 두가지다.

 

사람들은 이 중 점을 쓰는 방법을 더 선호한다.

단, 이름이 식별자로 사용할 수 없는 글자들로 구성된 경우(ex: name!@#!@%)에는 대괄호를 사용해야 한다.

 

2. 속성과 메소드(this)

앞서 말했듯이 속성가운데 함수가 속성이면 메소드가 된다.

아까의 오리의 경우엔 (비록 에러를 피하기 위해 스트링 처리했지만) 어빌리티들이 메소드에 속한다.

 

const character = {
  name: 'ORI',
  race: 'Guardian',
  age: undefined,
  ability_1: 'tripleJump()',
  ability_2: 'bash()',
  ability_3: 'Grapple()',
  ability_4: function (skill) {
    console.log(this.name + '는 ' + skill+ '를 사용')
  }
}

character.ability_4('버로우')

//결과
//ORI는 버로우를 사용

맨 처음 코드에서 4번 기술을 스트링이 아닌 함수로 바꾸었다.

 

여기서 this라는 키워드가 사용되었다.

this란 말 그대로 그 객체를 의미한다.

메소드에서 this 를 사용하면 그 메소드를 사용하는 객체를 뜻한다.

즉, 자신의 상위 개념을 가리킬 때 사용하는 개념이다.

 

3. 화살표함수와 메소드

익명함수와 화살표함수는 메소드로 사용될 때 this를 다른 방식으로 사용한다.

const test = {
	a: function (){console.log(this)},		//익명함수
	b: () => {console.log(this)}			//화살표함수
}

test.a()
test.b()

//결과
//{a: a(), b : b()}
//b의 경우는 실행환경에 따라 결과가 다름

 

b는 window객체를 출력한다.

이는 웹브라우저에서 실행하는 자바스크립트의 핵심 객체라 할 수 있다.

 

이처럼 화살표 함수는 this가 가리키는 대상이 이상해지기 때문에 화살표 함수를 메소드로 사용하지는 않는다.

 

 

4. 객체의 속성과 메소드(new)

앞서 설명했듯 배열은 객체이며 함수도 객체에 해당한다.

단, typeof를 사용해서 함수를 확인해보면 object 타입이 아닌 function 타입으로 나온다.

 

속성은 어디까지나 객체만이 가질 수 있으며 일반적인 자료형은 속성을 가질 수 없다.

때문에 객체가 아닌 대상에게 속성값을 넣어주면 애러는 안뜨지만 반응을 안한다.

const d = '안녕'
d.sample = 10
console.log(d.sample)

// 결과
// undefined

즉, 저런 문장을 쓸 수는 있지만 아무 의미없는 것이라고 할 수 있다.

 

그렇다면 일반 자료형을 객체로 바꿀 수 없을까?

다음과 같은 방법을 쓰면 가능하다.

let n = new Number(273)

변수 n이 선언되었는데 이것은 숫자형 자료를 가진 273이며 이것은 객체로 생성되었다는 의미다.

이제 n을 typeof로 검사해보면 object라고 뜨는 것을 알 수 있다.

 

 

5. 일반 자료형의 일시적 승급

일반 자료형은 속성을 가질 수 없다.

그러나 코딩의 편의를 위해 속성을 사용할 수 있는데, 이 경우 일시적으로 자료형이 승급된다.

a = 'JavaScript'
console.log(a.length)

// 결과
// 10

a는 객체가 아닌 일반 자료형이다.

그런데 langth라는 속성을 사용할 수 있다.

이를 일시적 승급이라고 한다.

a = 'JavaScript'
console.log(a.abcde = 10)
console.log(a.abcde)

// 결과
// 10
// undefined

일시적 승급은 그 순간에만 적용된다.

때문에 abcde라는 속성을 추가해주어도 그 순간에만 적용될 뿐

그 이후에는 적용되지 않아 undefined가 나오는 것을 알 수 있다.

 

 

6. 일반자료형을 위한 새로운 속성 또는 메소드 정의

 

prototype속성을 사용하여 가능하다.

Number.prototype.abcde = 10;

const i = 24;

console.log(i)
console.log(i.abcde)

// 결과
// 24
// 10

Number는 자료형, 즉 숫자임을 뜻한다.

그리고 abcde라는 속성을 새로 생성했고 이것은 10이라는 숫자를 가진다.

이제 자료형에 abcde라는 속성을 넣어주면 10이 출력된다.

 

 

Number.prototype.abc = function (n){
	return this.valueOf() **n
}

const a = 12
console.log(a.abc(3))

// 결과
// 1728

여기서 **은 제곱을 뜻한다.

즉 **n은 n제곱을 말한다.

 

this는 이것, 즉 자신을 사용할 존재을 뜻하고

valueOf()는 function에 입력된 값을 뜻한다 (사실 이부분은 생략해도 된다.)

 

정리하자면 abc라는 메소드는 파라미터로 n을 받으며 자신을 사용할 존재가 가진 값에 n제곱을 리턴한다는 뜻이다.

 

때문에 a.abc(3)은 12의 3제곱인 1728이 출력된다.

 

보너스

indexOf() 메소드는 문자열의 위치를 말해준다.

const j = '안녕하세요안녕하세요';

console.log(j.indexOf('안녕'))
console.log(j.indexOf('녕'))
console.log(j.indexOf('뷁'))

// 결과
// 0
// 1
// -1

안녕이라는 글자는 j의 0번에서 시작하고

녕이라는 글자는 j의 1에 위치해 있다.

단, 중복되는 글자가 있을 경우 가장 앞에 있는 글자를 리턴한다.

 

만약 없는 글자를 호출할 경우, -1을 리턴한다.

즉, 이 메소드를 사용해서 얻은 값이 0 이상이라면 파라미터 내의 문제를 포함한다고도 할 수 있다.

 

이 메소드는 배열에 사용할 경우, 해당 인덱스에 있는 값을 보여준다 (입력은 당연히 숫자로 해야한다.)

 

 

7. Number의 속성과 메소드

 

toFixed(n)는 해당 변수의 소숫점 n번째 자리까지 표시할 때 쓰인다.

const i = 3.141592
console.log(i.toFixed(0))
console.log(i.toFixed(1))
console.log(i.toFixed(2))

// 결과
// 3
// 3.1
// 3.14

 

 

isNaN(n)은 Number와 함께 쓰며, Number.isNaN(n)이라고 쓰며 n의 값이 NaN인가 여부를 출력한다.

const i = 3.141592
const j = '자바스크립트'
const k = Number('asdf')
console.log(Number.isNaN(i))
console.log(Number.isNaN(j))
console.log(Number.isNaN(k))
console.log(Number(j))

// 결과
// false
// false
// true
// nan

여기서 이상한 점이 하나 있다.

자바스크립트라는 문자열이 NaN이 아니라고 출력한 것인데

막상 자바스크립트라는 문자열을 Number로 출력하면 nan이라고 뜨는 것이다.

아직은 원인을 알 수 없으니 지금은 넘어가자

 

isFinite(n)은 Number와 함께 쓰며, Number.isFinite(n)이라고 쓰며 n의 값이 무한인가 여부를 출력한다.

정확히는 n은 셀 수 있는 숫자인가? 를 묻는 여부다.

무한으로 만드는 방법은 간단한데 그냥 0으로 나누어주면 된다.

const i = 10 / 0
const j = -5 / 0
console.log(i)
console.log(j)
console.log(Number.isFinite(i))

// 결과
// Infinity
// -Infinity
// false

보통 0으로 나누는 것은 금지되어 있으나

실제로 나눗셈을 할때 양수를 0에 가까운 값으로 나누어줄수록 값이 커지는 것을 알 수 있다.

때문에 0에 가까운 값이 아닌 0으로 나누어 줄 경우 무한이 나올 수 있으며 이러한 특징 때문에 0으로 나누는 것은

통념상 금지되어 있지만 자바스크립트에서는 무한으로 출력하며 음수를 나누어주면 -무한이 출력된다.

 

마지막으로 i가 셀 수 있는 숫자인가? 라는 질문에서 false라고 출력하는 것을 알 수 있다.

 

8. String의 속성과 메소드

trim()은 문자열 앞 뒤에 있는 공백과 줄바꿈을 없애준다.

const a = '   가나다\n라마 바 사\n\n'
const b = '경계선'
console.log(a)
console.log(b)
console.log(a.trim())
console.log(b)

// 결과
//  가나다
//라마 바 사
//
//경계선
//가나다
//라마 바 사
//경계선

a는 문자열 앞이 띄어쓰기, 뒤는 줄바꿈으로 이루어 져있다.

그러나 trim을 사용하자 문자열의 앞 뒤에 있던 띄어쓰기와 줄바꿈이 사라졌다.

 

split()는 문자열을 다른문자열을 기준으로 잘라서 배열을 만든다.

const a = '하나, 둘, 셋, 넷, 다섯'
console.log(a.split(','))

// 결과
// ["하나", " 둘", " 셋", " 넷", " 다섯"]