我正在阅读用于插件开发的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'(上下文)和参数列表,我不明白上面的调用调用是如何工作的。有人可以帮我理解这一行吗?
由于
答案 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()
。