[javascript] ‘this’는 JavaScript 클래스 메서드에서 정의되지 않았습니다.

저는 JavaScript를 처음 사용합니다. 내가 실제로 한 모든 것은 기존 코드를 수정하고 약간의 jQuery를 작성한 것입니다.

이제 속성과 메서드가있는 “클래스”를 작성하려고하지만 메서드에 문제가 있습니다. 내 코드 :

function Request(destination, stay_open) {
    this.state = "ready";
    this.xhr = null;
    this.destination = destination;
    this.stay_open = stay_open;

    this.open = function(data) {
        this.xhr = $.ajax({
            url: destination,
            success: this.handle_response,
            error: this.handle_failure,
            timeout: 100000000,
            data: data,
            dataType: 'json',
        });
    };

    /* snip... */

}

Request.prototype.start = function() {
    if( this.stay_open == true ) {
        this.open({msg: 'listen'});
    } else {

    }
};
//all console.log's omitted

문제는에,이다 Request.prototype.start, this정의되어 있지 않습니다 따라서 문 평가되면 false로. 내가 여기서 뭘 잘못하고 있니?



답변

시작 기능을 어떻게 호출하고 있습니까?

이것은 작동합니다 ( 새로운 것이 핵심입니다)

var o = new Request(destination, stay_open);
o.start();

직접처럼 호출 할 경우 Request.prototype.start(), this(글로벌 컨텍스트를 참조합니다 window브라우저에서).

또한 this정의되지 않은 경우 오류가 발생합니다. if 표현식은 false로 평가되지 않습니다.

업데이트 : this객체가 선언에 따라 설정되지 않고 호출에 의해 설정 됩니다 . 의미하는 바는 함수 속성을 같은 변수에 할당 x = o.start하고 호출 x()하면 this내부 시작이 더 이상 참조하지 않는다는 것 o입니다. 이것은 당신이 할 때 일어나는 일 setTimeout입니다. 작동하려면 대신 다음을 수행하십시오.

 var o = new Request(...);
 setTimeout(function() { o.start(); }, 1000);


답변

함수가 고차 함수 (인수로 전달됨)로 사용 된 후 범위 this가 손실 되었기 때문에 때때로이 오류가 발생한다는 점을 지적하고 싶었 습니다. 이러한 경우 이러한 함수를 this. 예

this.myFunction.bind(this);


답변

자바 스크립트의 OOP는 약간 펑키하고 (또는 많이) 익숙해지는 데 약간의 시간이 걸립니다. 가장 먼저 명심해야 할 것은 수업이 없으며 수업 측면에서 생각하면 당신을 괴롭힐 수 있다는 것입니다. 생성자 (클래스 정의에 해당하는 JavaScript)에 연결된 메서드를 사용하려면 개체를 인스턴스화해야합니다. 예를 들면 :

Ninja = function (name) {
    this.name = name;
};
aNinja = new Ninja('foxy');
aNinja.name; //-> 'foxy'

enemyNinja = new Ninja('boggis');
enemyNinja.name; //=> 'boggis'

참고 Ninja인스턴스가 같은 특성을 가지고 있지만 aNinja의 속성에 액세스 할 수 없습니다 enemyNinja. (이 부분은 정말 쉽고 간단해야합니다.)에 항목을 추가하기 시작하면 상황이 약간 달라집니다 prototype.

Ninja.prototype.jump = function () {
   return this.name + ' jumped!';
};
Ninja.prototype.jump(); //-> Error.
aNinja.jump(); //-> 'foxy jumped!'
enemyNinja.jump(); //-> 'boggis jumped!'

this생성자가 인스턴스화 될 때 (그렇지 않으면 window브라우저에서 전역 개체를 가리킴) 올바른 객체 ( “클래스”) 만 가리 키기 때문에 이것을 직접 호출하면 오류가 발생 합니다.


답변

ES2015에서 일명 ES6 classfunctions.

컨텍스트를 강제로 설정 this하려면 bind()메소드 를 사용할 수 있습니다 . @chetan이 지적했듯이 호출시 컨텍스트도 설정할 수 있습니다! 아래 예를 확인하십시오.

class Form extends React.Component {
constructor() {
    super();
  }
  handleChange(e) {
    switch (e.target.id) {
      case 'owner':
        this.setState({owner: e.target.value});
        break;
      default:
    }
  }
  render() {
    return (
      <form onSubmit={this.handleNewCodeBlock}>
        <p>Owner:</p> <input onChange={this.handleChange.bind(this)} />
      </form>
    );
  }
}

여기서 우리는 내부 컨텍스트 handleChange()Form.


답변

이 질문에 대한 답변이 있었지만 다른 사람이 여기에 올 수도 있습니다.

또한 this클래스를 초기화 할 때 어리석게도 클래스의 메서드를 구조화하려고 할 때 정의되지 않은 문제가있었습니다 .

import MyClass from "./myClass"

// 'this' is not defined here:
const { aMethod } = new MyClass()
aMethod() // error: 'this' is not defined

// So instead, init as you would normally:
const myClass = new MyClass()
myClass.aMethod() // OK


답변

화살표 기능 사용 :

Request.prototype.start = () => {
    if( this.stay_open == true ) {
        this.open({msg: 'listen'});
    } else {

    }
};


답변