Confused: Why Pass a String as an Array Index in jQuery?
I'm working through R Murphy's JQuery Fundamentals and am trying to make sense of her solution: slideshow.js.
She's created the following function (I've removed some of the navigation code in order to focus on the core functionality of fading images in and out):
fadeCallback = function() {
if (manualMode) { return; }
var $this = $(this),
$next = getItem($this, 'next'),
num = $this.prevAll().length + 1;
// set the timeout for showing
// the next item in 5 seconds
timeout = setTimeout(function() {
开发者_如何转开发 showItem($this, $next);
}, 5000);
};
Inside fadeCallback she calls getItem() to get the next sibling of $this:
getItem = function($item, trav) {
var $returnItem = $item[trav]();
return $returnItem.length ?
$returnItem :
$items[(trav == 'next') ? 'first' : 'last']();
},
I'm getting lost by her use of 'next' in the second argument to getItem(). Is this a roundabout way of calling the .next() jQuery function on the first argument, '$(this)'?
If so, why not just call the function directly? i.e. $item.next();?
Follow-up question
Maybe I've been looking at this code too long but it seems to me that inside getItem(), in the line:
$items[(trav == 'next') ? 'first' : 'last']();
trav is never not 'next'. Yet by virtue of the code testing whether trav equals 'next' it implies that there are cases where trav != 'next'. But I can't identify any such case.
What am I not seeing?
The code needs to make a decision whether to call the "first" or "last" function, based on whether the value of the parameter is the string "next" or not. Thus, it performs the comparison, uses the result to decide between the two function names, then access the functions as properties of the "$item" object, and finally calls whichever function was chosen.
The [ ]
"operator" in JavaScript is not just for arrays. In general, it's used to access a property of an object:
object [ propertyName ]
evaluates "propertyName" — which can be any expression — as a string, and then returns the value of the property (or undefined
). If the object is an array, integer values of "propertyName" are treated slightly specially, but that treatment is subtle and pretty much undetectable because numeric properties always can work, since they have a clear conversion to string values.
Alternative way of writing this, with "standard" function calls is:
var $returnItem = (trav == 'next') ? $item.next() : $item.prev();
return $returnItem.length ?
$returnItem :
(trav == 'next') ? $items.first() : $items.last();
As Pointy explains very well, JavaScript allows to call functions that are part of "complex" object in different way by "invoking" them as members of the object. Maybe this basic example will help you understand this better, you can mess around with it if you like.
By doing so, the author calls $item
only once instead of twice (same with $items
) and avoiding the conditional statement.
She is actually testing to see if there is a $returnItem. In case it does, the function return that item, while if it does not it checks if trav == next
and gets the first element of the $items
collection if so. If trav is not equal to next, it returns the last element from the collection using $items['last']
精彩评论