jQuery插件架构语法 - 这条线是什么意思?

时间:2011-12-29 22:44:19

标签: javascript jquery-plugins

我正在阅读用于插件开发的jQuery文档,我遇到了一行无法解决的代码。

  $.fn.tooltip = function( method ) {

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' );
}    

有问题的一行:

return methods[method].apply(this, Array.prototype.slice.call(arguments,1));

据我所知,所有javascript对象都继承了call()和apply(),我理解这两个函数之间的差异。我不明白的是Array上的原型。数组对象已经有一个slice(),为什么原型需要在这里?由于call()接受两个参数,即'this'(上下文)和参数列表,我不明白上面的调用调用是如何工作的。有人可以帮我理解这一行吗?

由于

2 个答案:

答案 0 :(得分:1)

arguments对象继承自Object.prototype。它可能看起来像一个数组,但事实并非如此。要对其执行数组操作,需要以下行:

Array.prototype.slice.call(arguments,1)

上一行复制arguments“数组”,并在其上使用slice(1)方法。

Array.prototype.slice(arguments, 1)相当于:

  • arguments转换为true数组(通过将Array.slice`的this设置为参数)
  • 使用.slice(1)方法返回不包含第一个元素的数组。

(请注意,在此过程中不会修改arguments对象)

的伪代码:

var arguments = {1: "arg1", 2: "arg2", 3: "arg3", length: 3};
var copy = convert_object_to_array(arguments); //This function does not exists
// copy looks like: ["arg1", "arg2", "arg3"]
copy.slice(1); //Returns ["arg2", "arg3"]

答案 1 :(得分:1)

简单来说,函数Array.prototype.slice如下:

Array.prototype.slice = function(from) {
    return elements of `this` from index `from`;
};

所以,当您执行Array.prototype.slice.call(obj, a)时,您将获得obj仅包含来自索引a的元素。

问题是它只在数组上可用,但您可以使用您描述的语法使它在对象上工作:

var obj = { length: 3,   0: 'a',   1: 'b',   2: 'c' };
Array.prototype.slice.call(obj, 1); // { length: 2,   0: 'b',   1: 'c' }

参数也一样 - 它不是一个数组,因此您必须使用Array.prototype.slice.call访问该函数。

基本上,数组与参数的唯一不同之处在于数组继承自Array.prototype,因此您可以直接调用arr.slice()