开发者

Can anyone explain what is happening in this bit of Javascript?

I was looking through a jQuery smooth-scrolling tutorial, and trying to figure out how it worked, when I hit this line of code:

 $target = $target.length && $target || $('[开发者_开发知识库name=' + this.hash.slice(1) +']');

I can't figure out what it does. It looks like the guy is assigning a string to a variable, but it also kinda looks like he's testing that variable. And I don't understand the use of && and || here. Can anybody explain this?

Thanks!

EDIT: Wow! What a response! This is taking a bit for me to understand, though - I will have to print this out or something and work on it. Once I understand what's going on, I'll be able to pick the answer that helped me the most. In particular, this bit:

if ($target.length && $target) {
$target = $target;

is stymying me. How does the program know to assign $target to $target? Does the operation assign $target to the first reference to itself (the left side of the equals sign), or to the second reference to itself (the right side, after the &&)?


It is a cryptic(or elegant?) version of the equivalent ternary operator

$target = ($target.length && $target) ? $target : $('[name=' + this.hash.slice(1) +']');

This ternary and the original short circuit expression will return exactly same values if the evaluation of $target does not change the value of $target. But if the evaluation of $target changes the value of $target then SCE and ternary returns different values e.g.

var a = 1; b = 2; c = 3;
a && ++b || c
returns 3;
//resetting b
b = 2
a && ++b ? ++b : c 
returns 4;

If the evaluation of $target changes the value of $target then the equivalent ternary operator for the SCE $target = $target.length && $target || $('[name=' + this.hash.slice(1) +']'); would be the following

$target = ($result= ($target.length && $target)) ? $result : $('[name=' + this.hash.slice(1) +']');


It's testing $target (which I assume is a jQuery object) for elements and if empty, assigning a default value.

See Logical Operators for a detailed explanation.

Update

To explain (in case you don't feel like reading the MDN docs), JavaScript logical comparison operators work left-to-right.

expr1 && expr2

This will return expr1 if it can be converted to false; otherwise, returns expr2

expr1 || expr2

This will return expr1 if it can be converted to true; otherwise, returns expr2

To break down the line in question, think of it this way

$target = ($target.length && $target) || $('[name=' + this.hash.slice(1) +']');

Looking at the first operation...

$target.length && $target

This will return $target.length if $target.length can be converted to false (ie 0), otherwise it will return $target.

The second operation looks like this...

(operation1) || $('[name=' + this.hash.slice(1) +']')

If the result of the operation1 can be converted to true (ie $target), then it will be returned, otherwise $('[name=' + this.hash.slice(1) +']').


This is called Short Circuit evaluation and its not equivalent of ternary operator.

and your peace of code equivalent is following:

if ($target.length && $target) {
    $target = $target;
} 
 else {
    $target = $('[name=' + this.hash.slice(1) +']');
}

In JavaScript and most of other loosely-typed languages which have more than the two truth-values True and False, the value returned is based on last value.

a && b will return a if it false, else will return b.

a || b will return a if true, else b.

to better understand last value look at the following examples:

var a = true;
var b = false;
var c = 5;
var d = 0;

return a && b; //returns false
return a && c; //returns 5
return b && c; //returns false
return c && b; //returns false
return c && a; //returns true;
return d && b; //returns 0;
return b && d; //returns false;

return a || b; //returns true
return a || c; //returns true
return b || c; //returns 5
return c || b; //returns 5
return c || a; //returns 5;
return d || b; //returns false;
return b || d; //returns 0;

Update:

Ternary operator:

(condition)?(evaluate if condition was true):(evaluate if condition was false)

Short Circuit Evaluation:

(evaluate this, if true go ahead else return this) && (evaluate this, if true go ahead else return this)

You can clearly see that there is a condition for ternary operator while in SCE the evaluation of value itself is the condition.


$target = $target.length && $target || $('[name=' + this.hash.slice(1) +']');

In javascript you can make inline comparisons when assigning a variable so the example you is the equivalent to

if($target.length && $target)
    $target = $target;
else
    $target = $('[name=' + this.hash.slice(1) +']');

for more examples, see http://www.w3schools.com/JS/js_comparisons.asp
for example:

var x= y > 4 ?value1:value2

Witch means that if condition is true (y is greater than 4), x will be assigned value1 otherwise it will be assigned value2

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜