JavaScript中的执行上下文

时间:2015-12-22 18:40:48

标签: javascript

我有一个名为Gallery的对象,它有几个属性和方法。 其中之一setCurrentPicture在显示新照片/视频之前从gallery容器中删除所有现有照片和视频DOM元素。除了我的画廊停止播放视频(将其设置为暂停模式)时,用户点击它。这是Gallery原型中的togglePlayVideo方法。首先,我从DOM中删除元素,然后显示新内容。如果这是视频,我将eventListener添加到文档, 使用绑定方法。

因此,在setCurrentPicture中我想删除视频元素上的EventListener。删除eventListener时,是否可以将此上下文绑定到Array.prototype.forEach方法中的文档?如果我将必要的上下文保存到新变量中,那么我就成功了。但后来我尝试绑定,我的IDE正在说这个'可能无效的用法。

代码段:

Gallery.prototype = {
  setCurrentPicture: function(currentPhoto) {
        var self = this;

        Array.prototype.forEach.call(container.children, function(item) {
          if (item.tagName === 'VIDEO') {
            document.removeEventListener('click', self.togglePlayVideo);
          }
          if (item.tagName === 'VIDEO' || item.tagName === 'IMG') {
            container.removeChild(item);
          }
        });

       if (pictures[currentPhoto] instanceof Video) {
          var video = document.createElement('video');
          ....
          document.addEventListener('click', self.togglePlayVideo);
        }
    },
},

 togglePlayVideo: function(e) {
      if (e.target.tagName === 'VIDEO') {
        return e.target.paused ? e.target.play() : e.target.pause();
      }
    }
}

如果添加document.addEventListener('click', self.togglePlayVideo); 我可以使用bind而不是self: document.addEventListener('click', this.togglePlayVideo.bind(this)

我可以在removeEventListener中使用bind吗?  document.removeEventListener(' click',this.togglePlayVideo.bind(this);

2 个答案:

答案 0 :(得分:2)

最适合你的是熟悉"这个"什么是" bind"。您可以阅读此brilliant description

来执行此操作

second part

简而言之 - 当你用&#34声明一个函数时,这个"像这样:

  1. 在违约情况下"这个"将是Window对象

    var f = function(){return this;};

    f(); //will return Window object

  2. 当一个对象拥有你的函数的链接时:

    var f = function(){return this;};

    var o = {func: f};

    o.func(); // will return the "o" object becuase "this" becomes o object

  3. 当你使用像call / apply这样的显式绑定时,你会将它设置为一个特定的值,如下所示:

    var f = function(){return this;};

    var obj = {};

    f.call(obj); // will return your obj

  4. 并且有所谓的"硬绑定"。像这样使用:

    var f = function(){return this;};

    var obj1 = {num:1};

    var obj2 = {num:2};

    var boundFunc = f.bind(obj1); //now it's hardbound to obj1

    //let's try to switch this by using "call"

    boundFunc.call(obj2); // will return obj1, because it's hardbound

  5. 当使用" new"调用函数时,这可能会受到影响关键字:

    f = function(){ this.a =1; this.b =2; };

    var obj = new f(); // will set brand new object as "this" and return it

    //so we will get {a:1, b:2} object as a result

答案 1 :(得分:0)

我应该将此绑定添加到Array.prototype.forEach.call,而不是将其实现为回调函数。

 Array.prototype.forEach.call(container.children, function(item) {
          if (item.tagName === 'VIDEO') {
            document.removeEventListener('click', this.togglePlayVideo);
          }
          if (item.tagName === 'VIDEO' || item.tagName === 'IMG') {
            container.removeChild(item);
          }
        }.bind(this));

感谢大家的回答。