徒手写 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 访问。

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

相关推荐
Qrun29 分钟前
Windows11安装nvm管理node多版本
前端·vscode·react.js·ajax·npm·html5
中国lanwp30 分钟前
全局 npm config 与多环境配置
前端·npm·node.js
JELEE.1 小时前
Django登录注册完整代码(图片、邮箱验证、加密)
前端·javascript·后端·python·django·bootstrap·jquery
TeleostNaCl3 小时前
解决 Chrome 无法访问网页但无痕模式下可以访问该网页 的问题
前端·网络·chrome·windows·经验分享
前端大卫5 小时前
为什么 React 中的 key 不能用索引?
前端
你的人类朋友5 小时前
【Node】手动归还主线程控制权:解决 Node.js 阻塞的一个思路
前端·后端·node.js
小李小李不讲道理7 小时前
「Ant Design 组件库探索」五:Tabs组件
前端·react.js·ant design
毕设十刻7 小时前
基于Vue的学分预警系统98k51(程序 + 源码 + 数据库 + 调试部署 + 开发环境配置),配套论文文档字数达万字以上,文末可获取,系统界面展示置于文末
前端·数据库·vue.js
mapbar_front8 小时前
在职场生存中如何做个不好惹的人
前端
牧杉-惊蛰8 小时前
纯flex布局来写瀑布流
前端·javascript·css