1. bind 함수를 이용해서 수동적으로 binding
function Cat(name) {
    this.name = name;
    this.printName = function() {
        console.log(`고양이의 이름을 출력한다옹 : ${this.name}`);
    };
    // 1. bind 함수를 이용해서 수동적으로 binding
    this.printName = this.printName.bind(this);
}

function Dog(name) {
    this.name = name;
    this.printName = function () {
        console.log(`강아지이의 이름을 출력한다옹 : ${this.name}`);
    };
}

const cat = new Cat('냐옹');
const dog = new Dog('멍멍');
cat.printName(); // bind 함수를 이용해서 수동적으로 binding
dog.printName(); // 강아지이의 이름을 출력한다옹 : 멍멍

dog.printName = cat.printName;
dog.printName(); // 고양이의 이름을 출력한다옹 : 냐옹

function printOnMonitor(printName) {
    console.log('모니터를 준비하고, 전달된 콜백을 실행!');
    printName();
}

printOnMonitor(cat.printName); // 고양이의 이름을 출력한다옹 : 냐옹
  1. arrow 함수를 사용 : arrow 함수는 렉시컬 환경에서의 this를 기억함
unction Cat(name) {
    this.name = name;
    // 2. arrow 함수를 사용 : arrow 함수는 렉시컬 환경에서의 this를 기억함
    this.printName = () => {
        console.log(`고양이의 이름을 출력한다옹 : ${this.name}`);
    };
  
}

function Dog(name) {
    this.name = name;
    this.printName = function () {
        console.log(`강아지이의 이름을 출력한다옹 : ${this.name}`);
    };
}

const cat = new Cat('냐옹');
const dog = new Dog('멍멍');
cat.printName(); // bind 함수를 이용해서 수동적으로 binding
dog.printName(); // 강아지이의 이름을 출력한다옹 : 멍멍

dog.printName = cat.printName;
dog.printName(); // 고양이의 이름을 출력한다옹 : 냐옹

function printOnMonitor(printName) {
    console.log('모니터를 준비하고, 전달된 콜백을 실행!');
    printName();
}

printOnMonitor(cat.printName); // 고양이의 이름을 출력한다옹 : 냐옹