为什么要有面向对象的思维,因为如果不这样,你可能需要一个方法的时候就去定义一个function,当需要另外一个方法的时候,再去随便定义一个function,同样,需要一个变量的时候,毫无规则地定义一些散落在代码各处的变量。
还是老问题,不方便维护,也不够清晰。当然,这些问题在代码规模较小时是体现不出来的。
如果将需要的重要变量定义到对象的属性上,函数变成对象的方法,当我们需要的时候通过对象来获取,一来方便管理,二来不会影响外部命名空间,因为所有这些变量名还有方法名都是在对象内部。
//构造函数
var Beautifier = function(ele, opt) {
//构造函数的属性
//这里在插件内部会传进 this==当前选中的元素
this.$element = ele,
//用户不传参时 会设置的属性
this.defaults = {
'color': 'red',
'fontSize': '16px',
'textDecoration': 'none'
},
//extend工具 使得 有无参数均可设置相应的属性
this.options = $.extend({}, this.defaults, opt)
}
//构造函数原型的方法
Beautifier.prototype = {
//插件其实用到的就是原型里的beatutify方法
beautify: function() {
//设置当前选中元素的样式
//至于为什么用return? 把对象return出去
return this.$element.css({
'color': this.options.color,
'fontSize': this.options.fontSize,
'textDecoration': this.options.textDecoration
});
}
}
//自制插件
$.fn.myPlugin = function(obj) {
//每次调用插件 都会创建一个新实例
var beautifier = new Beautifier(this, obj);
//通过实例方法 设置相应样式
return beautifier.beautify();
//return 保证链式语法
}
通过上面这样一改造,我们的代码变得更面向对象了,也更好维护和理解,以后要加新功能新方法,只需向对象添加新变量及方法即可,然后在插件里实例化后即可调用新添加的东西。
插件的调用还是一样的,我们对代码的改动并不影响插件其他地方,只是将代码的组织结构改动了而以
$(function(){
$('p').myPlugin({
"color":"red",
"fontSize":"30px",
"textDecoration": "underline"
})
})
命名空间的问题
不仅仅是jQuery插件的开发,我们在写任何JS代码时都应该注意的一点是不要污染全局命名空间。因为随着你代码的增多,如果有意无意在全局范围内定义一些变量的话,最后很难维护,也容易跟别人写的代码有冲突。
一个好的做法是始终用自调用匿名函数包裹你的代码
我们知道JavaScript中无法用花括号方便地创建作用域,但函数却可以形成一个作用域,域内的代码是无法被外界访问的。如果我们将自己的代码放入一个函数中,那么就不会污染全局命名空间,同时不会和别的代码冲突。
如上面我们定义了一个Beautifier全局变量,它会被附到全局的window对象上,为了防止这种事情发生,你或许会说,把所有代码放到jQuery的插件定义代码里面去啊,也就是放到$.fn.myPlugin里面。这样做倒也是种选择。但会让我们实际跟插件定义有关的代码变得臃肿,而在$.fn.myPlugin里面我们其实应该更专注于插件的调用,以及如何与jQuery互动。
所以保持原来的代码不变,我们将所有代码用自调用匿名函数包裹。
var foo = function() {
//为了测试如果 不加分号会出现的问题
}
;
(function($) {
var Beautifer = function(ele, opt) {
//保存jQ对象用$
this.$element = ele,
this.defaults = {
'color': 'red',
'fontSize': '16px',
},
this.setting = $.extend({}, this.defaults, opt)
}
Beautifer.prototype = {
beautify: function() {
//此处的return是把我们获取的 元素返还出去
return this.$element.css({
'color': this.setting.color,
'fontSize': this.setting.fontSize
});
}
}
$.fn.myPlugin = function(options) {
var beautifer = new Beautifer(this, options);
return beautifer.beautify();
//return 依然是为了链式调用
}
})(jQuery);
//我发现 在自调用里传进实参 jQuery 里面可以用任何变量名接收
//比如:把 $换为z 下面调用时 就是z.fn.myPlugin .前提是实参一定是!!jQuery!!jquery就不行
//这样 把插件 封装进一个匿名函数里 并 通过 自调用的方式 立即执行 的 好处是
// 1、JavaScript中无法用花括号方便地创建作用域,但函数却可以形成一个作用域,域内的代码
//是无法被外界访问的。如果我们将自己的代码放入一个函数中,那么就不会污染全局命名空间,
//同时不会和别的代码冲突。
//2、自调用匿名函数里面的代码会在第一时间执行,页面准备好过后,
//上面的代码就将插件准备好了,以方便在后面的代码中使用插件。
//为了防止们用来充当自调用匿名函数的第一对括号与上面别人定义的函数相连,
//中间没有分号嘛,代码无法正常解析;
//一个好习惯是我们在代码开头加一个分号
网友评论