如何把js的代码写的更加容易维护(一)--面向对象编程
总是头疼javascript的代码写起来不可维护,那么看看下面的代码:
(function (w, $) {
var app = {
init: function () {
var me = this;
me.render();
me.bind();
},
datas: {
num: 1
},
render: function () {
var me = this;
me.test = $('#table td');
},
bind: function () {
var me = this;
me.test.on('click', $.proxy(me['_do'], this));
},
_do: function (e) {
var m = $(e.target).text();
var me = this;
m = me.datas.num + m;
var s = '<input type="text" value="' + m + '">';
$(e.target).html(s);
}
};
app.init();
exports = app;
})(window, jQuery);
代码其实很简单,其基本思路就是,将数据、函数、事件监听和回调都封装在一个对象中,那么我们可以简单的把这个对象理解为一个组件。
封装的难点:事件监听和回调
封装的难点其实在于事件的监听和回调,先看一个简单的实现:
bind: function () {
var me = this;
me.test.on('click', function(e) {
// 操作
});
},
就是以匿名函数的形式写回调函数,可以满足需求,但如果有大量的事件需要监听、绑定回调函数时,这种方式显然就不太合理了:bind方法会变得过长而不好维护,那么以传入具名函数函数名的方式就可以解决这个问题,但是会遇到回调函数中的this不是指向app对象而指向触发元素的问题:
bind: function () {
var me = this;
me.test.on('click', me['_do']);
},
_do: function(e) {
// 这里的this指向谁?
var targetEle = $(e.target);
// 这里的this显然指的是触发事件的元素,在这里是一个jQuery对象
var me = this;
// 下面这句就会报错
m = me.datas.num + m;
}
那么如何解决上面的问题,答案就是$.proxy(fn, contenxt),这个方法可以改变函数执行时的上下文:
bind: function () {
var me = this;
me.test.on('click', $.proxy(me['_do'], this));
},
上面的代码使me['_do']被调用时,this指向app,那么在me['_do']中就可以获取app中的数据,从而解决了上面this的指向问题。
总结
上面的js代码实现了一个简陋的可编辑表格的功能,这段代码是京程一灯袁志佳在腾讯视频公开课上讲的代码,我贴在这里来提醒自己:前端javascript的编写还有许多要学习和挖掘的地方。代码中主要用到了jQuery.proxy()这个强大的函数,另外就是这种对象封装的思想。
存在的问题
虽然$.proxy()解决了this的指向问题,但它也不是完美的。这里在使用事件委托时就要小心了:
render: function () {
var me = this;
me.document= $(document);
},
bind: function() {
document.on('click', 'ul li', $.proxy(me['_do2'], this));
},
_do2: function(e) {
var eleTarget = $(e.target);
}
因为_do2中的this不再指向绑定事件的元素ul li,所以要想在_do2中获取ul li就有些麻烦,尤其是li中嵌套比较多的子元素时:
<ul>
<li>
<div><span></span>...</div>
</li>
</ul>
_do2中的eleTarget由于事件冒泡的原因可能是:span、div、li,那么该如何解决这个问题?很遗憾我没有想到好的解决方法,提供两个思路:1,如果li中嵌套了太多的子元素,那么事件委托在这里就不是一个好的解决方案了。2,如果嵌套的子元素不多,那么还可以通过查找的方法找到ul li,这个也是可行的。当然,如果抛开本文章,单纯使用事件委托还是可以的:
$(document).on('click', 'ul li', function(e) {
var this = $(this);
});
因为这里的this始终指向ul li,即委托的元素ul li。
这篇文章最初发表在我自己折腾的博客站点上:如何把js的代码写的更加容易维护(一)--面向对象编程,该博客用了一位前辈开源的源码,基于thinkjs和vuejs开发,欢迎大家来逛逛。
如何把js的代码写的更加容易维护(一)--面向对象编程的更多相关文章
- 自写脚本实现上线前本地批量压缩混淆 js , css 代码。
最近做项目遇到一个要求,就是把本地的 js 和 css 进行压缩后再上线,由于之前项目并没有使用 webpack 之类的库,项目上也因为一些机密不能在线上压缩,这无疑给代码打包压缩带来了很大麻烦,于是 ...
- CSS 黑魔法小技巧,让你少写不必要的JS,代码更优雅
首页 登录注册 CSS 黑魔法小技巧,让你少写不必要的JS,代码更优雅 阅读 8113 收藏 927 2017-09-26 原文链接:github.com 腾讯云容器服务CSS,立 ...
- 2019前端面试系列——JS高频手写代码题
实现 new 方法 /* * 1.创建一个空对象 * 2.链接到原型 * 3.绑定this值 * 4.返回新对象 */ // 第一种实现 function createNew() { let obj ...
- 如何让你的JS代码写的更漂亮
感觉这篇文章总结的js的规范写法不错,拿来收藏.转自:https://mp.weixin.qq.com/s/AtR94IL9BW9EXOTnKOilmA 1. 按强类型风格写代码 JS是弱类型的,但是 ...
- 引擎渲染速度测试--我js代码写得少你不要骗我
上一张图,很多人都看过的 地址:http://aui.github.io/artTemplate/test/test-speed.html 这个地址是在看artTemplate的时候看到的,很早都看过 ...
- JS函数 编程练习 使用javascript代码写出一个函数:实现传入两个整数后弹出较大的整数。
编程练习 使用javascript代码写出一个函数:实现传入两个整数后弹出较大的整数. 任务 第一步: 编写代码完成一个函数的定义吧. 第二步: 我们来补充函数体中的控制语句,完成函数功能吧. 提示: ...
- 网络问卷调查js实现代码
昨天一个同行妹纸写了一个网络问卷调查的效果,但是有bug,于是就来问我该如何解决这个bug.经过我的分析,bug主要还是出在复选框的那部分,经过修改,bug问题解决,现在贴出如下代码,仅供大家参考: ...
- js原生代码实现轮播图案例
一.轮播图是现在网站网页上最常见的效果之一,对于轮播图的功能,要求不同,效果也不同! 我们见过很多通过不同的方式,实现这一效果,但是有很多比较麻烦,而且不容易理解,兼容性也不好. 在这里分享一下,用j ...
- 原生JS实战:写了个斗牛游戏,分享给大家一起玩!
本文是苏福的原创文章,转载请注明出处:苏福CNblog:http://www.cnblogs.com/susufufu/p/5869953.html 该程序是本人的个人作品,写的不好,未经本人允许,请 ...
随机推荐
- 3dmax导入模型,解决贴图不显示的问题
在3dmax中导入模型数据后,经常出现贴图不显示的情况,效果如下图: 解决方法: 1.怀疑是贴图文件的路径设置有误.快捷键 shift+T打开“资源追踪”界面,重新设置贴图的正确路径(这里如果快捷键无 ...
- Android RecycleView 自定义Item的使用
自定义布局的RecycleView需要自己实现Adapter,ViewHolder和布局: 自定义Adapter继承RecycleView.Adapter,重写getItemCount(),onBin ...
- Kotlin入门(2)让App开发变得更容易
上一篇文章介绍了如何搭建Kotlin的开发环境,可是这个开发环境依然基于Android Studio,而在Android Studio上使用Java进行编码,本来就是理所应当的,何必还要专门弄个Kot ...
- C#中禁止跨线程直接访问控件
C#中禁止跨线程直接访问控件,InvokeRequired是为了解决这个问题而产生的,当一个控件的InvokeRequired属性值为真时,说明有一个创建它以外的线程想访问它.此时它将会在内部调用ne ...
- [20171206]rman与truncate.txt
[20171206]rman与truncate.txt --//昨天下班在回家的路上,突然想起以前遇到的问题,就是truncate表后,rman做备份时会备份多少truncate表的信息,--//当时 ...
- 根据id来大量删除数据between
id的范围来删除数据 比如要删除 110到220的id信息:delete id from 表名 where id between 110 and 220;
- 【PAT】B1032 挖掘机技术哪家强(20 分)
#include<cstdio> const int maxx= 100010; int school[maxx]={0}; int main() { int n,schid,schsco ...
- 1.1开篇一:C语言编译器的选择---Dev C++
返回总目录 目录: 1.Dev C++的下载&安装: 2.Dev C++的使用: 前言: 那么多编译器,为什么选择Dev C++?理由有下 理由一:Dev C++ 体积比较小,不占用太多的内存 ...
- strong vs copy
一.前言 在这里,我通过实例去介绍strong和copy的区别(%p打印出来对象的地址) ViewController.h #import <UIKi ...
- Department and Student
软工结对作业之二 本人ID:杨光海天 031502634 队友(大佬)ID:陈涵 031502106 GitHub链接 BIN文件地址 代码文件 整体概况 模型建立 学生类,属性包括: * 1)编号 ...