【问题标题】:Cannot read given property of undefined无法读取未定义的给定属性
【发布时间】:2018-06-21 15:51:16
【问题描述】:

我正在调用 this.getAllJobsAPI();在渲染函数中。

这成功调用了 getAllJobsAPI(如下所示),我能够从 JSON 作业数组中检索作业名称。

getAllJobsAPI(){
var headers = new Headers();
headers.append('Authorization', 'Basic YWRtaW46YWRtaW4=');

fetch('http://localhost:8080/api/json', {headers: headers})
.then((result) => {
  // Get the result
  // If we want text, call result.text()
  return result.json();
}).then((jsonResult) => {
  // get all jobs 
  var jobs = [];

  Object.keys(jsonResult.jobs).forEach(function(key) {
    jobs.push(jsonResult.jobs[key].name);

    var job = jsonResult.jobs[key].name;
    console.log(job);

    this.getLastBuildAPI(job);   

});

//var a = 'meetup';
//this.getLastBuildAPI(a);
console.log(jsonResult);

})
}

但是调用 this.getLastBuildAPI(job);在 for each 循环中抛出“Uncaught (in promise) TypeError: Cannot read property 'getLastBuildAPI' of undefined”错误。但是如果我在函数末尾硬编码一个名称变量并调用 this.getLastBuildAPI(a);我可以得到成功响应。

谁能告诉我为什么我不能调用 this.getLastBuildAPI(job);在每个 JSON 数组中?请注意,我可以在控制台中看到作业变量。

谢谢,

【问题讨论】:

    标签: javascript json reactjs typescript typeerror


    【解决方案1】:

    因为解析回调中的thisundefined(因为它是不同的上下文),而当它在回调之外时,this 是您期望的对象。您可以先引用this var 存储它。

    getAllJobsAPI(){
    var headers = new Headers();
    headers.append('Authorization', 'Basic YWRtaW46YWRtaW4=');
    var self = this;
    
    fetch('http://localhost:8080/api/json', {headers: headers})
    .then((result) => {
      // Get the result
      // If we want text, call result.text()
      return result.json();
    }).then((jsonResult) => {
      // get all jobs 
      var jobs = [];
    
      Object.keys(jsonResult.jobs).forEach(function(key) {
        jobs.push(jsonResult.jobs[key].name);
    
        var job = jsonResult.jobs[key].name;
        console.log(job);
    
        self.getLastBuildAPI(job);   
    
    });
    
    //var a = 'meetup';
    //this.getLastBuildAPI(a);
    console.log(jsonResult);
    
    })
    

    您还可以应用其他方法。

    1。使用bind 方法。

    bind() 方法创建一个新函数,在调用该函数时,该函数具有 此关键字设置为提供的值,具有给定的序列 调用新函数时提供的任何参数之前的参数。

    Object.keys(jsonResult.jobs).forEach(function(key) {
        jobs.push(jsonResult.jobs[key].name);
        var job = jsonResult.jobs[key].name;
        console.log(job);
        this.getLastBuildAPI(job);   
    }.bind(this));
    

    2。使用arrow 函数。

    直到arrow 函数,每个new 函数都定义了自己的this 值。

    例如,this 在构造函数的情况下可以是一个新对象。

    function Person(age){
      this.age=age;
      console.log(this);
    }
    let person=new Person(22);

    如果创建的函数可以像obj.getAge() 一样访问,则this 可以指向base 对象。

    let obj={
      getAge:function(){
        console.log(this);
        return 22;
      }
    }
    console.log(obj.getAge());

    arrow 函数不会创建自己的this,它只是使用enclosing 执行contextthis 值。另一方面,arrow 函数使用父作用域的this

    Object.keys(jsonResult.jobs).forEach((key) => {
    jobs.push(jsonResult.jobs[key].name);
       var job = jsonResult.jobs[key].name;
       console.log(job);
       this.getLastBuildAPI(job);   
    });
    

    【讨论】:

    • 我用更多方法更新了答案,以便对其他人更有用
    【解决方案2】:

    您已将普通的 function 传递给 forEach,这改变了上下文。如果您想保留上下文,请使用箭头函数,或者,您可以创建一个新变量来保留对 this 的引用。

    使用箭头函数:

    Object.keys(jsonResult.jobs).forEach(key => {
        .....
        this.getLastBuildAPI(job); 
    });
    

    保留对this的引用:

    var that = this;
    Object.keys(jsonResult.jobs).forEach(function(key) {
         ....
        that.getLastBuildAPI(job); 
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-04-06
      • 2020-11-29
      • 2020-10-30
      • 2019-10-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多