在我的 javascript 项目中获取不正确的值时,将函数作为事件处理程序的回调传递



在这里,我有一个刚刚提取的问题部分代码,因为它是一个带有clickInfo方法的对象,我想在单击html中的testDivbtn时使用该方法

var product = {
        jsondata:[
        {title:"GearBox", price:80000},
        {title:"Clutch", price:7000}
        ],
    loadInfo:function (event) {
    ​   // This line is printing first product info from the jsondata array​ - just to test
     console.log (this.jsondata[0].title + " " + this.jsondata[0].price);
      }
}

这是附加到单击处理程序的简单div

$ ("#testDivbtn").click(product.loadInfo); 

这是 html

<div class="col-sm6"><button id="#testDivbtn" type="button" class="btn btn-default">Test Product</button></div>

它在控制台中显示错误 - 无法读取未定义的属性"0"我在我的应用程序中的许多其他地方都有此错误,如果任何一个点错误都会非常有帮助。

你需要

使用bind

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

编号 : https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_objects/Function/bind

最初当你使用 this.jsondata[0].title 时,这里this指的是 <button> 元素,它没有属性.jsondata

$(function() {
  var product = {
    jsondata: [{
      title: "GearBox",
      price: 80000
    }, {
      title: "Clutch",
      price: 7000
    }],
    loadInfo: function(event) {
      console.log(this.jsondata[0].title + " " + this.jsondata[0].price);
    }
  }
  $("#testDivbtn").click(product.loadInfo.bind(product));
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="col-sm6">
  <button id="testDivbtn" type="button" class="btn btn-default">Test Product</button>
</div>

波利填充

if (!Function.prototype.bind) {
  Function.prototype.bind = function(oThis) {
    if (typeof this !== 'function') {
      // closest thing possible to the ECMAScript 5
      // internal IsCallable function
      throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
    }
    var aArgs   = Array.prototype.slice.call(arguments, 1),
        fToBind = this,
        fNOP    = function() {},
        fBound  = function() {
          return fToBind.apply(this instanceof fNOP
                 ? this
                 : oThis,
                 aArgs.concat(Array.prototype.slice.call(arguments)));
        };
    if (this.prototype) {
      // Function.prototype don't have a prototype property
      fNOP.prototype = this.prototype; 
    }
    fBound.prototype = new fNOP();
    return fBound;
  };
}

在那里,您需要了解与正确使用"this"对象相关的一些概念。 很少有方法,如 bind(( -(从 ES5 开始(、apply(( 和 call((。 现在正如我所看到的,你的代码将 尝试详细解释这一点

在这里,按钮 $("#testDivbtn"( 本身就是一个对象,您将 product.loadInfo 方法作为回调传递给它的 click(( 方法,因为它位于 product.loadInfo 方法中,将不再引用产品对象。"this"现在将引用 product.loadInfo 中的对象 方法被执行,因为它是在该方法中定义的。 调用 product.loadInfo 的对象是按钮对象,product.loadInfo 将在按钮对象的单击方法中执行。

即使您使用 product.loadInfo(( 调用 loadInfo (( 方法。在这一点上,应该很明显 当上下文更改时,当我们在最初定义对象以外的其他对象上执行方法时,

"this">

关键字不再引用最初定义"this"的原始对象,但它现在引用调用定义"this"的方法的对象。

当方法作为回调函数传递时解决此问题的解决方案: 由于您确实希望 this.jsondata 引用产品对象上的 jsondata 属性,因此我们可以使用 Bind ((、Apply (( 或 Call (( 方法来专门设置此值。

如上所述,答案建议使用绑定替换所有像这样的地方

    $("#testDivbtn").click (product.loadInfo);

有了这个

    $("#testDivbtn").click (product.loadInfo.bind (product)); // it will print Gearbox 80000 in console.

我正在链接一个问题,在这里寻找有关应用调用绑定的更多详细信息真的很好Javascript call(( & apply(( vs bind((?

最新更新