在ES6类中绑定事件

概述

ES6提供了类,给模块化带来了很大的帮助。在类里面绑定事件,一来是为了使得代码结构清晰,二来是为了可以使用类的变量和方法。但是,由于事件的回调函数并不是由类的实例对象触发,所以,事件回调函数里面并不能访问类的this变量。另外,我们也不希望事件回调函数对外暴露,免得调用者直接调用。

简单来说,我们就希望:
1. 事件回调函数要能访问类的this变量
2. 事件回调函数不能直接调用

如何访问类的this

方案一:将类的this保存成一个局部变量

this的指代是动态改变的,但是局部变量的指代却是明确的,并且,函数定义的局部变量在整个函数里面都可以用。所以,我们可以使用let that = this保存类的this变量。


class A{//绑定事件的方法bindEvent(){let that = this;this.button1.on('click',function(e){this.addClass('on'); //this指代所点的元素that.doSomething();  //that指向类的this})}doSomething(){//事件处理函数}//解绑事件unBindEvent(){this.button1.off();}}

这种方法只在使用jquery时有用,因为jquery解绑事件不需要提供回调函数,直接off就可以了。但是原生js需要提供回调函数也有它的道理,因为同一个元素的同一种事件可以绑定多个回调函数,所以你需要指出释放哪一个。

方案二:使用bind()改变this的指向

有类A,在A中要添加mousemove事件,根据需求写出下面代码:

class A{//添加事件addEvent(){document.addEventListener( 'mousemove', onMouseMove, false );}//添加事件removeEvent(){document.removeEventListener( 'mousemove', onMouseMove , false );}}//事件回调函数中
function onMouseMove(event){console.log(this);    //#document
}

但是,这样获取不到类的this。onMouseMovethis将会指向document。因为事件是添加到document上的,所以自然是由document触发事件并调用onMouseMove进行处理,所以onMouseMove中的this指向document

比较正确的做法是:使用bind()函数改变onMouseMovethis的指向,同时将事件回调函数移到类外面:

class A{//添加事件addEvent(){document.addEventListener( 'mousemove', onMouseMove.bind(this), false );}//添加事件removeEvent(){document.removeEventListener( 'mousemove', onMouseMove.bind(this) , false );}}//事件回调函数中
function onMouseMove(event){console.log(this); 
}

但是这样仍然存在问题,事件移除不掉了!因为this.bind()每次调用都会返回一个新的函数,所以:

document.addEventListener( 'mousemove', onMouseMove.bind(this), false );

document.removeEventListener( 'mousemove', onMouseMove.bind(this), false );

两者的第二个参数并不相同。

正确的做法是: 将bind()的结果保存到一个变量中:

class A{constructor(){this._onMouseMove = onMouseMove.bind(this);    //看这里}//添加事件addEvent(){document.addEventListener( 'mousemove', this._onMouseMove , false );}//添加事件removeEvent(){document.removeEventListener( 'mousemove', this._onMouseMove , false );}}//事件回调函数中
function onMouseMove(event){console.log(this); 
}

如何定义私有的事件回调函数

在Java中,不想对外暴露的方法可以定义为私有方法,但是ES6并没有提供私有方法,只能通过一些办法模拟。但是,事件回调函数比较特别,因为事件除了定义,还要移除,这会带来额外的麻烦。但还是有办法的:

使用Symbol变量来定义

const _onMouseMove = Symbol("_onMouseMove");
class A{constructor(){this[_onMouseMove] = onMouseMove.bind(this);}//添加事件addEvent(){document.addEventListener( 'mousemove', this[_onMouseMove] , false );}//添加事件removeEvent(){document.removeEventListener( 'mousemove', this[_onMouseMove] , false );}}//事件回调函数中
function onMouseMove(event){console.log(this); 
}

Symbol("_onMouseMove")会产生一个唯一的值,这个值是在对象创建的时候才生成的,所以,调用者没有办法在写代码时知道这个值的,所以,就无法调用使用这个值命名的方法了,这样就定义了一个私有方法。


参考链接

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/430050.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

DevExpress.Utils.ToolTipLocation

private void textBox1_TextChanged(object sender, EventArgs e){if ((sender as TextBox).Text.Length 0){DevExpress.Utils.ToolTipLocation tipLocation new DevExpress.Utils.ToolTipLocation();toolTipController1.ShowHint("不能为空", textBox1, ToolTipLo…

github基本使用教程

2017-10-22 更新 目前已经有一个很好的Github教程—— Git it,可以花半个小时比较全面的了解github的使用,直接在relaese里下载一个最新版,双击运行就可以看到教程了。下面的教程也还可使用。 如果不熟悉 git命令,可以使用 learngitbranchi…

python while九九乘法表儿歌_python使用while循环实现九九乘法表

protocol http not supported or disabled in libcurl apt-getubuntu 14.04 碰到了这个莫名其妙的问题.谷歌了一把,解决方案如下:http://askubuntu.com/questions/683857/curl-1-protocol-https-n ...linux基础-基本命令的讲解(1-7单元)基本命令的讲解 主要内容介绍 1…

EF+postgresql中的一些问题

需要基于MVC的WebAPI搭建一个服务接口,数据存储在postgresql数据库,在使用的过程中遇到了很多问题。做一下记录: (1) System.IO.FileLoadException: 未能加载文件或程序集“Npgsql, Version3.1.2.0, Cultureneutral, P…

Navicat Error 2003 - can't connect to mysql server 'localhost' (10061)

项详细出错对象:Navicat for mysql出错信息:2003 - can’t connect to mysql server ‘localhost’ (10061)出错原因:mysql 服务器没有启动解决办法:去mysql的安装目录下找到“\bin\mysqld.exe”,双击运行!…

▲数据结构 笛卡尔树【2011】五2 C++版

转载于:https://www.cnblogs.com/qilinart/articles/5940726.html

运行时异常与一般异常有何异同_Java修行第015天,异常机制和常用类

1. 异常概念_分类1) 什么叫异常?答:异常(Expection)就是在程序运行过程中所发生的不正常的事件,它会中断正在运行的程序2) 请简述异常的分类?答:异常分为Error(仅靠程序本身无法恢复的严重错误)和由Java应用程序 抛出和处理的非严重错误.非严重错误又分为…

js 自定义事件

自定义事件很难派上用场? 为什么自定义事件很难派上用场,因为以前js不是模块化开发,也很少协作。因为事件本质是一种通信方式,是一种消息,只有存在多个对象,多个模块的情况下,才有可能需要用到…

uWSGI安装配置

uWSGI安装配置官方网站:http://uwsgi-docs.readthedocs.io环境:CentOS 7.2python-2.7.5一.安装yum -y install gcc gcc-c python-develcurl -sSL https://projects.unbit.it/downloads/uwsgi-2.0.14.tar.gz |tar -xvf - --gzipcd uwsgi-2.0.14make -j4################# uWSGI …

python日志输出 超量 停止_linux 内存分配参数导致的 buffer_pool 分配不出来的问题排查...

linux 内存分配参数导致的 buffer_pool 分配不出来的问题排查:参考:http://blog.csdn.net/jollyjumper/article/details/24127009原文:http://www.cnblogs.com/gomysql/p/6130405.htmlvm.overcommit_memory默认值为:0从内核文档里…

javascript自定义事件应用实例

可以先看例子 从 js 自定义事件 里知道:元素A通过dispatchEvent方法触发的事件,只有A上注册的监听器才能监听得到。 我们想要的效果是,别的对象干了某件事之后, 发个消息给我们,好让我们能做相应的改变。要做到这样…

啥是ETL、ELT

ETL就是Extract、Transfrom、Load即抽取、转换、加载三个英文单词首字母的集合。抽取:就是从源系统抽取需要的数据,这些源系统可以是同构也可以是异构的:比如源系统可能是Excel电子表格、XML文件、关系型数据库,而目标系统通常都是…

python无法导入numpy_python – Pycharm无法导入numpy

我的系统是Mac OS X.我首先通过macport安装numpy然后下载Pycharm并发现无论我选择哪种解释器我都无法导入numpy.结果如下:/Library/Frameworks/Python.framework/Versions/2.7/bin/python2.7 "/Users/erleye/Documents/Python/Pycharm Projects/test.py"T…

DOM Element对象的offsetXXX方法

原生js的offset***方法 c.offsetLeft 和 c.offsetTop 一般指当前元素的CSS边框相对于其offsetParent的X和Y坐标c.offsetHeight 和 c.offsetWidth 当前元素及其所有内容的高度&#xff0c;宽度。c.offsetParent 大多数元素都的都是指<body> 参考《javascript权威指南 第六…

weblogic10异常:org.hibernate.hql.ast.HqlToken

转自&#xff1a;http://www.programgo.com/article/68682994452/ 在做查询的时候&#xff0c;报出 org.hibernate.QueryException: ClassNotFoundException: org.hibernate.hql.ast.HqlToken这 个错误&#xff08;是通过数据源连接的&#xff09; 解决方法如下&#xff1a;…

出现一个黑色框按不动_创意 | 这才是走心的衣架设计,给衣服一个高逼格的家!...

12月&#xff0c;来到了年底剁手的时节自己新买的秋冬衣服&#xff0c;加上以前的衣服几乎都要把你的衣橱给撑爆了只恨衣架不够用&#xff0c;够用也没有空间可以挂衣服了也许以前的衣架只是为了挂衣服&#xff0c;让空间变得整洁一些&#xff1b;现如今&#xff0c;衣架从样式…

windows搜索工具_加快搞定并替代 Windows 10 搜索框搜索文件速度的免费小工具

毫无疑问&#xff0c;Everything 搜索是 Windows 操作系统上可用的最快的搜索工具之一。它比内置的 Windows 搜索工具快得多&#xff0c;因为它几乎立即返回结果&#xff0c;并支持许多自定义选项以优化搜索。而今天大眼仔要给大家分享的是可以把 Everything 固定的任务栏上的免…

同步和异步简述

同步&#xff1a;执行当前进程&#xff0c;当进程执行到某个请求时&#xff0c;若该请求需要一段时间才返回信息&#xff0c;那么这个进程将会一直等待下去直到请求返回。 异步&#xff1a;与同步相反&#xff0c;他不会等到直到信息返回才继续执行下去&#xff0c;而是直接执行…

计算鼠标移动的精确速度

效果 要达到无论在什么机器上&#xff0c;算出来的速度是一样的。 思路&#xff1a; 计算两次mousemove之间的位移和时间&#xff0c;就可以算出精确的速度 不要将onMousemove的调用时间间隔看成是均等的&#xff0c;事实上也不是均等的&#xff0c;而是根据机器的运行状况…

python数组元素复制_python的numpy数组 的复制问题?

还是一句一句来分析吧第一句vector numpy.array([5, 10, 15, 20])用numpy生成一个array对象 &#xff1a; vector然后第二句equal_to_ten_or_five (vector 10) | (vector 5)这里有个或操作首先 vector10 这个其实是把vector里面的所有对象与10对比&#xff0c;相同为True&a…