作为一个前端er,如果不会写一个小插件,都不好意思说自己是混前端界的。写还不能依赖jquery之类的工具库,否则装得不够高端。那么,如何才能装起来让自己看起来逼格更高呢?当然是利用js纯原生的写法啦。以前一直说,掌握了js原生,就基本上可以解决前端的所有脚本交互工作了,这话大体上是有些浮夸了。不过,也从侧面说明了原生js在前端中占着多么重要的一面。好了。废话不多说。咱们就来看一下怎么去做一个自己的js插件吧。
插件的需求
我们写代码,并不是所有的业务或者逻辑代码都要抽出来复用。首先,我们得看一下是否需要将一部分经常重复的代码抽象出来,写到一个单独的文件中为以后再次使用。再看一下我们的业务逻辑是否可以为团队服务。
插件不是随手就写成的,而是根据自己业务逻辑进行抽象。没有放之四海而皆准的插件,只有对插件,之所以叫做插件,那么就是开箱即用,或者我们只要添加一些配置参数就可以达到我们需要的结果。如果都符合了这些情况,我们才去考虑做一个插件。
插件封装的条件
一个可复用的插件需要满足以下条件:
插件自身的作用域与用户当前的作用域相互独立,也就是插件内部的私有变量不能影响使用者的环境变量;
插件需具备默认设置参数;
插件除了具备已实现的基本功能外,需提供部分API,使用者可以通过该API修改插件功能的默认参数,从而实现用户自定义插件效果;
插件支持链式调用;
插件需提供监听入口,及针对指定元素进行监听,使得该元素与插件响应达到插件效果。
关于插件封装的条件,可以查看一篇文章:原生JavaScript插件编写指南
而我想要说明的是,如何一步一步地实现我的插件封装。所以,我会先从简单的方法函数来做起。
插件的外包装
用函数包装
所谓插件,其实就是封装在一个闭包中的一种函数集。我记得刚开始写js的时候,我是这样干的,将我想要的逻辑,写成一个函数,然后再根据不同需要传入不同的参数就可以了。
比如,我想实现两个数字相加的方法:
function add(n1,n2) {
return n1 + n2;
}
// 调用
add(1,2)
// 输出:3
这就是我们要的功能的简单实现。如果仅仅只不过实现这么简单的逻辑,那已经可以了,没必要弄一些花里胡哨的东西。js函数本身就可以解决绝大多数的问题。不过我们在实际工作与应用中,一般情况的需求都是比较复杂得多。
如果这时,产品来跟你说,我不仅需要两个数相加的,我还要相减,相乘,相除,求余等等功能。这时候,我们怎么办呢?
当然,你会想,这有什么难的。直接将这堆函数都写出来不就完了。然后都放在一个js文件里面。需要的时候,就调用它就好了。
// 加
function add(n1,n2) {
return n1 + n2;
}
// 减
function sub(n1,n2) {
return n1 - n2;
}
// 乘
function mul(n1,n2) {
return n1 * n2;
}
// 除
function div(n1,n2) {
return n1 / n2;
}
// 求余
function sur(n1,n2) {
return n1 % n2;
}
OK,现在已经实现我们所需要的所有功能。并且我们也把这些函数都写到一个js里面了。如果是一个人在用,那么可以很清楚知道自己是否已经定义了什么,并且知道自己写了什么内容,我在哪个页面需要,那么就直接引入这个js文件就可以搞定了。
不过,如果是两个人以上的团队,或者你与别人一起协作写代码,这时候,另一个人并不知道你是否写了add方法,这时他也定义了同样的add方法。那么你们之间就会产生命名冲突,一般称之为变量的 全局污染
用全局对象包装
为了解决这种全局变量污染的问题。这时,我们可以定义一个js对象来接收我们这些工具函数。
var plugin = {
add: function(n1,n2){…},//加
sub: function(n1,n2){…},//减
mul: function(n1,n2){…},//乘
div: function(n1,n2){…},//除
sur: function(n1,n2){…} //余
}
// 调用
plugin.add(1,2)
上面的方式,约定好此插件名为plugin,让团队成员都要遵守命名规则,在一定程度上已经解决了全局污染的问题。在团队协作中只要约定好命名规则了,告知其它同学即可以。当然不排除有个别人,接手你的项目,并不知道此全局变量已经定义,则他又定义了一次并赋值,这时,就会把你的对象覆盖掉。当然,可能你会这么干来解决掉命名冲突问题:
if(!plugin){ //这里的if条件也可以用: (typeof plugin == ‘undefined’)
var plugin = {
// 以此写你的函数逻辑
}
}
或者也可以这样写:
var plugin;
if(!plugin){
plugin = {
// …
}
}
这样子,就不会存在命名上的冲突了。
【版权与免责声明】如发现内容存在版权问题,烦请提供相关信息发邮件至 lnkj@3173.top ,我们将及时沟通与处理。 本站内容除了3117站长服务平台( www.3117.cn )原创外,其它均为网友转载内容,涉及言论、版权与本站无关。