在对象文字内的函数内调用函数

时间:2017-11-18 17:50:32

标签: javascript

所以我正在为我在网上发现的一个视频做一个教程。在该教程中,他使用 IIFE 来创建mvc模型而不是对象文字

我决定使用对象文字

重新创建项目

这是我现在遇到的问题,我不确定问题是什么。我怀疑它与范围界定问题有关。

这是控制器的代码,最后我启动了init()。

var model ={ //Code }
var view = {//Code}

var controller = {
    dom: view.getDom(),
    setEventHandler: function(){
       document.addEventListener("keypress", function(ev){
          if(ev.keyCode === 13){
             this.addItem();
          }
      });
    },

    addItem: function(){
      this.updateMethod();
      // Code
    },
    init: function(){
       this.setupEventHandler();
    },
    updateMethod: function(){
       // Some code
    }


{

controller.init();

现在,当我按下回车键调用该事件时,我从控制台收到错误。它声明:

"未捕获的TypeError:this.addItem不是HTMLDocument的函数。[匿名]"

问题: 为什么不识别addItem()?

当我尝试调用this.updateMethod()时,addItem()中会出现相同的错误消息。

我发现在事件监听器中调用this.addItem()的一种方法是使用()=> ,而不是使用常规的匿名函数声明。

document.addEventListener("keypress", (ev) => {
   if(ev.keyCode === 13){
      this.addItem();
   {
});

2 个答案:

答案 0 :(得分:4)

在JavaScript中,this的值取决于函数的调用方式。在您的示例中,this指的是绑定事件的元素。

方法很少,

  1. 使用Function#bind
  2. 使用Arrow Function
  3. this保留在变量中
  4.   

    使用Function#bind

    var model = {};
    var view = {};
    var controller = {
      dom: view.getDom(),
      setEventHandler: function() {
        document.addEventListener("keypress", function(ev) {
          if (ev.keyCode === 13) {
            this.addItem();
          }
        }.bind(this));
      },
      addItem: function() {
        this.updateMethod();
        // Code
      },
      init: function() {
        this.setupEventHandler();
      },
      updateMethod: function() {
        // Some code
      }
    };
    controller.init();
    
      

    使用箭头功能:

    var model = {};
    var view = {};
    var controller = {
      dom: view.getDom(),
      setEventHandler: function() {
        document.addEventListener("keypress", (ev) => {
          if (ev.keyCode === 13) {
            this.addItem();
          }
        });
      },
      addItem: function() {
        this.updateMethod();
        // Code
      },
      init: function() {
        this.setupEventHandler();
      },
      updateMethod: function() {
        // Some code
      }
    };
    controller.init();
    
      

    使用变量保持this上下文

    var model = {};
    var view = {};
    var controller = {
      dom: view.getDom(),
      setEventHandler: function() {
        var _this = this;
        document.addEventListener("keypress", function(ev) {
          if (ev.keyCode === 13) {
            _this.addItem();
          }
        });
      },
      addItem: function() {
        this.updateMethod();
        // Code
      },
      init: function() {
        this.setupEventHandler();
      },
      updateMethod: function() {
        // Some code
      }
    };
    controller.init();
    

答案 1 :(得分:0)

  

问题:为什么不识别addItem()?

     

...

     

我发现在事件监听器中调用this.addItem()的一种方法是使用()=>而不是使用常规的匿名函数声明。

因为使用传统的函数语法,this的值受调用者约束,因此它成为绑定元素。虽然箭头函数不绑定其自己的this值,但它将使用this方法中的setEventHandlercontroller方法将引用init

请注意setupEventHandler来电setEventHandler,但应该是filter