2016-12-31 1 views
0

Я изучаю this из MDN. Существует функция «петли»Как получить доступ к внешнему вызывающему абоненту в гнезде для каждого

function loop(){ 
    ctx.fillStyle='rgb(255,200,124,.35)'; 
    ctx.fillRect(0,0,width,height); 

    while(balls.length<15){ 
     var ball = new Ball(); 
     balls.push(ball); 
    } 

    balls.forEach(function(b){ 
     b.draw(); 
     b.update(); 
     b.collisionDetect(); 
    }); 

    requestAnimationFrame(loop); 
} 

balls является массивом, а в collisionDetect() есть другое использование forEach, как показано ниже. Я хочу, чтобы this в collisionDetect() обратитесь к вызывающему b в loop()

Ball.prototype.collisionDetect = function(){ 

    balls.forEach(function(bl){ 

     if(!(this.x===bl.x&&this.y==bl.y 
      &&this.velX===bl.velX&&this.velY===bl.velY)){ 
      var dx = this.x-bl.x; 
      var dy = this.y-bl.y; 
      var distance = Math.sqrt(dx*dx+dy*dy); 

      if(distance<this.size+bl.size){ 
       bl.color = this.color = "rbg(" 
       + random(0,255) 
       +"," 
       +random(0,255) 
       +"," 
       +random(0,255) 
       +")"; 
      } 
     } 
    }); 
} 

Я попытался прохождения b в качестве параметра collisionDetect(). Это работает, но не то, что ожидается.

Я знаю, что два forEach могут быть просто заменены оригинальной петлей for, но мне просто интересно, могу ли я сделать это с forEach.

Спасибо вам большое.

+0

В функции collisionDetect «это» равно Ь. Поэтому просто запишите его в переменной перед forEach и используйте эту переменную в функции, переданной для forEach. – Robba

+0

Я сомневаюсь в методах OO, используемых в этой статье, а именно 'collisionDetect'. Один экземпляр «Бал» не должен касаться произвольной переменной «шары» из охватывающей области. Тьфу. Это должен быть «метод класса» (в случае javascript - свойство функции конструктора) 'Ball.collisionDetect = function (ball, balls) {}' – Damon

+0

@Damon Возможно, автор хочет сделать код более понятным и понятным, потому что это учебник для абсолютного новичка :) –

ответ

2

Вы можете привязать локальную переменную к this.

Ball.prototype.collisionDetect = function(){ 
    var self = this; 
    balls.forEach(function(bl){ 

     if(!(self.x===bl.x&&self.y==bl.y 
      &&self.velX===bl.velX&&self.velY===bl.velY)){ 
      var dx = self.x-bl.x; 
      var dy = self.y-bl.y; 
      var distance = Math.sqrt(dx*dx+dy*dy); 

      if(distance<self.size+bl.size){ 
       bl.color = this.color = "rgb(" + random(0,255) +"," +random(0,255) +"," +random(0,255) +")"; 
      } 
     } 
    }); 
} 

Другой способ заключается в использовании функции стрелок ES6, потому что они сохраняют this.

Ball.prototype.collisionDetect = function(){ 

    balls.forEach(b1 => { 

     if(!(this.x===bl.x&&this.y==bl.y 
      &&this.velX===bl.velX&&this.velY===bl.velY)){ 
      var dx = this.x-bl.x; 
      var dy = this.y-bl.y; 
      var distance = Math.sqrt(dx*dx+dy*dy); 

      if(distance<this.size+bl.size){ 
       bl.color = this.color = "rbg(" + random(0,255) +"," +random(0,255) +"," +random(0,255) +")"; 
      } 
     } 
    }); 
} 
+0

Спасибо @Barmar, два твоих предложения, но принесу еще одну проблему. В ожидаемом результате, когда шарики разваливаются, они меняют цвет и продолжают двигаться. В моем первом испытании шары не меняют цвет для столкновения. Ваше предложение изменяет цвет шарика, но количество мячей также уменьшилось, и, наконец, все шары раздаются. Ты знаешь почему? Если вы хотите посмотреть, есть готовая версия в ссылке в начале вопроса. Спасибо. –

+0

Можете ли вы сделать jsfiddle, который демонстрирует проблему? Здесь ничего нет, что удалит шары. – Barmar

+0

Спасибо, Бармар. Это будет ваше первое предложение. http://jsbin.com/wikijaxuze/1/edit?js,output Это для вашего второго предложения. http://jsbin.com/luvetuzigo/edit?js,output –

0

Вы можете привязать функцию к любому контексту/области, которую вы хотите. Таким образом, он будет работать:

Ball.prototype.collisionDetect = function(){ 

balls.forEach(function(bl){ 

    if(!(this.x===bl.x&&this.y==bl.y 
     &&this.velX===bl.velX&&this.velY===bl.velY)){ 
     var dx = this.x-bl.x; 
     var dy = this.y-bl.y; 
     var distance = Math.sqrt(dx*dx+dy*dy); 

     if(distance<this.size+bl.size){ 
      bl.color = this.color = "rbg(" 
      + random(0,255) 
      +"," 
      +random(0,255) 
      +"," 
      +random(0,255) 
      +")"; 
     } 
    } 
}.bind(this)); 
} 
+0

Спасибо, @abeyaz, я попробовал ваше предложение, он вроде как работает, но приносит еще один неожиданный результат. В ожидаемом результате, когда шары collid, они изменят цвет и продолжат двигаться. В моем первом испытании шары не меняют цвет для столкновения. Ваше предложение изменяет цвет шарика, но количество мячей также уменьшилось, и, наконец, все шары раздаются. Ты знаешь почему? Если вы хотите посмотреть, есть готовая версия в ссылке в начале вопроса. Спасибо. –

1

Это подпись Array#forEach:

arr.forEach(callback[, thisArg]) 

Как вы можете видеть, Array#forEach принимает 2-й из параметров, thisArgs, который устанавливает this обратного вызова, когда он выполняется ,

Таким образом, пройти текущий this как 2 пар, и он будет назначен на обратный вызов:

Ball.prototype.collisionDetect = function(){ 

    balls.forEach(function(bl){ 

     if(!(this.x===bl.x&&this.y==bl.y 
      &&this.velX===bl.velX&&this.velY===bl.velY)){ 
      var dx = this.x-bl.x; 
      var dy = this.y-bl.y; 
      var distance = Math.sqrt(dx*dx+dy*dy); 

      if(distance<this.size+bl.size){ 
       bl.color = this.color = "rbg(" 
       + random(0,255) 
       +"," 
       +random(0,255) 
       +"," 
       +random(0,255) 
       +")"; 
      } 
     } 
    }, this); // set thisArg to this 
} 
+0

Спасибо @Ori Drori, я ценю ваше предложение, это вроде работы, но приносит еще одну проблему. В ожидаемом результате, когда шарики разваливаются, они меняют цвет и продолжают двигаться. В моем первом испытании шары не меняют цвет для столкновения. Ваше предложение изменяет цвет шарика, но количество мячей также уменьшилось, и, наконец, все шары раздаются. Ты знаешь почему? Если вы хотите посмотреть, есть готовая версия в ссылке в начале вопроса. Спасибо. –

 Смежные вопросы

  • Нет связанных вопросов^_^