분류 javascript

6 장. 자바 스크립트에서 This

컨텐츠 정보

  • 조회 229 (작성일 )

본문

"this"을 이해하기 


JavaScript에서 this 키워드는 초보자에게는 두꺼운 미스터리이며 더 많은 경험 개발자에게는 끊임없는 요점입니다. 실제로 this는 명백한 이유 없이 코드 실행 중에 변경 될 수 있는 움직이는 대상입니다. 그러나 this 키워드가 다른 프로그래밍 언어에서 어떻게 보이는지 잠시 살펴 보겠습니다. 먼저 JavaScript 클래스가 있습니다.


https://github.com/valentinogagliardi/Little-JavaScript-Book/blob/v1.0.0/manuscript/chapter6.md 


class Person {
  constructor(name) {
    this.name = name;
  }

  greet() {
    console.log("Hello " + this.name);
  }
}


5 장에서 JavaScript에는 클래스가 없지만 this는 클래스 자체에 대한 참조처럼 보입니다. 또한 파이썬 클래스에는 self라는 병렬이 있는 것 같습니다.


class Person:
    def __init__(self, name):
        self.name = name
    
    def greet(self):
        return 'Hello' + self.name


Python 클래스에서 self는 클래스의 인스턴스를 나타냅니다. 즉, 클래스에서 시작하여 생성되는 새 객체입니다.


me = Person('Valentino')


PHP에도 비슷한 것이 있습니다.


class Person {
    public $name; 

    public function __construct($name){
        $this->name = $name;
    }

    public function greet(){
        echo 'Hello ' . $this->name;
    }
}


여기서 $this는 실제 클래스 인스턴스입니다. 두 개의 새 객체를 생성하기 위해 JavaScript 클래스를 다시 가져 오면 object.name을 호출 할 때마다 올바른 문자열이 다시 표시됩니다.


class Person {
  constructor(name) {
    this.name = name;
  }

  greet() {
    console.log("Hello " + this.name);
  }
}

const me = new Person("Valentino");
console.log(me.name); // 'Valentino'

const you = new Person("Tom");
console.log(you.name); // 'Tom'


말이 되는 것 같습니다. JavaScript는 Python, Java, PHP와 비슷하며 실제 클래스 인스턴스를 가리키는 것으로 보입니까? 실제로는 아닙니다. JavaScript는 객체 지향 언어가 아니며 실제로 허용적이고 역동적이며 실제 클래스가 없다는 것을 잊지 마십시오. this는 클래스와 관련이 없으며 간단한 JavaScript 함수로 브라우저의 요점을 증명할 수 있습니다.


function whoIsThis() {
  console.log(this);
}

whoIsThis();


출력은 무엇입니까? 스포일러 : JavaScript 함수가 소위 전역 컨텍스트에서 실행될 때 이것은 전역에 대한 참조가 됩니다. 그리고 브라우저에서 실행할 때 전역은 창을 가리킵니다. 보시다시피 JavaScript 함수에는 항상 일부 컨텍스트 객체에 대한 링크가 있습니다. 이는 함수가 실행중인 객체입니다. 링크는 고정되어 있지 않습니다 : 우연히 변경되거나 의도적으로 변경 될 수 있습니다. 그러나 안심해야 할 점은 this가 어디를 가리켜야 하는지를 결정하는 규칙이 여전히 있다는 것입니다. 그들을 분해하자.


규칙 번호 1 : 전역 "this"(일명 기본 바인딩)로 폴백 


브라우저에서 다음 코드를 실행하는 경우 :


function whoIsThis() {
  console.log(this);
}

whoIsThis();


다음과 같은 결과가 나타납니다.


Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}


놀라운? 우리는 class에 참여하지 않으며 this는 여전히 있습니다. this는 항상 일반 함수에 존재하며 함수 호출 방식에 따라 많은 형태를 취할 수 있기 때문입니다. 전역 환경에서 함수가 호출되면 항상 전역 객체인 창(window)을 가리킵니다. 이것이 JavaScript의 규칙 번호 1이며 기본 바인딩이라고 합니다. 기본 바인딩은 대체와 비슷하며 대부분의 경우 바람직하지 않습니다. 전역 환경에서 실행되는 모든 함수는 전역 변수를 "폴링"하여 코드에 혼란을 줄 수 있습니다. 다음 예를 고려하십시오.


function firstDev() {
  window.globalSum = function(a, b) {
    return a + b;
  };
}

function nastyDev() {
  window.globalSum = null;
}

firstDev();
nastyDev();
var result = firstDev();
console.log(result);

// Output: undefined


첫 번째 개발자는 globalSum이라는 전역 변수를 만들고 여기에 함수를 할당합니다. 나중에 다른 개발자는 동일한 변수에 null을 할당하여 코드에서 오작동을 일으킵니다. 전역 변수를 사용하는 것은 항상 위험하므로 이러한 이유로 JavaScript는 몇 년 전에 "안전 모드": 엄격 모드를 얻었습니다. "엄격한 사용"을 설정하면 엄격한 모드가 활성화됩니다. 모든 JavaScript 파일의 상단에 있습니다. 엄격 모드에는 많은 긍정적인 효과가 있으며 그 중 하나는 기본 바인딩의 중화입니다. 엄격 모드에서는 전역 컨텍스트에서 액세스하려고 할 때 정의되지 않습니다.


"use strict";

function whoIsThis() {
  console.log(this);
}

whoIsThis();

// Output: undefined


엄격 모드는 JavaScript 코드를 보다 안전하고 (거의) 이와 같은 바보 같은 버그로부터 무료로 만듭니다. 요약하자면 기본 바인딩은 JavaScript에서 이 규칙의 첫 번째 규칙입니다. 엔진이 this가 무엇인지 파악할 수 없는 경우 전역 객체로 돌아갑니다. 그러나 이것에 대한 3 가지 다른 규칙이 있기 때문에 그것은 이야기의 절반에 불과합니다. 그들을 함께 보자.


규칙 번호 2 : "this"가 내 호스트 객체인 경우 (일명 암시적 바인딩) 


"암시적 바인딩"은 위협적인 용어이지만 그 뒤에 숨겨진 이론은 그렇게 복잡하지 않습니다. 그것은 모두 사물로 좁혀집니다. JavaScript 객체가 함수를 포함 할 수 있다는 것은 놀라운 일이 아닙니다.


var widget = {
  items: ["a", "b", "c"],
  printItems: function() {
    console.log(this.items);
  }
};


함수가 객체의 속성으로 할당되면 해당 객체는 함수가 실행되는 "홈"이 됩니다. 즉, 함수 내부의 this 키워드는 해당 객체를 자동으로 가리킵니다. 이것은 JavaScript에서 규칙 2번이며 암시적 바인딩의 이름으로 사용됩니다. 전역 컨텍스트에서 함수를 호출 할 때도 암시적 바인딩이 작동합니다.


function whoIsThis() {
  console.log(this);
}

whoIsThis();


코드에서 알 수는 없지만 JavaScript 엔진은 전역 객체 창의 새 속성에 함수를 할당합니다. 후드 아래는 다음과 같습니다.


window.whoIsThis = function() {
  console.log(this);
};


가정을 쉽게 확인할 수 있습니다. 브라우저에서 다음 코드를 실행하십시오.


function whoIsThis() {
  console.log(this);
}

console.log(typeof window.whoIsThis)


"함수"로 돌아갑니다. 그리고 이 시점에서 당신은 묻습니다 : 전역 함수 내에서 this의 실제 규칙은 무엇입니까? 기본 바인딩이라고 하지만 실제로는 암시적 바인딩과 비슷합니다. 혼란스러운가요? 결국 JavaScript입니다! 컨텍스트에 대한 의문이 있을 때 JavaScript 엔진은 항상 전역으로 폴백한다는 사실을 기억하십시오 (기본 바인딩). 반면에 함수가 JavaScript 객체 내에 정의되고 해당 객체의 일부로 호출되면 다른 방법은 없습니다 : this는 호스트 객체 (암시적 바인딩)를 나타냅니다. 이제 JavaScript에서 세 번째 규칙을 보도록 하겠습니다.


규칙 번호 3 : "this"(일명 명시적 바인딩)가 어떻습니까? 


경력의 어느 시점에서 다음과 같은 코드를 보지 못한 JavaScript 개발자는 없습니다.


someObject.call(anotherObject);
Someobject.prototype.someMethod.apply(someOtherObject);


그것은 명백한 바인딩 행동입니다. 바인딩의 또 다른 예 : React가 선택한 UI 라이브러리로 부상하면서 클래스 메소드가 클래스 자체에 "바운드"되어있는 것이 일반적입니다.


class Button extends React.Component {
  constructor(props) {
    super(props);
    this.state = { text: "" };
    // bounded method
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    this.setState(() => {
      return { text: "PROCEED TO CHECKOUT" };
    });
  }

  render() {
    return (
      <button onClick={this.handleClick}>
        {this.state.text || this.props.text}
      </button>
    );
  }
}


요즘 React 후크는 클래스를 거의 불필요하게 만들지만 ES2015 클래스를 사용하는 "레거시"React 구성 요소가 많이 있습니다. 대부분의 초보자가 묻는 질문 중 하나는 React의 이벤트 핸들러 메소드를 "바인드"로 리바인드 하는 이유입니다. call, apply, bind의 세 가지 메소드는 Function.prototype에 속하며 소위 명시적 바인딩 (규칙 번호 3)에 사용됩니다. 명시적 바인딩은 함수를 가져 와서 컨텍스트 객체라고도 하는 홈을 사용자가 제공하는 것으로 강제합니다. 그러나 왜 명시적으로 함수를 바인딩 하거나 리바인드 해야 합니까? 몇 년 전에 가상의 JavaScript에 익숙하지 않은 동료가 작성한 일부 기존 JavaScript 코드를 고려하십시오.


var legacyWidget = {
  html: "",
  init: function() {
    this.html = document.createElement("div");
  },
  showModal: function(htmlElement) {
    var newElement = document.createElement(htmlElement);
    this.html.appendChild(newElement);
    window.document.body.appendChild(this.html);
  }
};


showModal은 legacyWidget 객체에 바인딩 된 "메소드"입니다. 모달이 새 요소를 추가해야 하는 HTML 요소 (this.html)를 변경할 방법이 없기 때문에 암시적으로 바인드 되어 (규칙 번호 2) 거의 쓸모가 없습니다. this.html은 메소드 내부에 하드 코딩 되어 있습니다. 걱정하지 마십시오. showModal이 실행되는 이 객체를 변경하기 위해 명시적 바인딩에 의존 할 수 있습니다. 새로운 컨텍스트 객체와 선택적 인수 목록을 취하는 호출 작업입니다. 이제 새로운 "shiny"위젯을 작성하고 시작점으로 다른 HTML 요소를 제공 할 수 있습니다.


var legacyWidget = {
  html: "",
  init: function() {
    this.html = document.createElement("div");
  },
  showModal: function(htmlElement) {
    var newElement = document.createElement(htmlElement);
    this.html.appendChild(newElement);
    window.document.body.appendChild(this.html);
  }
};

var shinyNewWidget = {
  html: "",
  init: function() {
    // A different HTML element
    this.html = document.createElement("section");
  }
};


이 시점에서 원래 메소드에서 호출을 실행할 수 있습니다.


var legacyWidget = {
  html: "",
  init: function() {
    this.html = document.createElement("div");
  },
  showModal: function(htmlElement) {
    var newElement = document.createElement(htmlElement);
    this.html.appendChild(newElement);
    window.document.body.appendChild(this.html);
  }
};

var shinyNewWidget = {
  html: "",
  init: function() {
    this.html = document.createElement("section");
  }
};

// Initialize the new widget with a different HTML element
shinyNewWidget.init();

// Run the original method with a new context object
legacyWidget.showModal.call(shinyNewWidget, "p");


명시적 바인딩에 대해 여전히 혼란스러우면 코드 재사용을 위한 기본 스타일과 같이 생각하십시오. 해킹과 버그가 있는 것처럼 보이지만 리팩토링 할 기존 JavaScript 코드가 있는 경우 최선을 다합니다. 또한 프로토 타입 시스템은 위의 코드를 구성하는 데 더 적합한 후보이지만 오늘날에도 프로덕션에 여전히 나쁜 소프트웨어가 있다고 생각합니다. 이 시점에서 적용 및 바인딩이 무엇인지 궁금 할 것입니다. apply는 매개 변수가 목록으로 제공 될 것으로 예상하는 반면, 전자는 매개 변수의 배열을 허용한다는 점을 제외하고는 호출 사용과 동일한 효과를 갖습니다. 다시 말해, call은 매개 변수 목록으로 작동합니다.


var obj = {
  version: "0.0.1",
  printParams: function(param1, param2, param3) {
    console.log(this.version, param1, param2, param3);
  }
};

var newObj = {
  version: "0.0.2"
};

obj.printParams.call(newObj, "aa", "bb", "cc");


apply는 일련의 매개 변수를 예상하지만 :


var obj = {
  version: "0.0.1",
  printParams: function(param1, param2, param3) {
    console.log(this.version, param1, param2, param3);
  }
};

var newObj = {
  version: "0.0.2"
};

obj.printParams.apply(newObj, ["aa", "bb", "cc"]);


그리고 bind는 어떻습니까? 이것이 함수를 바인딩 하는 가장 강력한 방법입니다. bind는 여전히 주어진 함수에 대해 새로운 컨텍스트 객체를 취하지 만 새로운 컨텍스트 객체로 함수를 호출하는 것은 아닙니다. 해당 객체에 영구적으로 바인딩 된 새 함수를 반환합니다.


var obj = {
  version: "0.0.1",
  printParams: function(param1, param2, param3) {
    console.log(this.version, param1, param2, param3);
  }
};

var newObj = {
  version: "0.0.2"
};

var newFunc = obj.printParams.bind(newObj);

newFunc("aa", "bb", "cc");


bind의 일반적인 사용 사례는 원래 함수의 영구적인 리바인드입니다.


var obj = {
  version: "0.0.1",
  printParams: function(param1, param2, param3) {
    console.log(this.version, param1, param2, param3);
  }
};

var newObj = {
  version: "0.0.2"
};

obj.printParams = obj.printParams.bind(newObj);

obj.printParams("aa", "bb", "cc");


이제부터 obj.printParams는 항상 newObj를 함수가 실행 중인 객체로 참조합니다. 이 시점에서 우리가 React에서 클래스 메소드를 바인드로 리바인드 하는 이유가 분명해야 합니다.


class Button extends React.Component {
  constructor(props) {
    super(props);
    this.state = { text: "" };
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    this.setState(() => {
      return { text: "PROCEED TO CHECKOUT" };
    });
  }

  render() {
    return (
      <button onClick={this.handleClick}>
        {this.state.text || this.props.text}
      </button>
    );
  }
}


그러나 현실은 더 미묘한 차이가 있으며 "손실 된 바인딩"과 관련이 있습니다. 이벤트 핸들러를 React 요소에 대한 소품으로 할당하면 메소드가 함수가 아닌 참조로 전달됩니다. "vanilla"JavaScript로 말하면 다른 콜백 내에 이벤트 핸들러 참조를 전달하는 것과 같습니다.


// BINDING LOST!
    const handleClick = this.handleClick;
    //
    element.addEventListener("click", function() {
      handleClick();
    });


할당 작업이 바인딩을 중단합니다. 위의 예제 구성 요소에서 handleClick (버튼 요소에 할당) 메소드는 this.setState()를 호출하여 구성 요소의 상태를 업데이트하려고 합니다. 호출되면 메소드는 이미 더 이상 클래스 자체가 아닌 바인딩을 잃어 버렸습니다. 이제 컨텍스트 오브젝트는 창 글로벌 오브젝트입니다. 이 시점에서 "TypeError : undefined의 'setState'속성을 읽을 수 없습니다."라는 두려움이 나타납니다. React 구성 요소는 대부분 ES2015 모듈로 내보내지는 시간입니다. ES 모듈은 기본적으로 엄격 모드를 사용하므로 기본 바인딩을 비활성화하므로 정의되지 않습니다. 엄격한 모드는 ES2015 클래스에서도 활성화되며 구성 요소를 ES 모듈로 내 보내지 않아도 정의되지 않습니다. React 컴포넌트를 모방한 간단한 클래스로 직접 테스트 할 수 있습니다. click 이벤트에 대한 응답으로 handleClick에 의해 호출 된 setState 메소드가 있습니다.


class ExampleComponent {
  constructor() {
    this.state = { text: "" };
  }

  handleClick() {
    this.setState({ text: "New text" });
    alert(`New state is ${this.state.text}`);
  }

  setState(newState) {
    this.state = newState;
  }

  render() {
    const element = document.createElement("button");
    document.body.appendChild(element);
    const text = document.createTextNode("Click me");
    element.appendChild(text);

    const handleClick = this.handleClick;

    element.addEventListener("click", function() {
      handleClick();
    });
  }
}

const component = new ExampleComponent();
component.render();


문제가 되는 코드는 다음과 같습니다.


const handleClick = this.handleClick;


클래스를 HTML 파일에 포함 시키십시오.


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Loosing the binding</title>
</head>
<body>

</body>
<script src="this.js"></script>
</html>


버튼을 클릭하십시오. 콘솔을 확인하면 "TypeError : 정의되지 않은 'setState'속성을 읽을 수 없습니다"가 표시됩니다. 이 문제를 해결하기 위해 클래스 자체를 올바른 컨텍스트에 고정 시키기 위해 bind를 사용할 수 있습니다.


constructor() {
    this.state = { text: "" };
    this.handleClick = this.handleClick.bind(this);
  }


버튼을 다시 클릭하면 예상대로 경고가 표시됩니다. 명시 적 바인딩은 암시 적 바인딩과 기본 바인딩보다 강력합니다. apply, call 및 bind를 사용하면 함수에 동적 컨텍스트 객체를 제공하여 원하는 대로 이를 구부릴 수 있습니다. "컨텍스트 객체"가 여전히 추상적이라면 JavaScript 함수가 실행되는 상자라고 생각하면 됩니다. 상자는 항상 존재하지만 명시 적 바인드로 언제든지 좌표를 변경할 수 있습니다.


규칙 번호 4 : "신규" 바인딩 


5 장에서는 JavaScript에서 새 객체를 만드는 행위를 캡슐화 하는 데 도움이 되는 생성자 함수 패턴을 보았습니다.


function Person(name, age) {
  this.name = name;
  this.age = age;
}

Person.prototype.greet = function() {
  console.log("Hello " + this.name);
};

var me = new Person("Valentino");
me.greet();

// Output: "Hello Valentino"



여기서는 "Person"이라는 엔터티에 대한 청사진을 만듭니다. 그 청사진이 주어지면 "새"호출로 Person을 "구성"하여 Person 유형의 새 개체를 만들 수 있습니다.


var me = new Person("Valentino");


JavaScript에서 이것을 구부리는 방법에는 여러 가지가 있지만 생성자 함수에서 new를 사용할 때 엔진은 의심의 여지가 없습니다. 항상 새로 만든 객체를 가리킵니다. 다음과 같이 생성자 함수의 프로토 타입에 정의 된 함수 :


Person.prototype.greet = function() {
  console.log("Hello " + this.name);
};


대부분의 경우 새로 호스트 개체에서 작동하므로 항상 "이 사람"을 알 수 있습니다. 다음 예제에서 greet이 나에게 호출됩니다.


var me = new Person("Valentino");
me.greet();

// Output: "Hello Valentino"


내가 생성자 호출을 통해 구성되었으므로 이것의 의미에 대해 모호하지 않습니다. 물론 Person으로부터 인사를 빌려 다른 대상에 대해 실행할 수 있습니다.


Person.prototype.greet.apply({ name: "Tom" });

// Output: "Hello Tom"


JavaScript에서 이것을 볼 수 있듯이 유연성이 뛰어나지만 이 규칙을 알지 못하면 교육 받은 추측을 할 수 없으며 진정한 힘을 이용할 수 없습니다. 간단히 말해 이것은 4 가지 "단순한"규칙을 기반으로 하지만 ES 2015 화살표 기능을 사용하면 실제로 물릴 때 약간 "속임수"를 사용할 수 있습니다. 방법을 보자.


화살표 함수와 "this" 


2 장 ECMAScript 2015에서 볼 수 있듯이 화살표 함수가 도입되었습니다. 화살표 함수의 구문은 편리하고 간결하지만 다시 한 번 강조하지 않는 것이 좋습니다. 그러나 화살표 함수에는 많은 흥미로운 기능이 있습니다. 먼저 Post라는 생성자 함수를 고려하십시오. 생성자에서 새 객체를 생성하자마자 REST API에 대한 Fetch 요청이 있습니다.


"use strict";

function Post(id) {
  this.data = [];

  fetch("https://jsonplaceholder.typicode.com/posts/" + id)
    .then(function(response) {
      return response.json();
    })
    .then(function(json) {
      this.data = json;
    });
}

var post1 = new Post(3);


위의 코드는 엄격 모드이므로 기본 바인딩 (전역으로 돌아가는)은 금지되어 있습니다. 브라우저에서 코드를 실행하면 "TypeError : undefined의 'data'속성을 : 11 : 17에 설정할 수 없습니다" 라는 메시지가 표시됩니다. 정의되지 않은 속성 데이터를 설정할 수 없습니다! 맞는 말입니다. 전역 모드는 엄격 모드에서 정의되지 않습니다 ... 잠시만 기다리십시오. 왜 함수가 post1.data 대신 window.data를 업데이트 하려고 합니까? 그 이유는 간단합니다. Fetch에 의해 트리거 되는 콜백은 브라우저 내에서 실행되므로 this가 window를 가리킵니다. 무서운. 이 문제를 해결하기 위해 우리는 오래된 속임수인 "그것"을 가졌습니다. 다른 말로, 당신은 그것이라는 변수에 this에 대한 참조를 저장할 수 있지만 이번에는 콜백 함수 외부에 있습니다 :


"use strict";

function Post(id) {
  var that = this;
  this.data = [];

  fetch("https://jsonplaceholder.typicode.com/posts/" + id)
    .then(function(response) {
      return response.json();
    })
    .then(function(json) {
      that.data = json;
    });
}

var post1 = new Post(3);


지금 코드를 실행하면 post1.data에 예상대로 데이터가 표시됩니다.


console.log(post1.data.body);

// "et iusto sed quo iure
// voluptatem occaecati omnis eligendi aut ad
// voluptatem doloribus vel accusantium quis pariatur
// molestiae porro eius odio et labore et velit aut"


이 오래된 해키 트릭 대신 화살표 기능을 사용하지 않으면 어떻게 될까요? 실제로 가장 흥미로운 기능 중 하나는 이들이 this를 처리하는 방법입니다. 일반 함수 대신 화살표 함수를 콜백으로 사용할 수 있습니다.


"use strict";

function Post(id) {
  this.data = [];

  fetch("https://jsonplaceholder.typicode.com/posts/" + id)
    .then(response => {
      return response.json();
    })
    .then(json => {
      this.data = json;
    });
}

var post1 = new Post(3);


문제가 발생했습니다. 이제 this.data는 항상 post1을 가리킵니다. 왜 그래? 화살표 함수는 둘러싸는 환경을 가리킵니다 (공식 문서와 대부분의 자습서에서는 "어휘 범위"라고 함). 즉, 화살표 함수는 창 개체 내에서 실행 중인지 신경 쓰지 않습니다. 둘러싼 환경은 post1 객체이며 앞으로부터 계속 될 것입니다. 화살표 함수의 가장 흥미로운 사용 사례 중 하나입니다.


결론 


this가 JavaScript에서 무엇입니까? 글쎄요. 기본 바인딩, 암시적 바인딩, 명시적 바인딩 및 "새"바인딩이라는 4 가지 규칙을 기반으로 합니다. 암시 적 바인딩은 함수가 this을 참조하고 JavaScript 객체의 일부로 실행될 때 해당 "호스트"객체를 가리킬 것이라고 말합니다. 그러나 JavaScript 함수는 항상 개체 내에서 실행됩니다. 예를 들어 소위 전역 범위에 정의 된 전역 함수의 경우입니다.

브라우저에서 작업 할 때 전역 범위는 창이며 현재 브라우저의 탭입니다. 이 상황에서 전역으로 실행되는 모든 함수는 this를 창으로 볼 수 있습니다. 이것이 기본 바인딩입니다.

대부분의 경우 전역 범위와 상호 작용하여 JavaScript가 엄격한 모드로 기본 바인딩을 중화하는 방법을 제공하는 것은 바람직하지 않습니다.

엄격 모드에서는 전역 객체에 대한 참조가 정의되어 있지 않으므로 어리석은 실수로부터 효과적으로 보호 할 수 있습니다.

암시적 및 기본 바인딩 외에 "명시적 바인딩"도 있습니다. apply, call 및 bind의 세 가지 방법으로 자체적으로 this를  향하는데 사용됩니다.

이 메소드는 주어진 함수가 작동해야 하는 명시적 호스트 객체를 전달하는 데 유용합니다.

마지막으로 소위 생성 된 호출을 통해 객체가 "구성"될 때 조치를 취하는 "새"바인딩이 있습니다. 대부분의 개발자에게 this는 무서운 일이며 모든 비용을 피해야 합니다.

그러나 더 깊이 파고 싶은 사람들에게는 JavaScript 코드를 재사용 할 수 있는 강력하고 유연한 시스템입니다. 받아보세요!