본문 바로가기
시작/TIL(Today I Learned)

221104 - JavaScript - prototype, 메서드 Date, indexOf, 삼항연산자

by 백씨네 2022. 11. 5.

오늘 내가 배운 것

1. prototype

  • `자바스크립트는 무슨 언어이냐?` 
  • 추상적이냐 구체적이냐
  • prototype 언어의 특성

2. Date()

  • 날짜 - Date 객체 다루기

3. indexOf()

  • indexOf
  • EX.  'indexOf()'  의 활용 - 4가지 방법

4. 삼항 연산자

 

1. Prototype

 

`자바스크립트는 무슨 언어이냐?` 


흔히 알고 있는 언어는 함수형 언어와 객체지향 언어가 있다. (더 많은 종류가 있겠지만 가장 많이 보인 것은 두 가지였다.)

그리고 많은 곳에 자바스크립트는 객체지향 언어다 라는 말도 많이 보였는데,
사실 자바스크립트는 `프로토타입(prototype)` 언어이다.

프로토타입은 `원래의 형태`, `원형`이라는 뜻을 가지고 있는데 객체지향 언어와 비교했을 때 객체지향 언어는 객체를 만들기 위해 가상의 틀을 만들고 거기에 속성 값을 넣어 객체의 특성을 분류하고 그 뒤에 객체를 만들어내는 반면, 프로토타입 언어인 자바스크립트는 객체를 만드는 과정에서 분류를 한다. 그리고 다른 객체를 만들 때 앞서 만든 객체와 같은 분류라고 생각되면 그 뒤를 상속받아서 객체를 만들어 간다.

자바스크립트는 단일 상속만을 허용하는 언어로 객체엔 하나의 분류만 상속받을 수 있는데, 제약이 많아 더 상속받고 싶을 때가 있는데 `믹스인`이라는 기법을 이용해서 프로토타입을 바꾸지 않고 한 객체를 다른 객체에 복사해서 사용할 수 있는 방식이 있다. (믹스인은 나중에 다시 조사해볼 예정)


추상적이냐 구체적이냐


프로그래밍에서 추상적인 것과 구체적인 것을 나눠보면
`추상적인` 과 `가상` 과 `class`가 비슷하고, `구체적인` 과 `실체` 와 `인스턴스`가 비슷하다고 볼 수 있다.
인스턴스를 생성한다는 말은 구체적으로 무언가를 만든다는 뜻이 될 수 있고
class를 만드는 것을 추상적으로 어떠한 틀을 만든다고 볼 수 있을 것 같다.

일반적인 객체지향 프로그래밍은 최소 기능(분류)부터 하면서 큰 기능을 구현한다.
큰 문제를 작게 쪼개는 방식이 아니라 작은 문제들을 해결할 수 있는 객체들을 만든 뒤 (class), 이 객체들을 조합해서 큰 문제를 해결하는 Bottom-Up 방식을 지향하는 것이다.
하지만 프로토타입 언어인 자바스크립트는 `근본적으로` 객체를 만들고 이미 있는 객체를 상속해서 다른 객체를 만든다. 즉, 추상적인 것으로부터 실체를 만드는 것이 아니라 이미 있는 것을 가지고 분류를 하자의 의미이다.

결론으로는 최근 자바스크립트의 스펙이 업그레이드 되면서
`class`, `arrow function` , `let`, `const` 등 prototype의 원형을 바꾸려 한다. 
지금의 트렌드는 자바스크립트를 객체지향처럼 사용하고 싶어 한다. 그래서 객체지향 적으로 배우고 prototype인 자바스크립트의 코딩 스타일을 `객체지향`처럼 해야 한다. 그저 prototype 언어의 본질을 알기 위해서 알아봤다.

 

class를 이용한 객체지향 언어

//'새'라는 큰 추상적인 틀을 만든다.
//공통적인 속성을 만들어 두고 객체를 만들 때 상속을 시키는 것. 
class 새 {
    constructor(){
        this.날개갯수 = 2
        this.날수 있나 = true
    }
}      
       부모        자식           
class 비둘기 extends 새 {
    constructor(){

    }
}

extends 상속한다는 뜻으로 비둘기 속성 안에 새라는 속성이 있는 것이다.
새를 만들어야 비둘기를 만들 수 있기 때문에 객체지향이 어렵다 분류해야 할 것이 너무 많다. 대표적인 장점은 추후 확장성이 좋다.

 

prototype 언어

// 생성자 함수를 이용한 객체 생성
function 새(){
    this.날개갯수 = 2
    this.날수있나 = true
}
const 비둘기 = new 새()
console.log(비둘기)
// 참새라는 새로운 객체를 만드려 한다.
// 참새는 기본적으로 새가 가지는 것 말고 크기가 작다는 속성이 있다.

function 작은새(){
    this.크기 = "작다"
}
//다른 객체(참새)를 생성할 떄 기존에 있던 객체(비둘기)를 이용하여 객체를 생성한다.
작은새.prototype = 비둘기
const 참새 = new 작은새()
console.log(참새)

//객체지향 : 분류를 확실하게 해라
//프로토타입 : 분류를 하면서 정해라   왜냐하면 사람마다 다르니지 않냐..!

console.log(참새.날수있나)// True.. 비둘기가 가지고 있는 속성을 받은 상태

필요한 것을 일단 분류하지 않고 일단 객체를 만들어서 쓰고 필요할 때 그것을 상속해서 만든다.

prototype 언어의 특성

호이스팅

자바스크립트는 실체, 의미에 많이 치중하는 편이다.
그래서 자바스크립트를 실행했을 때 결정이 되는 경우가 많다. 대표적인 게 `호이스팅`이다.

호이스팅을 막기위해 신문법이 많이 나온 것이므로 호이스팅을 설명하기 위해선 옛날 문법을 쓸 수밖에 없다. `var` 나 `function`

// 출력이 되는 것이 무엇일까요?
var name = "gildong"

init()
function init(){
    var name = "홍길동" 
    function displayName(){
        console.log(name)
        var name = "길동"
    }
    displayName()
}

자바스크립트는 실행될 때 결정되는 것이 많다.

면접 단골 질문 - 언제 호이스팅이 되냐?
-실행 컨텍스트 생성 시 렉시컬 스코프 내에 선언이 끌어올려지는 게 호이스팅


실행이 될 때 전체를 묶어서 콜스텍이 하나 쌓이고 init()이 쌓이고 displayName이 실행되기 위해 하나 쌓인다.(실행 컨텍스트 생성) 그리고, displayName의 console.log(name) 부터 실행이 되는데, 밑에 var 키워드가 있으면 var name 이 렉시컬 스코프(init 함수 코드블럭 내) 내의 최 상단으로 끌어올려진다. 이때 name 뒤는 올려지지 않음.  
그래서 var name으로 선언은 했는데 할당되는 게 없는 상태에서 console.log를 만나 undefined로 출력이 되는 것이다.
만약 ` var name = "길동" `이 없다면 ` function displayName(){` 의 위에 있는 ` var name = "홍길동" ` 이 밑에 내려와 `홍길동` 이 출력되었을 것이다.

어차피 코드를 짤 때 호이스팅 안되게 코드를 짤 것이다.

this

this의 역할이 실행될 때 뒤죽박죽 된다.. 근데 거기서 패턴은 있다. 그걸 node.js때 이용하기는 하는데 그때 다시 설명하고 배울 예정..

 

 

2. 날짜 - Date 객체 다루기

 

Date() - javascript 기본적으로 내장되어있는 생성자 함수이다. new키워드를 이용해서 작성한다.

// 인자를 안쓸 때
new Date() // 현재 시간 출력

// 인자가 1개이고, 데이터 타입이 'number'인 경우
//인자가 1개인 경우 milliseconds (1/1000)로 인자값을 갖는다.
new Date(0) //UTC 기준 1970-01-01 00:00:00
new Date(1000) // 1초 늘어남.
new Date(24 * 3600 * 1000) // 1일 늘어남. 

// 인자가 1개이고, 데이터 타입이 'string'인 경우
// 직관적으로 원하는 시간을 표현 할 수 있다.
new Date('2022-11-04')

// 인자가 n개이고, 데이터 타입이 'number' 인 경우
// 년 월 일 시 분 초 + "요일"

const dt = new Date(2022, 11, 04)

dt.getFullYear()
현지 시간 기준 연도(네 자리 연도면 네 자리로)를 반환합니다.
dt.getMonth()
현지 시간 기준 월(0–11)을 반환합니다.
dt.getDate()
현지 시간 기준 일(1–31)을 반환합니다.
dt.getHours()
현지 시간 기준 시(0–23)를 반환합니다.
dt.getMinutes()
현지 시간 기준 분(0–59)을 반환합니다.
dt.getSeconds()
현지 시간 기준 초(0–59)를 반환합니다.

 

3. indexOf

 

string 타입에서 작성되는 메서드 indexOf(), 괄호 안에 인자로 내가 찾고자 하는 값이 있는지 확인하는 기능

//찾는 위치의 첫 시작점을 출력해준다.
const text = 'javascript' //글자수 만큼 0부터 표현한다.
text.indexOf('java') // 0
text.indexOf('script') //4
text.indexOf('a') //1 //여러개 있어도 제일 먼저 만나는걸 표현
text.indexOf('hello') // -1 없어서..

찾는 글자의 시작점을 알려준다. 값이 있으면 있는 위치를 정수로 표현해주고 값이 없으면 -1 이 출력된다.

 

 

EX.  'indexOf()'  의 활용

url을 모아서 정리하려고 하는데 넘겨준 데이터 값에 `https://` 이 있는 사람이 있고 없는 사람이 있었다..
몇 개정도였다면 하나씩 찾아서 하는 게 빨랐겠지만 1,000개 단위 10,000개 단위일 경우 하나씩 찾아보기 어렵다.
이때, indexOf를 활용해서 `https://` 가 없는 곳을 찾아서 넣어 줄 수 있다.

 

function Blog(url) { 
    this.blog = setBlog(url)
    this.type = setType(url)

    function setBlog(url){
        if(url.indexOf("https://" === -1)){
            return "https://" + url
        }
        return url
    }
    function setType(url){
        if(url.indexOf('tistory.') >= 0){
            return 'tistory'
        }
        if(url.indexOf('velog.') <= 0 ){
            return 'velog'
        }
        return null
    }
}

const a = new Blog("https://baekspace.tistory.com/")
const b = new Blog('baekspace.tistory.com')
const c = new Blog('5678.velog.io/12435')

console.log(a)
console.log(b)
console.log(c)

 

 

// 삼항 연산자로 return값 바꾸기

function Blog(url) { 
    this.blog = setBlog(url)
    this.type = setType(url)

    function setBlog(url){
        return  (url.indexOf("https://" === -1)
        ? "https://" + url
        : url
        )
    }
    function setType(url){
        if(url.indexOf('tistory.') >= 0){
            return 'tistory'
        }
        if(url.indexOf('velog.') <= 0 ){
            return 'velog'
        }
        return null
    }
}

 

 

//생성자 문법 -> class로 바꾸기
class Blog{
    constructor(url) {
        this.setBlog = url
        this.setType = url
    }
    set setBlog(value) {
        this.blog = value.indexOf('http://') === -1 ? "http://" + value : value
    }
    set setType(value){
        this.type = value.indexOf("tistory") === -1 ? 'velog' : 'tistory'
    }
}

 

 

//setBlog를 외부변수로 묶어서 할당 받기

class Blog{
    //ES7 멤버변수
    blog;
    type;
    name; 

    constructor(url){
        this.setBlog = url
        this.setType = url
    }
    set setBlog(value){
        let result = value
        if(value.indexOf("http")=== -1) {
            result = "http" + value
        }
        this.blog = result
    }
    set setType(value){
        if(value.indexOf('tistory.') !==-1){
            this.type='tistory'
        }
        if(value.indexOf('velog.') !==-1){
            this.type='velog'
        }
    }
}

 

ES7에 추가된 `멤버 변수`라는 것이 있는데 class 밑에 내가 보이고자 하는 값들의 속성을 먼저 기입해 줄 수 있다. 만약 그 밑에서 보이고자 했던 값에 대한 결과값이 없다면 undefined을 출력한다.

 

앞에 선언 없이 출력하고 싶은 속성을 기입하면 된다.

 

 

4. 삼항 연산자

 

항이 3개이다. (조건, True 일 때, False 일 때)

개념은 if문과 같다. 하지만 문법이 다르다. 

 

//기본 if문 문법  
let result
if (true) {
    //실행
    result = 1
}else {
    //샐행
    result = 2
}

    //기본문법
let result = (조건) ? true : false

 

기본 if문과 삼항 연산자의 결과물은 같은 결과물을 주게 된다.
기본 문법은 조건을 먼저 작성 후 "?"를 구분자로 넣고 true 와 false 사이에 :(콜론) 구분자를 넣어서 작성을 한다.
'?' 앞 조건문을 판단 후 T이면 콜론 앞에 결과값을, F면 콜론 뒤에 결과값을 출력하여 준다.
중요한 것은 조건이나, 결과값이 아무리 길어도 '?' 와 ':' 사이에 있으면 그 코드는 작동을 한다.
삼항 연산자를 남발하면 가독성이 떨어져 코드가 지저분해 보일 순 있지만
간단한 삼항 연산을 할 때에는 좋다 

 

댓글