使用 Object.defineProperty 实现单例模式,解决 layui 组件覆盖导致的问题

先前在 逼乎 知乎看到对 Layui 的争论,绝大部分职业前端都在吐槽,支持者都是一些顺手写写前端的后端或者前端小白。
虽然我是半路出家,但好歹也是个职业前端人,态度嘛自不待言。由于 Layui 学起来没啥压力、引入方式又那么方便,所以很多用着过时的技术、靠拼凑代码过活的外包公司尤其喜爱,所以会导致出现很多难以维护的代码。其实我也明白,贤心大佬的出发点是好的,错不在 Layui ,错在许多使用者轻视前端开发的工程化和专业化的风气,而 Layui 则助长了这样的风气
很不巧由于公司研发力量薄弱,老板又要小步快跑,于是买了一套基于 Discuz 的系统,前端代码基本都是 php 拼合的 HTML 片段,由于前述原因,很多片段都引入了 Layui 及其个别组件,一个页面最多引入十二次之多……导致后面的 Layui 引入之后,往往会把前面的给覆盖掉,覆盖是没问题的,问题在于把人家的组件也盖掉了,所以控制台里山河一片红,都是找不到组件。
一开始我选择手动加上报错的组件,但是这套系统时不时还有更新,每更新一次我的代码就被覆盖一次,抓狂。
思前想后,问题原因是 Layui 的反复初始化 ,用单例模式即可解决,落地的方案是在页面公共头部加这段代码:

!function(){
        // catch the first layui
        // fixme Warning: 此实现可能导致版本滞后,引起兼容问题。
        // TODO 将所有插件混入同一个 layui 实例,并升级 layui (尽量采用最新的版本)
        var layuiBuffer = null;
        Object.defineProperty(window, 'layui', {
            get: function(){
                return layuiBuffer || this;
            },
            set: function(value){
                !layuiBuffer && (layuiBuffer = value);
                return value
            }
         });
    }();

虽然不是完美的解决方案(注释里也说了,被钦点为单例的版本可能滞后,导致新的问题),但是那一堆报错算是解决了。
之后我也构想过一个比较“完美”的解决方案 —— upgrade.js,来解决解决上述方案可能导致版本滞后的问题,但是考虑到类似 JS 库会慢慢被淘汰,并且类似问题出现的概率不大,顿时就没了更新的动力。

你可能感兴趣的:(使用 Object.defineProperty 实现单例模式,解决 layui 组件覆盖导致的问题)