javascript - 关于原生JS插件的一些问题?

查看:90
本文介绍了javascript - 关于原生JS插件的一些问题?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问 题

首先有2个测试用的<p>标签

    <p class="demo">原本的内容1</p>
    <p class="demo">原本的内容2</p>

然后有个简单的JS插件

    ! function() {

        //默认属性
        var options = {
            smg1: 'Hello',
            smg2: 'world'
        };

        function changeText(el, stg1, stg2) {
            el.textContent = stg1 + ' ' + stg2 + '!';
        };

        var plugin = {

            config: function(opts) { //参数覆盖
                if (!opts) return options;
                for (var key in opts) {
                    options[key] = opts[key];
                };
                return this;
            },

            listen: function(elem) {
                var elems = document.querySelectorAll(elem);
                for (var i = 0; i < elems.length; i++) {
                    //功能函数
                    changeText(elems[i], options.smg1, options.smg2);
                };   
                return this;
            }

        };

        window.myPlugin = plugin; //暴露给全局
    }();

问题一:config和listen两个函数都return this了,但是还是无法链式调用?比如:

   myPlugin.listen('.demo').config({
        smg1: 'Goodbye',
        smg2: 'guys'
    });

但config在前面又可以:

    myPlugin.config({
        smg1: 'Goodbye',
        smg2: 'guys'
    }).listen('.demo');

问题二:前面的方式与构造函数的方式写插件有什么优劣么?比如下面这个同样的功能

    ! function() {
        var options = { //默认参数
            smg1: 'Hello',
            smg2: 'world'
        };

        function MyPlugin(opts) {
            this.config = Object.assign({}, options, opts); //合并参数
            this.listen(this.config.elem);
        }
        MyPlugin.prototype = {

            constructor: MyPlugin,
            listen: function(elem) {
                var elems = document.querySelectorAll(elem);
                for (var i = 0; i < elems.length; i++) {
                    this.changeText(elems[i], this.config.smg1, this.config.smg2);
                };
            },
            changeText: function(el, smg1, smg2) {
                el.textContent = smg1 + ' ' + smg2 + '!';
            }

        }
        window.MyPlugin = MyPlugin;
    }()
    //调用
            new MyPlugin({
            smg1: 'Hey',
            smg2: 'guys'
        }).listen('.demo');

解决方案

1、问题一:

由于 myPlugin 是一个Object类型,那么意味者 myPlugin 就像是一个静态类一样。而类中不管是 config 还是 listen 里所有 this 都指向Object自身,所以不存在你说的链式写法不正确。

唯一可能结果不对就是listen().config()的写法,或者 config() 不传递参数时结果返回的是 options 非 this,自然也就无法链式。

2、问题二:

相比较前者,后者每一个实例都会有一份独立的数据,并且互不冲突。你可以在 listen 里面加一个 ++this.count 来验证这一点。

其实,这个问题我更想说点 prototype 在这里面的妙处。

示例2中 listenchangeText 都是在 prototype 下面,JavaScript规定,每一个函数都会有这么一个东西 prototype 来指向另一个对象,而该对象所有方法、属性都会被实例继承。

换句话说,当你多次 new MyPlugin() 的话, listenchangeText 在内存当中都将只有一份。

应该如何选择,试着应该考虑几点:

  • 内部数据是否需要互不冲突。

  • myPluginnew MyPlugin 更方便。

  • 是否会在同一个页面中要大量使用插件。

这篇关于javascript - 关于原生JS插件的一些问题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆