javascript - 关于原生JS插件的一些问题?
PHPz
PHPz 2017-04-11 12:31:12
[JavaScript讨论组]

首先有2个测试用的

标签

    

原本的内容1

原本的内容2

然后有个简单的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');
PHPz
PHPz

学习是最好的投资!

全部回复(2)
阿神

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 更方便。

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

ringa_lee

自己检查了下,发现是

 if (!opts) return options;

这句的问题--有点迷惑

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号