上代码:
(function( $ ){
var methods = {
init : function( options ) {
// THIS
},
show : function( ) {
// IS
},
hide : function( ) {
// GOOD
},
update : function( content ) {
// !!!
}
};
$.fn.tooltip = function( method ) {
// Method calling logic
if ( methods[method] ) {
return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
} else if ( typeof method === 'object' || ! method ) {
return methods.init.apply( this, arguments );
} else {
$.error( 'Method ' + method + ' does not exist on jQuery.tooltip' );
}
};
})( jQuery );
});
// calls the init method
$('div').tooltip();
// calls the init method
$('div').tooltip({
foo : 'bar'
});
// calls the hide method
$('div').tooltip('hide');
// calls the update method
$('div').tooltip('update', 'This is the new tooltip content!');
以上代码是官方jQuery Plugins开发提供的开发文档上的一个例子。(参见:http://docs.jquery.com/Plugins/Authoring)
这里主要是对第22行代码的理解: return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
首先是Array.prototype.slice.call( arguments, 1)这个方法,前面这一段实际上只是单纯的对slice方法的调用,然后通过call设置其执行时的作用域。我们知道Array是JS默认的引用类型,也是一个内置对象,而每个引用类型都有一个prototype属性,实际上prototype才是保存它们所有实例方法的真正所在。(有人可能会疑问,为什么访问实例化之后的对象的prototype里面的方法的时候不能加.prototype,而这里访问Array这种内置对象的prototype下面的方法的时候要加.prototype。好吧,先记住这个规则,具体的原因可以参看《JavaScript高级程序设计(第三版)》第148页的解释) call方法接收两个参数,第一个参数是一个对象arguments,即设置其执行时的作用域为arguments对象;第二个参数1实际上是要传给slice方法的参数,我们知道slice方法是从位置0开始检索的,而我们调用插件的时候,如:$(‘div’).tooltip(‘update’, ‘This is the new tooltip content!’); 实际上第一个参数是我们想要执行的方法名,第二个参数才是我们想要传入的参数。slice执行之后,返回一个数组,正好作为apply的第二个参数传过去。
举例来说,当插件的调用方式是:
1. $(‘div’).tooltip();
第22行代码不会执行,因为if()里面的判断条件为false;
-
$(‘div’).tooltip(‘hide’);
第22行代码实际上就是:
return methods[‘hide’].apply( this, [] );
methods[ method ]实际上是访问对象属性的另一种形式,换成一种我们熟悉的形式就好理解了:
return methods.hide.apply( this, [] ); -
$(‘div’).tooltip(‘update’, ‘This is the new tooltip content!’);
第22行代码实际上就是:
return methods.update.apply( this, [‘This is the new tooltip content!’] );