?
本系列文章由石川创作,李松峰翻译,W3ctech.com首发,图灵社区转载。
?
?
“OOP与jQuery”是“解码jQuery”系列中的一个子系列,主要讨论jQuery的内部构成及相关的OOP(Object Oriented Programming,面向对象编程)概念。
在这篇文章中,我们会讨论函数作用域、jQuery连缀模式和jQuery.fn。
?
?
1. 函数作用域
?
? ? ?我们都看到了,jQuery对象被包装在了很多层函数中。为什么我们用函数来定义作用域呢?因为JavaScript不能用花括号 ? ? ?定义作用域。JavaScript变量只有全局作用域和函数作用域。
?
? ? ?举例来说吧,为了把下面这个jQuery变量变成私有变量,必须把它包装在一个函数中:
?
function a() { var jQuery = "hellow world"; } console.log(jQuery); // undefined
?
? ? ?JavaScript函数具有词法作用域。什么意思?就是说,函数的作用域是在定义的时候创建的,而不是在执行的时候创建 ? ? ? ? ?的。
?
var jQuery = "hi there"; var f= function() { console.log(jQuery); var jQuery = "hello world"; }; f(); // undefind
?
? ? ?所以,如果运行上面的代码,返回的值会是undefined,而不是"hi there"。就是说,在同一个变量作用域或者同一个函数 ? ? ?内,只要有使用var声明jQuery的语句,那就可以在函数中的任何位置访问它,包括在var语句之前。所以上面的等同于:
?
var jQuery = "hi there"; var f = function() { var jQuery; // 等同于 var jQuery = undefined; console.log(jQuery); jQuery = "hello world"; }; f(); // undefined
?
? ? ?就是说,函数f有自己的作用域,它没有读var jQuery = "hi there"。但在函数f内部,确定定义了jQuery变量,只不过调用 ? ? ? ?console.log()时,jQuery还没有定义(值为undefined)。
?
2. jQuery连缀模式
?
? ? 看看init方法,不知道你是否注意到了,这个方法返回this。
?
var jQuery = function(selector, context) { // jQuery对象实际上就是一个“增强版的”init函数 return new jQuery.fn.init(selector, context, rootjQuery); } jQuery.fn = jQuery.prototype = { init : function(selector, context, rootjQuery) { // ....... return this; // ....... } }?
? ? ?在jQuery中,可以在一个方法调用后面连缀另一个方法调用。之所以能够如此,是因为每个方法都像这里一样返回this对 ? ? ?象。
? ? ?还是不清楚?我们来解释一下。首先,来看看对象中的this关键字有什么用。
?
var city = { name : "beijing", getName : function() { return this.name; } } console.log(city.getName());
?
? ? ?以下代码输出的城市名是beijing,说明this引用的是city对象。
? ? ?在进一步,如果我们返回的是整个对象呢?
?
var num = { value : 1, minus : function(n) { this.value -= n; return this; }, plus : function(n) { this.value += n; }, getVal : function() { console.log(this.value); } }; num.minus(2).plus(5).getVal();
?
? ? 这样,就可以把方法调用连缀起来了。
?
3. jQuery.fn
?
? ? 在core.js中,我们可以看到这行代码:
?
jQuery.fn = jQuery.prototype = { // ...... }
?
? ? 在我们开发jQuery插件时,经常要用到$.fn,也就是jQuery.fn。现在知道了吧,jQuery插件其实就是添加到 ? ? ? ? ? ? ? ? jQuery.prototype的方法。正因为如此,插件里也不要忘了返回this噢。
?
(function($) { $.fn.fontcolor = function() { return this.each(function() { $(this).css("color", "orange"); }); }; })(jQuery);?
?