[TIL] 211004

Lee Syong·2021년 10월 4일
0

TIL

목록 보기
47/204
post-thumbnail

📝 오늘 한 것

  1. sound.js 작성 / apply / this / 상속 / 다양성

📖 학습 자료

  1. 드림코딩 '프론트엔드 필수 브라우저 101' 강의

  2. 생활코딩 2014 this, 상속 강의


📚 배운 것

1. 리팩토링

당근만 클릭 구현 게임

3. 사운드 파일 만들기

1) sound.js 작성

'use strict';

const bgSound = new Audio('sound/bg.mp3');
const alertSound = new Audio('sound/alert.wav');
const carrotSound = new Audio('sound/carrot_pull.mp3');
const bugSound = new Audio('sound/bug_pull.mp3');
const winSound = new Audio('sound/game_win.mp3');

// 사용자가 매번 오디오 파일을 할당한 변수 이름을 기억할 필요 없도록 함수를 만듦
// 이렇게 안 하면 sound.playSound(carrotSound)처럼 일일이 오디오를 적어줘야 함

export function playBackground () {
  playSound(bgSound);
}

export function playAlert () {
  playSound(alertSound);
} 

export function playCarrot () {
  playSound(carrotSound);
}

export function playBug () {
  playSound(bugSound);
}

export function playWin () {
  playSound(winSound);
}

export function stopBackground () {
  stopSound(bgSound);
}

// main.js에서 가져온 함수들
// 공통적으로 쓰여야 하는 함수이므로 글로벌 스코프에 선언

function playSound (sound) {
  sound.currentTime = 0;
  sound.play();
}
function stopSound (sound) {
  sound.pause();
}

2) main.js 수정

아래와 같이 작성했다.

import * as sound from './sound.js';

sound.playCarrot();

2. 객체 지향 프로그래밍

1) 전역 객체

  • 모든 객체는 전역 객체의 프로퍼티이다.
func();
window.func(); // func()와 같다. window 생략 가능.
window.o.func(); // 전역 객체 window는 o라는 객체를 프로퍼티로 가진다.

2) this

생활코딩 2014 this 강의 참고

함수 내에서 함수 호출 맥락(context)를 의미한다. 함수를 어떻게 호출하느냐에 따라서 this가 가리키는 대상이 달라진다. 자바스크립트에서 this는 함수와 객체를 연결시켜주는 역할을 한다.

(1) 함수 호출

  • 함수 호출 시, ꡸ 함수는 사실 전역 객체 window의 메서드이기 때문에 함수 안의 this는 전역 객체인 window뼟 가리킨다.
function func () {
  if (window === this) {
  console.log('window === this');
}

func(); // window === this

(2) 메서드 호출

  • 객체의 속성이 함수일 때, 이를 메서드라고 한다.

  • 메서드 호출 시, ꡸ 메서드는 객체 소속이기 때문에, 메서드의 this는 ꡸ 객체를 가리킨다.

var o = {
  func = function () {
    if (o === this) {
      console.log('o === this');
    }
  }
};

o.func(); // o === this

사실 (1)과 (2)는 같은 결과이다. (1)에서 func()는 window.func()와 같기 때문이다. (1)과 (2)에서 모두 this는 그것이 작성된 함수가 속한 객체를 의미한다.

(3) 생성자와 this

  • 함수가 new 키워드와 함께 생성자로 쓰이면, this는 만들어진 객체를 가리킨다.

  • 그런데 만약 아래처럼 코드를 작성하면 문제가 발생한다. 생성자 함수 Func()에 if(o2 === this)가 쓰여 있다.

    그러나 맨 마지막 줄에서 생성자 함수를 호출하면 이로 인해 생성된 객체는 이 호출이 모두 끝난 후에야 o2라는 변수에 할당된다. 그 전까지는 객체는 만들어져 있지만, o2라는 변수에는 할당이 되어 있지 않기 때문에 우리는 o2 변수를 통해 그 객체를 참조할 수 없다. 그러므로 생성자 안에서 o2와 this가 같은지를 확인하면 아직 o2는 undefined 상태이므로 이 조건식은 false가 된다.

    반면, this는 생성자 함수에서도 그 생성자 함수로 인해 만들어진 객체를 가리키게 된다. 따라서 this는 객체의 생성이 끝나서 o2라는 식별자에 담기기 전에 그 객체를 참고할 수 있는 식별자라고 할 수 있다.

var funcThis = null;

function Func() {
  if (o2 === this) {
    funcThis = this;
  };
}

var o2 = new Func();

(4) 객체로서의 함수

  • 객체
// 1. 객체 리터럴
// o라는 객체를 만듦
var o = {
  one : 'one',
  two : 'two'
};

// 2. new 연산자와 생성자 함수
// o라는 객체를 만듦
var o = new Object();
o.one = 'one';
o.two = 'two';
  • 함수
// 1. 함수 리터럴
// sum이라는 함수 즉, 객체를 만듦
function sum (x, y) {
  return x + y;
}

// 2. new 연산자와 생성자 함수
// sum이라는 함수 즉, 객체를 만듦
var sum = new Function('x', 'y', 'return x + y');

(5) apply와 this

  • 따라서 함수 또한 객체이므로 ꡸ 프로퍼티로서 메서드를 가질 수 있다. apply는 함수에 사용할 수 있는 메서드 중 하나이다. 이들은 다른 객체 대신 메서드를 호출하는 데 사용된다.

  • 일반적인 객체 지향 언어에서 메서드는 하나의 객체에 고정되어 소속된다. 그러나 자바스크립트에서 함수는 ꡸ 자체로 객체이기도 하지만, 함수를 어떤 맥락에서 호출하냐에 따라 ꡸ 함수가 소속된 객체가 달라질 수도 있다. (주인-노예 관계)

var o = {};
var p = {};
function func () {
  switch (this) {
    case o:
      console.log('o');
      break;
    case p:
      console.log('p');
      break;
    case window:
      console.log('window');
      break;
  }
}

func(); // 같은 함수를 이렇게 호출하면, this는 window이다
func.apply(p); // 〃 this는 window 대신 p가 된다
func.apply(o); // 〃 this는 window 대신 o가 된다

3) 상속

생활코딩 2014 상속 강의, [TIL] 210918 프로토타입 체인 설명 참고

// [ Person 생성자 함수 ]
function Person (name) {
  this.name = name;
}

// Person이라는 생성자 함수 즉, '객체'에는
// prototype이라는 프로퍼티가 있는데 여기에는 어떤 '객체'가 들어 있다
// 그 객체에 name과 introduce를 설정해 값을 주었다
Person.prototype.name = null;
Person.prototype.introduce = function () {
  return 'my name is' + this.name;
}

var person = new Person('syong');
console.log(person.introduce()); // my name is syong



// [ Programmer 생성자 함수 ]
function Programmer (name) {
  this.name = name;
}

Programmer.prototype = new Person();

var p1 = new Programmer('syong');
console.log(p1.introduce()); // my name is syong
  • Programmer 생성자 안에는 introduce() 메서드가 정의되어 있지 않다. 그런데 Programmer 생성자를 통해 만든 pl 객체에서 introduce() 메서드를 사용할 수 있는 이유는, Programmer 생성자 함수가 Person 생성자 함수를 통해 만들어진 객체를 상속하기 때문이다.

  • Programmer 생성자 함수가 가지고 있는 프로퍼티 중에, prototype이라는 특수한 프로퍼티의 값으로, new Person()을 지정해 주었다. 즉, Person 생성자 함수를 통해 만든 객체를 지정해준 것이다.

  • Person 생성자 함수를 통해 객체를 생성할 때, 자바스크립트는 Person 생성자 함수가 가지고 있는 prototype이라는 특수한 프로퍼티 안에 들어 있는 객체와 똑같은 객체를 만든다. ꡸ 객체는 name 속성과 introduce() 메서드를 가진다. (name 속성은 Person 생성자 함수에 의해 값을 가지게 된다.)

💡 결론

Programmer.prototype = new Person();

어떠한 객체를 상속받고 싶다면, 그 객체를 다른 생성자 함수의 prototype에 할당하면 된다.

4) 다양성

// [ Person 생성자 함수 ]
function Person (name) {
  this.name = name;
}

Person.prototype.name = null;
Person.prototype.introduce = function () {
  return 'my name is' + this.name;
}



// [ Programmer 생성자 함수 ]
function Programmer (name) {
  this.name = name;
}

Programmer.prototype = new Person();
Programmer.prototype.coding = function () {
  return 'hello';
}



// [ Designer 생성자 함수 ]
function Designer (name) {
  this.name = name;
}

Designer.prototype = new Person();
Designer.prototype.design = function () {
  return 'beautiful';
}



var p1 = new Programmer('syong');
console.log(p1.introduce()); // my name is syong
console.log(p1.coding()); // hello

var p2 = new Designer('mong');
console.log(p2.introduce()); // my name is mong
console.log(p2.design()); // beatiful
profile
능동적으로 살자, 행복하게😁

0개의 댓글