将本地变量传递给回调函数[duplicate]

时间:2022-05-12 19:55:19

This question already has an answer here:

这个问题已经有了答案:

Question

问题

How can a callback function retain a local variable from whence it was created?

回调函数如何保留创建它的本地变量?

Simple example

简单的例子

I'm creating a video player. It will have sliders to control the saturation, contrast, and hue. When the user plays with the sliders, it needs to acknowledge which slider got changed and what value it got changed to. The problem is that the name of the slider is a local variable from the scope of the creator of this onChange callback. How can this callback retain the name of the slider?

我正在创建一个视频播放器。它将有滑块来控制饱和度、对比度和色调。当用户使用滑块时,它需要确认哪个滑块被修改了,它被修改了什么值。问题是,滑块的名称是这个onChange回调的创建者的作用域中的一个局部变量。这个回调如何保留滑块的名称?

HTML

HTML

<div id="saturation">
 <div class="track"></div>
  <div class="knob"></div>
 </div>
</div>

<div id="contrast">
 <div class="track"></div>
  <div class="knob"></div>
 </div>
</div>

<div id="hue">
 <div class="track"></div>
  <div class="knob"></div>
 </div>
</div>

JS

JS

var elements = [
 'saturation',
 'contrast',
 'gamma'
];

for(var i = 0; i < sliders.size(); i++) {
 new Control.Slider(
  $(elements[i]).down('.knob'),
  $(elements[i]).down('.track'), {
   onChange: function(value) {
    // ERROR: elements[i] is undefined
    alert(elements[i] + ' has been changed to ' + value);
   }
 }
}

3 个解决方案

#1


6  

The same variable, i — who's value ends up being 4 — is bound to every function you create inside the loop. You could wrap the function in another function that you call on the spot and pass i as a parameter to that function:

同样的变量i——它的值最后是4——被绑定到循环中创建的每个函数。你可以把这个函数封装到另一个函数中,你在这个函数中调用它并将i作为参数传递给这个函数:

for(var i = 0; i < sliders.size(); i++) {
 new Control.Slider(
  $(elements[i]).down('.knob'),
  $(elements[i]).down('.track'), {
   onChange: (function(inner_i) { function(value) {
    alert(elements[inner_i] + ' has been changed to ' + value);
   } })(i)
 }
}

#2


8  

Create a copy of the variable for each callback, you can do this with an anonymous function that you pass in the value:

为每个回调创建一个变量的副本,您可以使用传递值的匿名函数:

for(var i = 0; i < sliders.size(); i++) {

    (function(e) { // get a local copy of the current value

        new Control.Slider(
          $(elements[e]).down('.knob'),
          $(elements[e]).down('.track'), {
           onChange: function(value) {
            // ERROR: elements[e] is undefined
            alert(elements[e] + ' has been changed to ' + value);
           }
         }

     })(i); // pass in the current value
}

This way you don't reference the same i X times.

这样你就不会引用相同的i X次。

#3


0  

Put your function inside a closure in this way:

以这种方式将你的功能放在闭包中:


for(var i = 0; i < sliders.size(); i++) {
 (function(q){
 new Control.Slider(
  $(elements[q]).down('.knob'),
  $(elements[q]).down('.track'), {
   onChange: function(value) {
    // ERROR: elements[q] is undefined
    alert(elements[q] + ' has been changed to ' + value);
   }
 }
 })(i)
}

#1


6  

The same variable, i — who's value ends up being 4 — is bound to every function you create inside the loop. You could wrap the function in another function that you call on the spot and pass i as a parameter to that function:

同样的变量i——它的值最后是4——被绑定到循环中创建的每个函数。你可以把这个函数封装到另一个函数中,你在这个函数中调用它并将i作为参数传递给这个函数:

for(var i = 0; i < sliders.size(); i++) {
 new Control.Slider(
  $(elements[i]).down('.knob'),
  $(elements[i]).down('.track'), {
   onChange: (function(inner_i) { function(value) {
    alert(elements[inner_i] + ' has been changed to ' + value);
   } })(i)
 }
}

#2


8  

Create a copy of the variable for each callback, you can do this with an anonymous function that you pass in the value:

为每个回调创建一个变量的副本,您可以使用传递值的匿名函数:

for(var i = 0; i < sliders.size(); i++) {

    (function(e) { // get a local copy of the current value

        new Control.Slider(
          $(elements[e]).down('.knob'),
          $(elements[e]).down('.track'), {
           onChange: function(value) {
            // ERROR: elements[e] is undefined
            alert(elements[e] + ' has been changed to ' + value);
           }
         }

     })(i); // pass in the current value
}

This way you don't reference the same i X times.

这样你就不会引用相同的i X次。

#3


0  

Put your function inside a closure in this way:

以这种方式将你的功能放在闭包中:


for(var i = 0; i < sliders.size(); i++) {
 (function(q){
 new Control.Slider(
  $(elements[q]).down('.knob'),
  $(elements[q]).down('.track'), {
   onChange: function(value) {
    // ERROR: elements[q] is undefined
    alert(elements[q] + ' has been changed to ' + value);
   }
 }
 })(i)
}