programing

프라 미스를 사용할 때 클래스 메서드 내에서 'this'가 정의되지 않은 이유는 무엇입니까?

nasanasas 2020. 9. 14. 21:14
반응형

프라 미스를 사용할 때 클래스 메서드 내에서 'this'가 정의되지 않은 이유는 무엇입니까? [복제]


이 질문에 이미 답변이 있습니다.

나는 자바 스크립트 클래스를 가지고 있으며 각 메소드는 Q약속을 반환합니다 . this에서 정의되지 않은 이유를 알고 싶습니다 . 이 코드를 작성하는 더 정확한 방법이 있습니까?method2method3

function MyClass(opts){
  this.options = opts;

  return this.method1()
    .then(this.method2)
    .then(this.method3);
}

MyClass.prototype.method1 = function(){
  // ...q stuff...

  console.log(this.options); // logs "opts" object

  return deferred.promise;
};

MyClass.prototype.method2 = function(method1resolve){
  // ...q stuff...

  console.log(this); // logs undefined

  return deferred.promise;
};

MyClass.prototype.method3 = function(method2resolve){
  // ...q stuff...

  console.log(this); // logs undefined

  return deferred.promise;
};

다음을 사용하여이 문제를 해결할 수 있습니다 bind.

function MyClass(opts){
  this.options = opts;

  return this.method1()
    .then(this.method2.bind(this))
    .then(this.method3.bind(this));
}

그러나 왜 bind필요한지 완전히 확실하지 않습니다 . 되어 .then()죽이는 this해제?


this항상 메서드가 호출되는 객체입니다. 그러나 메서드를에 전달할 때 then()호출하지 않습니다! 메서드는 어딘가에 저장되고 나중에 거기에서 호출됩니다. 을 보존 this하려면 다음과 같이해야합니다.

.then(() => this.method2())

or if you have to do it the pre-ES6 way, you need to preserve this before:

var that = this;
// ...
.then(function() { that.method2() })

Promise handlers are called in the context of the global object (window) by default. When in strict mode (use strict;), the context is undefined. This is what's happening to method2 and method3.

;(function(){
  'use strict'
  Promise.resolve('foo').then(function(){console.log(this)}); // undefined
}());

;(function(){
  Promise.resolve('foo').then(function(){console.log(this)}); // window
}());

For method1, you're calling method1 as this.method1(). This way of calling it calls it in the context of the this object which is your instance. That's why the context inside method1 is the instance.


Basically, you're passing it a function reference with no context reference. The this context is determined in a few ways:

  1. Implicitly. Calling a global function or a function without a binding assumes a global context.*
  2. By direct reference. If you call myObj.f() then myObj is going to be the this context.**
  3. Manual binding. This is your class of functions such as .bind and .apply. These you explicitly state what the this context is. These always take precedence over the previous two.

In your example, you're passing a function reference, so at it's invocation it's implied to be a global function or one without context. Using .bind resolves this by creating a new function where this is explicitly set.

*This is only true in non-strict mode. In strict mode, this is set to undefined.

**Assuming the function you're using hasn't been manually bound.


One way functions get their context (this) is from the object on which they are invoked (which is why method1 has the right context - it's invoked on this). You are passing a reference to the function itself to then. You can imagine that the implementation of then looks something like this:

function then( callback ) {

  // assume 'value' is the recently-fulfilled promise value
  callback(value);
}

In that example callback is a reference to your function. It doesn't have any context. As you've already noted you can get around that by binding the function to a context before you pass it to then.

참고URL : https://stackoverflow.com/questions/34930771/why-is-this-undefined-inside-class-method-when-using-promises

반응형