保存对此范围的访问

IT技术 javascript jquery this
2021-03-11 21:22:56

我将颜色存储在我想在切换中使用的按钮上的数据属性中。但是,当我尝试使用 访问数据信息时this,没有数据可用。我怎样才能保持对正确this范围的访问

我试图只为不包含跳过的元素切换给定的颜色。

html

<div>
 <input id="toggleButton" type="button" value="Toggle" data-color="Red" />
</div>
<div id="toggleSet">
<div>Element</div>
 <div>Skip</div>
 <div>Element</div>
</div>

css

.ActivateRed{ color: red; }

js

$('#toggleButton').click(function(){
 $("#toggleSet div").each(function(index,element){
  if( element.innerHTML != "Skip" ){
   $(element).toggleClass("Activate"+$(this).data("color"));
                                       //^this has no data to access?
                                       //Why am I getting undefined?
  }
 });
});

这是我尝试jsFiddle我一直Activateundefined作为class名称。为什么不this访问我的 toggleButton 数据?

1个回答

问题说明

这改变了

thisMDN的值已更改,不再引用预期的元素或值。通常这是因为范围发生了变化,因此this引用也发生了变化

这包含在执行上下文中

范围是指当前的执行上下文ECMA为了理解为什么this会发生变化,了解这些执行上下文在 JavaScript 中的运行方式很重要。

执行上下文绑定 this

当控制进入执行上下文(代码正在该范围内执行)时,变量的环境被设置(词法和变量环境 - 本质上,这设置了一个区域供变量进入,这些区域已经可以访问,以及一个区域供局部变量访问存储),并且this发生绑定

执行上下文的 this 绑定已更改

这些上下文形成一个逻辑堆栈。结果是堆栈中更深的上下文可以访问先前的变量,但它们的绑定可能已被更改。每次 jQuery 调用回调函数时,它都会使用applyMDN更改 this 绑定

callback.apply( obj[ i ] )//where obj[i] is the current element

调用的结果apply是在 jQuery 回调函数内部,this指的是回调函数正在使用的当前元素。

例如,在 中.each,常用的回调函数允许.each(function(index,element){/*scope*/}). 在那个范围内,this == element是真的。这样做的结果是,如果您希望有一个前一个this可用,它将被绑定到一个不同的元素。

thisjQuery 回调的简要说明

如上所示,jQuery 回调使用 apply 函数将被调用的函数与当前元素绑定。这个元素来自 jQuery 对象的元素数组。构造的每个 jQuery 对象都包含一个元素数组,这些元素与用于实例化 jQuery 对象选择器jQuery API相匹配

$(selector)调用 jQuery 函数(请记住,这$是对jQuery, 代码:的引用window.jQuery = window.$ = jQuery;)。在内部,jQuery 函数实例化一个函数对象。因此,虽然它可能不是很明显,但在$()内部使用new jQuery(). 这个 jQuery 对象的部分构造是找到选择器的所有匹配项。然后,jQuery 对象包含与选择器匹配的 DOM 元素的类似数组的结构。

当调用 jQuery api 函数时,它将在内部迭代这个类似数组的结构。对于数组中的每个项目,它调用 api 的回调函数,将回调绑定this到当前元素。这个调用可以在上面的代码片段中看到,其中obj是类数组结构,i是用于当前元素在数组中的位置的迭代器。

寻找解决方案

很难确定发生了什么,因为 jQuery 往往会默默地失败。.data()jQuery API在这里仍然是一个有效的调用,它只是返回undefined. 结果,上面的代码产生了一个“Activate”+undefined,“Activateundefined”的类名。

这里要认识到的重要部分是 jQuery 改变了this绑定。为了使用先前的this绑定,该值必须存储在变量中。存储 this 的常用名称是thatselfme,或者在最佳实践中,是对所this代表内容的实际描述

保存绑定有效的原因是回调的执行上下文将在执行上下文堆栈中相对于保存绑定值的位置更深,因此可以访问该存储值。

jsFiddle 演示

$('#toggleButton').click(function(){
 var toggleBtn = this;
     //^ store this into the toggleBtn variable
 $("#toggleSet div").each(function(index,element){
                           //^ binds `this` to the current element
  if( element.innerHTML != "Skip" ){
       //^ we could have used `this.innerHTML` here
     $(element).toggleClass("Activate"+$(toggleBtn).data("color"));
                                        //^ re-use the stored `this` value
  }
 });
});