0821 개발일지

Yesol Lee·2021년 8월 21일
0

AI스쿨_개발일지

목록 보기
40/57

학습내용

생성자함수, prototype, this (1), (2)
js-typing
github커밋

생성자 함수

  • 객체 지향 프로그래밍 (OOP - Object Oriented Programming)
  • 생성자 함수: 첫 글자 대문자로 작성
  • 생성자 함수 안 this는 인스턴스 자체를 가리킴
function Heroes(name, age) {
    this.name = name;
    this.age = age;
};

// 인스턴스 = new 함수이름(인자)
var superMan = new Heroes('Super Man', 30);
var blackWidow = new Heroes('Black Widow', 34);

인스턴스에 메서드 만들기

function Person(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;

    this.fullName = function() {
        console.log(this.firstName + " " + this.lastName);
    }
}
var lee = new Person('Yesol', 'Lee');
var heo = new Person('JuYeon', 'Heo');

heo.fullName();

prototype

  • Person 생성자 함수를 만들 때 Person.prototype 객체가 함께 생성됨
  • prototype 객체에 fullName() 메서드 추가함
  • Person.prototype = 조상. 조상의 메서드 상속받아 사용 가능
  • 개별 인스턴스가 메서드 가지고 있지 않아 메모리 절약할 수 있음
  • 메서드 등 모든 객체가 동일한 속성 가지고 있는 부분은 prototype에 적용하면 좋을 듯
function Person(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
}

Person.prototype.fullName = function () {
    console.log(this.firstName + " " +this.lastName);
}

// 인스턴스: 후손. 생성자 안 메서드 없어도 prototype의 메서드 사용 가능
var heo = new Person('JuYeon', 'Heo');

heo.fullName();

proto와 constructor

proto: 인스턴스의 조상(prototype) 탐색

  • 인스턴스의 prototype 알아내기 = 인스턴스.proto
  • 생성자로 만든 string은 데이터타입이 문자열이 아닌 객체이다.
  • 자바스크립트 모든 객체는 Object.prototype의 자손

prototype: 생성자 함수와 함께 만들어 진 객체

  • 생성자 함수가 만들어짐과 동시에 해당 함수로 prototype 객체가 만들어지고, 이 prototype이 이후 만들어진 모든 instance의 조상(instance.proto)가 된다.

constructor: 인스턴스의 생성자 함수 보여주는 속성

  • 인스턴스의 생성자 함수 알아내기 = 인스턴스.constructor
// 생성자 함수
function Person (firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
}
// 생성자 함수로 인스턴스 생성
var lee = new Person('Yesol', 'Lee');

console.log(lee.__proto__ === Person.prototype); // true
console.log(Person.prototype.__proto__ === Object.prototype); // true
console.log(lee.__proto__ === Object.prototype); // false 중간단계 뛰어넘기 불가능

console.log(Person.__proto__ == Function.prototype); // true
console.log(Function.prototype.__proto__ === Object.prototype); // true

// 인스턴스와 prototype은 모두 생성자함수로 만들어 진 객체
console.log(lee.constructor === Person); // true
console.log(Person.prototype.constructor === Person);

this

this의 경우의 수: this가 포함된 위치에 따라 가리키는 대상 달라짐

  1. 일반 함수 this -> window (브라우저)
  2. 중첩함수 this -> window (브라우저): 중첩 함수 안 this는 무조건 window
  3. 이벤트에서 this -> 이벤트 객체
  4. 객체의 메서드 안 this -> 객체
  5. 메서드 안 함수 this -> window (브라우저)

일반함수, 중첩함수 this 예시

function a () {
    console.log(this);
    function b () {
        console.log(this);
    }
    b(); // this = window
};
a(); // this = window

이벤트의 this

var btn_prev = document.querySelector('.btn-prev');
btn_prev.addEventListener('click', function() {
    console.log(this); // this = btn_prev
});

메서드 안 this

var obj = {
    age: 54,
    sum: function () {
        console.log(this.age); // this = obj
      
        function c () {
            console.log(this); // 중첩함수라서 this = window
        }
        c(); 
    }
};
obj.sum();

중첩함수의 this도 객체를 가리키게 하고 싶을 때: 변수 that에 this 저장

var obj = {
    age: 54,
    sum: function () {
        console.log(this.age);
        var that = this;

        function c () {
            console.log(that);
        }
        c(); // 중첩함수라서 this = window
    }
};
obj.sum();

실습 1: 생성자 사용

  • 어제 했던 이미지 리스트 정보들을 담은 이미지 객체를 생성자 함수로 생성하는 연습
var arr = [];
var i = 0;
// 이미지 정보 객체 생성자 함수
function NatureImage(name, img, txt) {
    this.name = name;
    this.img = img;
    this.txt = txt;
}
// 생성자 함수로 이미지 인스턴스 만들어 배열에 삽입
function createNatureImage (name, img, txt) {
    var fullImg = `img/img-${img}.jpg`;
    var natureImage = new NatureImage(name, fullImg, txt);
    arr.push(natureImage);
};

createNatureImage('nature 1 name', 1 , 'nature 1 description');
createNatureImage('nature 2 name', 2 , 'nature 2 description');
...

실습 2

일정 시간마다 무한히 반복되는 함수 만들기: setTimeOut(f(x), time) 활용

  • % 나머지 연산의 특징을 이용해 index값이 무한히 늘어나도 current는 배열 인덱스값 안에서 무한히 반복되도록 한다.
  • setTimeOut() 함수 내부에서 loop() 함수 자신을 다시 호출하면 2초마다 무한히 반복하게 할 수 있다.
var arr = [10, 20, 30];
var index = 0; // 기준점

function loop() {
    var current = index % arr.length; // 0 % 3 = 0
    console.log(arr[current]);
    index++;

    setTimeout(function() {
        loop()
    }, 2000);
}
loop();

2. 배열 안 단어를 한 글자씩 생성, 삭제하기

1. 가져올 단어의 리스트, 단어를 띄울 html 태그를 가져온다.

var words = ['엔드게임', '인피니티 워', '에이지 오브 울트론'];
var txtElement = document.getElementById('txt');

2. 작업에 필요한 속성들을 가진 생성자 함수를 만들고 호출해둔다.

function TypeWriter(txtElement, words) {
    this.txtElement = txtElement; // html 태그
    this.words = words; // 단어 리스트

    this.txt = ""; // 출력할 텍스트
    this.wordIndex = 0; // 리스트에서 가져올 단어 인덱스
    this.isDeleting = false; // 현재 작성 중/삭제 중인지 

    this.type(); // 실제 작성하는 함수 실행시켜 둠
};

// 인스턴스 없어도 생성자 함수 호출 가능
new TypeWriter(txtElement, words);

3. 프로토타입의 type 함수 작성

  1. 현재 작성 중, 삭제 중 상태에 따라 배열 안 단어에서 필요한 부분 잘라서 가져오기
TypeWriter.prototype.type = function() {
  // 현재 배열 안 데이터 가져오기
  var current = this.wordIndex % this.words.length;
  var fullTxt = this.words[current];

  // 각 단어에서 필요한 부분만 잘라서 가져오기
  // substring(start, end): start부터 end 직전까지. 인자 1개면 start 이후부터 가져오기
  if(this.isDeleting) {
    this.txt = fullTxt.substring(0, this.txt.length - 1);
  } else {
    this.txt = fullTxt.substring(0, this.txt.length + 1); // 글자수보다 1개 더까지 잘라내기
  }
  this.txtElement.textContent = this.txt;
}
  1. // 글자가 완성되었을 때, 글자가 모두 삭제되었을 때 상태 변경
if(!this.isDeleting && this.txt === fullTxt) {
  this.isDeleting = true;

} else if (this.isDeleting && this.txt === ""){
  this.isDeleting = false;
  this.wordIndex++; // 다음 단어로 넘어가기
}
  1. 일정 시간마다 자기 자신 호출
  • 원 코드는 무한히 반복되지만 wordIndex를 활용해서 멈추는 지점을 추가해주었다.
var that = this; // 중첩함수 안에서도 객체 선택하기 위한 코드

setTimeout(function() {
  console.log(that);

  // 멈추는 지점 추가
  if(that.wordIndex<5) {
    that.type();
  }

}, 500);

기타

Templete Literal: 백틱(`) 사용해서 문자열 만들기 (ES6)

  • 백틱 안 문자열을 쓰고 js 변수는 ${}안에 작성할 수 있다.
var name = 'mango';
console.log("my name is " + name);
console.log(`my name is ${name}.`);

어려웠던 점

  1. 생성자 함수, __proto__, prototype, constructor 등 특정 속성 혹은 객체와 그 속성을 찾는 방법이 섞여 있어서 헷갈렸다.
  2. 마지막 문자열 차례로 나타내는 실습 과제를 하는데, 아마도 생성자 등의 실습을 위해 구성한 문제라서 그렇겠지만 풀이 과정이 새로웠다. 내가 그냥 문제를 풀었으면 생각해내지 못했을 방법이다.

해결방법

  1. 각 개념의 속성과 목적을 분명히 구분했다.
  2. 다른 방향의 문제 풀이법을 익혔다고 생각해야겠다.

소감

html, css를 사용할 때와 다르게 좀더 논리적인 과정이 많이 필요해졌다고 느낀다. 디자인과 다르게 어느정도 순차적인 기능을 구현해야 하기 때문이라고 생각한다. 어서 진도를 나가서 웹사이트 기능을 만들어 보고 싶다.

profile
문서화를 좋아하는 개발자

0개의 댓글