徒手写 JS ,你还会吗? JS 自定义类注意事项整理

背景

有了 React、Vue 等前端开发框架后,开发人员只用关注数据、而不用考虑 DOM 操作问题,前端开发相对容易多了。自从用了前端框架后,我已经六年没用过原生 JS 写过前端了。

最近维护一个老项目,纯 html 页面、数据控制全靠 jQuery 手堆。其中,有一个规则配置选项,十几个编辑页面都引用了它。旧的实现方式是拷贝,每个页面都拷贝了这段配置的代码,大约 500 行。真佩服当时的开发者,宁愿拷贝10次,也不抽取一个工具类。

上周要对这个功能调整,配置方式从前端分页变成后端分页。改十几个引用的地方,逐个拷贝确实挺费手的。心一横,重构一下吧。

卡住的几个点:

  1. 自定义 JS 类时,方法中如何访问类的变量?必须通过 this.变量名称访问。
  2. 类的方法中通过 JQuery 绑定事件/各种回调函数中,想要访问这个类的属性,怎么办法?通过外层先定义一个 this 的拷贝对象,copyThis = this,引用该副本,或者事件回调用 () => {} 表达式。
  3. 拼接的 html 中的事件方法是当前类的方法时,应该怎么访问?用引用该类的变量的方法调用。
  4. 弹框页面想要访问这个工具的方法,可以通过 parent.commonConfigUtil 访问。

公共代码抽取

重构思路,以 JS 类的思维,定义一个类,每个页面只需要创建这个类的对象,然后直接调用这个类的公共方法就可以,主要包含三类方法:

  1. 页面初始化时的按钮绑定事件
  2. 动态拼接数据到页面的配置显示区域
  3. 页面初始化时查询当前绑定的配置并回显
  4. 删除某配置

定义一个公共 js 文件,命名为 configUtil.js ,抽取的类定义如下:

javascript 复制代码
var CommonConfigUtil = function (config) {
    this.config = config;
    this.att1 = 1;
    this.att2 = 20;
    this.pageData = 20;
    this.baseUrl = config.baseUrl;
    
    // 页面初始化绑定按钮事件
    this.bindEvent = function bindEvent() {
        $('#btn1').bind('click',  event => {
            const attr1 = this.attr1;
            // TODO 使用外层类的属性完成按钮的绑定事件
        });

        $('#btn2').bind('click',  event => {
            const aa1 = this.attr2;
			 // TODO 使用外层类的属性完成按钮的绑定事件
        });
    };

   // 动态拼接数据到页面,且绑定一个删除事件
   this.addData = function addData(arr, now, count) {
        let tr = '';
   		this.pageData.forEach(item => {
            tr += '<div id="' + item.id + '">' +
                '<div style="text-align: left;word-break:break-all">' +
                '<h2 class="bkm" id="dd">' + item.name + '</h2><div style="float: right;"></div>' +
                '<a href="javascript: void(0);" onclick="(event.stopPropagation()||(event.cancelBubble = true))&& commonConfigUtil.deleleData(\'' + item.id + '\')" style="float: right;"><i class="layui-icon">&#xe640;</i></a>' +
                '</div>' +
                '</div>';
        });
        $('#configList').append(tr);
  });
  
  // 页面初始化 ajax 回显数据
  this.initConfig = function queryConfigById(id) {
        const copyThis = this;
        $.ajax({
            type: 'GET',
            url: this.baseUrl + "/xx.action",
            data: {
                "id": id
            },
            success: function (pageData) {
                // TODO 数据使用,赋给外部类的属性
                copyThis.pageData = pageData;
            }
        });
    }     

  // 删除
  this.deleteConfig = function deleteConfig(configId) {
  });  
}

公共引用

需要用的地方

javascript 复制代码
<script src="${baseUrl}/xx/configUtil.js"></script>
<script>
     var baseUrl = '${baseUrl}';
     // TODO 从路径参数获取 ID
	 var id = '';	
     // 全局公告配置 变量
     var commonConfigUtil = new CommonConfigUtil({
         baseUrl: baseUrl,
     });
    
    //初始化页面
    $(document).ready(function(){
        commonConfigUtil.bindEvent();
        // 编辑回显
        if (id != '') {
            commonConfigUtil.initConfig(id);
        } 
    });
    ......
</script>

这样就能将 500 行的公告代码转换为十几行的工具类调用了。

启示录

这个抽取过程还是比较容易的,有几个卡壳的点,总结如下:

  1. 自定义 JS. 类的注意事项:方法中不能直接访问类的变量,必须通过 this.变量名称访问。
  2. 类的方法中通过 JQuery 绑定事件、各种回调函数中,想要访问这个类的属性,可以通过 copyThis = this,引用该副本,或者事件回调用 () => {} 表达式,后者有一个问题,它会改变 jQuery 的 $ 操作的 this 信息。所以最简单的还是先定义副本对象,后面需要用类信息时都通过该副本对象。
  3. 拼接的 html 中的事件方法必须时当前页面定义的,如果是引用的某个类的,可以通过该类的变量来访问类对应的方法。拼接的元素commonConfigUtil.deleleData() 这里真正触发时,会调用当前页面的全局变量 commonConfigUtil 对象来访问删除方法。
  4. 页面可以直接访问 commonConfigUtil 的各属性,没有权限问题,这点跟 Java 的类的属性的访问方式不同。
  5. 弹框页面想要访问这个工具的方法,可以通过 parent.commonConfigUtil 访问。

虽然代码拷贝很容易,但是大量重复拷贝,也很费劲呐,把所有的重复代码都删掉、换成这是十几行引用,搞了两天,手点鼠标都快断了。编码工作,懒是偷不了的:大脑想偷懒,徒手拷贝复制也挺受累。不是心累,就是手累!

相关推荐
待磨的钝刨31 分钟前
【格式化查看JSON文件】coco的json文件内容都在一行如何按照json格式查看
开发语言·javascript·json
逐·風3 小时前
unity关于自定义渲染、内存管理、性能调优、复杂物理模拟、并行计算以及插件开发
前端·unity·c#
Devil枫4 小时前
Vue 3 单元测试与E2E测试
前端·vue.js·单元测试
尚梦5 小时前
uni-app 封装刘海状态栏(适用小程序, h5, 头条小程序)
前端·小程序·uni-app
GIS程序媛—椰子5 小时前
【Vue 全家桶】6、vue-router 路由(更新中)
前端·vue.js
前端青山5 小时前
Node.js-增强 API 安全性和性能优化
开发语言·前端·javascript·性能优化·前端框架·node.js
毕业设计制作和分享6 小时前
ssm《数据库系统原理》课程平台的设计与实现+vue
前端·数据库·vue.js·oracle·mybatis
从兄7 小时前
vue 使用docx-preview 预览替换文档内的特定变量
javascript·vue.js·ecmascript
清灵xmf8 小时前
在 Vue 中实现与优化轮询技术
前端·javascript·vue·轮询
大佩梨8 小时前
VUE+Vite之环境文件配置及使用环境变量
前端