Javascript 这个代码是做什么的?
虽然我已经写了一些jQuery插件,但我正在通读。现在我看到jQuery有一种特殊的方法来确定方法的作用域和调用:Javascript 这个代码是做什么的?,javascript,jquery,Javascript,Jquery,虽然我已经写了一些jQuery插件,但我正在通读。现在我看到jQuery有一种特殊的方法来确定方法的作用域和调用: (function( $ ){ var methods = { init : function( options ) { // THIS }, show : function( ) { // IS }, hide : function( ) { // GOOD }, update : function( content ) { // !!!
(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 );
我理解最终会发生什么的概念…但具体如何?这一部分让我感到困惑:
// 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 );
}
为什么Array.prototype.slide.call(argumetns,1)
?变量“参数”突然从哪里来?任何简短或深入的解释都将不胜感激。据说,这就是插件的编写方式……所以我想知道为什么
谢谢 参数
参数
是JavaScript语言的一部分。当我第一次遇到它时,我和你一样困惑;不仅仅是你。:-)它是每个函数中的一个自动局部变量,是一个类似数组的结构,提供所有参数(请参见的第10.6节),例如:
请注意,当为namedArg
赋值时,结果会反映在参数[0]
中,反之亦然
arguments
确实很酷,但只有在需要时才使用它-一些实现通过在函数实际首次尝试访问它之前不连接它来加快调用函数的速度,这会降低函数的速度(非常轻微)
参数
上还有一个名为被调用方
的属性,它是对函数本身的引用:
function foo() {
alert(foo === arguments.callee); // alerts true
}
但是,出于以下几个原因,最好避免使用参数.callee
。一个原因是,在许多实现中,调用速度非常慢(我不知道为什么,但让您了解一下,如果使用参数.callee
,函数调用开销可能会增加一个数量级)。另一个原因是不能在ECMAScript 5的新“严格”模式中使用它
(一些实现也有参数。调用者-不寒而栗-但幸运的是,它从未普及,也没有在任何地方标准化(也不太可能)
切片
调用和应用
关于
return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
所做的是使用Array#slice
方法将参数复制到数组中(减去第一个参数,即要调用的方法),然后将结果数组传递到它调用的函数实例上的函数#apply
函数中Function#apply
使用给定的this
对象和作为数组提供的参数调用函数实例。代码不仅使用了参数.slice
,因为(同样)参数
并不是一个真正的数组,所以你不能依赖它拥有所有的数组函数,但是规范明确规定(在第15.4.4.10节中)你可以将Array.prototype.slice
函数应用于任何类似数组的东西,这就是他们所做的
Function#apply
和Function#call
也是JavaScript的内置部分(参见第15.3.4.3节和第15.3.4.4节)。以下是每种方法的简单示例:
// A function to test with
function foo(msg, suffix) {
alert(this.prefix + ": " + msg + suffix);
}
// Calling the function without any `this` value will default `this`
// to the global object (`window` on web browsers)
foo("Hi there", "!"); // Probably alerts "undefined: Hi there!" because the
// global object probably doesn't have a `prefix` property
// An object to use as `this`
var obj = {
prefix: "Test"
};
// Calling `foo` with `this` = `obj`, using `call` which accepts the arguments
// to give `foo` as discrete arguments to `call`
foo.call(obj, "Hi there", "!"); // alerts "Test: Hi there!"
// ^----^-----------^---- Three discrete args, the first is for `this`,
// the rest are the args to give `foo`
// Calling `foo` with `this` = `obj`, using `apply` which accepts the arguments
// to give `foo` as an array
foo.apply(obj, ["Hi there", "!"]); // alerts "Test: Hi there!"
// ^---------------^---- Note that these are in an array, `apply`
// takes exactly two args (`this` and the
// args array to use)
是一个关键字,传递给函数的参数。但是你不需要所有的参数,因为你知道的第一个参数是方法
,所以这就是把第一个参数之后的每个参数都传递给第一个方法
参数中指定的方法
如果它找不到方法
(意味着第一个参数不是'init'
,'show'
,'hide'
,或者'update'
,那么它会转到else
部分,并将所有参数传递给init
方法(如果愿意,默认)
例如:
.tooltip({thing:value})
将调用init({thing:value})
,因为这是默认设置
.tooltip('show',var1,var2)
将调用show(var1,var2)
变量<代码>参数
是定义的javascript变量。它将函数中调用的所有参数存储在数组中。例如:
function variablesCount() {
alert(arguments.length);
}
variablesCount(var1, var2); // alerts 2
Array.prototype.slide.call(argumetns,1)
将参数
伪数组转换为真实数组(跳过第一个元素)
arguments
包含调用您当前所在函数的所有参数。它由JavaScript自动提供。由于我们需要一个实数组(arguments
无法操作等),因此我们使用此语句将其转换为一个数组。arguments
是一个特殊的JavaScript变量,表示“此函数的所有参数”。它不是一个数组,但其行为几乎类似于一个数组,因此它不说arguments.slice(1)
,而是调用array.prototype.slice.call(arguments,1)
;除了列表中的第一个值之外,它所做的一切都将是func(1,2,3,4)
,它将是[2,3,4]
这样做的最终结果是,当您调用$.fn.tooltip('foo','bar','baz')
时,它将尝试调用方法['foo']('bar','baz'))
参数不是传递到函数中的参数吗?有点像Python中的args和kwargs。@Matti Python的args和kwargs与JavaScript的参数非常不同,因为它们是手动指定的:def func(abcd,fghi=True,*args,**kwargs)
,func(43,False,79,83,apple='pie',turnips=False)
。有关参数的粗略Python等价物,请参阅。
!像你这样的ppl是我如此喜爱的原因。
// A function to test with
function foo(msg, suffix) {
alert(this.prefix + ": " + msg + suffix);
}
// Calling the function without any `this` value will default `this`
// to the global object (`window` on web browsers)
foo("Hi there", "!"); // Probably alerts "undefined: Hi there!" because the
// global object probably doesn't have a `prefix` property
// An object to use as `this`
var obj = {
prefix: "Test"
};
// Calling `foo` with `this` = `obj`, using `call` which accepts the arguments
// to give `foo` as discrete arguments to `call`
foo.call(obj, "Hi there", "!"); // alerts "Test: Hi there!"
// ^----^-----------^---- Three discrete args, the first is for `this`,
// the rest are the args to give `foo`
// Calling `foo` with `this` = `obj`, using `apply` which accepts the arguments
// to give `foo` as an array
foo.apply(obj, ["Hi there", "!"]); // alerts "Test: Hi there!"
// ^---------------^---- Note that these are in an array, `apply`
// takes exactly two args (`this` and the
// args array to use)
function variablesCount() {
alert(arguments.length);
}
variablesCount(var1, var2); // alerts 2