【问题标题】:why the program doesn't call the js class function?为什么程序不调用js类函数?
【发布时间】:2016-11-29 16:35:59
【问题描述】:

我在JS中有一个类,里面包含一系列方法,与登录和用户注册有关。这些方法基本上是捕捉页面的事件并做一些事情。

当它为UsersOperations()创建实例时,它被调用(由于点击事件)$("#login").click(function(){});,被正确执行......直到在调用saveUserInfo();之前,此时页面被重新加载,并且我不知道为什么,我不明白,我有相同的方法,但没有上课,一切都很好。

请帮帮我,否则我会因为这个存在问题而死。

$(document).ready(function(){
  new UserOperations();
});

  class UserOperations{
    constructor() {
      if(!this.checkUserWithLogin())
        this.addLoginAndRegisterButtons();
      var self = this;
      $("#Log_In").click(function(){
        $.ajax({
          type: "GET",
          url: "php/request.php",
          async: true,
          data: {nick_log:$("#username").val(),
                  pass_log:$("#userpass").val()},
          success: function(data){
          var dataJson = JSON.parse(data);

          if(dataJson==null)
            alert("You are not registered");
          else {
            if($("#Keep_log").is(':checked')) 
              self.saveUserInfo(dataJson,"localStorage"); 

            else 
              self.saveUserInfo(dataJson,"sessionStorage"); 
            self.checkUserWithLogin();
          },
          error: function (obj, error, objError){
            alert("There is an error!");
          }
        });
      });
   }
}

【问题讨论】:

  • 很可能是因为#login 按钮提交了表单?
  • 但是在那种情况下,ajax函数不会接收到数据(因为它有效地从request.php接收数据)还是没有?不,“#login”按钮不是提交类型。但它在一个表单标签中
  • 你怎么知道success函数被调用了?你怎么知道它在页面重新加载之前执行“直到那个点”?
  • 因为我成功添加了一些alerts...许多alerts,并且直到那时才显示消息
  • 嗯,这可能意味着此时抛出了异常。你看过你的错误控制台吗? (但这并不能解释为什么页面会重新加载)

标签: javascript ajax oop events


【解决方案1】:

因为this 不再引用该对象,所以它找不到函数。您作为回调附加的函数不会关闭this。您可以使用另一个变量,例如 var self = this;,也可以使用 Function.prototype.bind() 绑定回调。

这里有一些示例代码可以使答案更完整,展示了三种不同的机制来保存上下文。这些方法的根本需求是,在创建回调函数时,我们不会自动保留定义回调函数的方法中存在的this 的值。我们需要一些机制来在正确的对象上执行函数:

function Cat(name) {
    this.name = name;

    // Note we don't need anything special when we're immediately executing:
    console.log("Immediate execution with this:");
    this.speak();

    // Option 1. Explicitly specify the value of 'this' inside the callback using bind()
    setTimeout(function () {
        console.log("Callback execution with bind:");
        this.speak();
    }.bind(this), 1000);

    // Option 2. Copy 'this' into a local variable which is then captured in a closure
    var self = this;
    setTimeout(function () {
        console.log("Callback execution with closure variable:");
        self.speak();
    }, 2000);

    // Option 3. (ES6) Use a lambda/arrow function which does preserve the value of 'this' from the context in which it was defined
    setTimeout(() => {
        console.log("Lambda preserves the value of this:");
        this.speak();
    }, 3000);

}

Cat.prototype.speak = function () {
    console.log(this.name + " says meow!");
}

【讨论】:

  • 如果是这样,为什么this.addLoginAndRegisterButtons() 运行正确?太奇怪了,我也试过把this.拿出来,结果还是一样。
  • 因为在第一行,您仍然在构造函数中,而不是在回调中。构造函数具有正确的上下文,但是当您创建用作回调的匿名函数时,该函数将没有该上下文。我正在吃午饭,正在玩手机——回家后我会添加更多代码来更好地解释这一点。
  • oooooh,我现在明白了,你有所有的理由。那是我没有考虑上下文。我更改了代码,现在可以使用...非常感谢!
  • @Spines - 很高兴它正在工作!添加了更多示例代码以获得更完整的答案,展示了解决此问题的几种方法。
猜你喜欢
  • 1970-01-01
  • 2013-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-28
  • 2011-12-13
  • 1970-01-01
  • 2022-07-01
相关资源
最近更新 更多