JS class - 'this' 在承诺中未定义

JS class - 'this' is undefined in promise

有一个 Class 里面如果这个 class 我正在尝试填充一个数组 winch 定义在 'constructor'.

 class ClassA {

   constructor(){
      ...
      this.place = [];
   }

   fillUp() {
      fetch(path)
        .then(function(response) {
          return response.json();
        }).then(function(result) {

         this.place.push({"result":result})
        })
    }
 }
inst = new ClassA();   
inst.fillUp();

结果我得到了这个错误:类型错误:无法读取未定义的 属性 'place'。 问题出在哪里?

this 在 javascript 中很奇怪。根据对对象调用 code/function 的方式,它可能 return 值不是您所期望的。如果您使用的是现代 javascript,则应使用短箭头表示法。这将保留 this 绑定的内容。否则,您必须将 .bind(this) 添加到您引用 this:

的函数中
fetch(path)
    .then((response)=>{
        return response.json();
    }).then((result)=>{
        this.place.push({"result":result})
    })

使用箭头函数。

 class ClassA {

   constructor(){
      ...
      this.place = [];
   }

   fillUp = () => {
      fetch(path)
        .then(function(response) {
          return response.json();
        }).then(function(result) {

         this.place.push({"result":result})
        })
    }
 }
inst = new ClassA();   
inst.fillUp();

承诺处理程序是具有不同 this 值的不同函数。

要使 this 内部相等,您可以使用箭头函数,它从定义它们的地方继承 this

class ClassA {

   constructor(){
      ...
      this.place = [];
   }

   fillUp() {
      fetch(path)
        .then(response =>  response.json())
        .then(result => {
          this.place.push({"result":result})
        })
      }
    }
inst = new ClassA();   
inst.fillUp();

或者,.bind()函数:

class ClassA {

   constructor(){
      ...
      this.place = [];
   }

   fillUp() {
      fetch(path)
        .then(function(response) {
          response.json()
        })
        .then((function(result) {
          this.place.push({"result":result})
        }).bind(this))
      }
    }
inst = new ClassA();   
inst.fillUp();

您可以通过在尝试 push 到数组的回调中使用 arrow function expression 来解决您的问题。使用典型函数表达式的问题是它创建了自己的 this 关键字绑定。另一方面,箭头函数:

An arrow function does not have its own this. The this value of the enclosing lexical scope is used; arrow functions follow the normal variable lookup rules. So while searching for this which is not present in current scope, an arrow function ends up finding the this from its enclosing scope.

因此,如果您在回调中使用箭头函数,该函数将从它的封闭范围(即:ClassA 对象)中获取 this

这是它如何工作的演示:

const mockFetch = new Promise((resolve, reject) => {
  console.log('Fetching data..please wait..')
  setTimeout(() => resolve({
    json: () => '{ data: \'Some response data\'}'
  }), 1500)
});


class ClassA {
  constructor() {
    this.place = [];
  }

  fillUp() {
    mockFetch.then(function(response) {
      return response.json();
    }).then(result => {
      this.place.push({
        "result": result
      });
      console.log(this.place);
    })
  }
}

inst = new ClassA();
inst.fillUp();

.then((result) => {
 this.place.push({"result":result})
})

效果很好。比你!