1.逻辑或运算符||:
由于&&和||可能不考虑第二个运算数,所以我们应尽量避免在它们右边使用具有副作用(赋值、递增、递减和函数调用)的表达式,除非非常清楚自己再做什么。
代码如下 | 复制代码 |
if((a == null) && (b++ >10)) stop(); //b++递增运算可能不被执行 if((b++ >10) && (a == null)) stop(); //保证b++递增运算都被执行 |
2.逐位运算
&和|除了可以进行"逻辑运算"[1]外,还可以进行逐位运算,而&&和||只能进行逻辑运算。
3.JS的&和|与C#的&和|
在JS中,&和|只是逐位运算符,而在C#中,&和|既是逻辑运算符,又是位运算,通过以下代码可以看出。
代码如下 | 复制代码 |
document.write(true & false); //JS,结果为0 document.write(1 & 0); //JS,结果为0 |
当运算符||的两个运算数都是布尔值,它对这两个运算数执行布尔OR操作。
它先计算第一个运算数,如果这个表达式的值可以被转换成true,那么它就返回左边这个表达式的值。否则计算第二个运算数即使||运算符的运算数不是布尔值,任然可以将它看作布尔OR运算,因为无论它返回的值是什么类型,都可以被转换为布尔值。
而且另一方面,对非布尔型的运算数使用了||,这是利用了它对非布尔型的值会将其返回的特性。该运算符的这一用法通常是选取一组备选值中的第一个定义了的并且非空的值(也就是说第一个不会转换为false的值)
例:
代码如下 | 复制代码 |
var max=max_width || preferences.max_width || 500 |
例:
代码如下 | 复制代码 |
var add_level = 0; switch(add_step){ case 5 : add_level = 1; break; case 10 : add_level = 2; break; case 12 : add_level = 3; break; case 15 : add_level = 4; break; default : add_level = 0; break; }
|
将这段代码使用或会是什么样呢?
ok,让我们来看看js强大的表现力吧:
代码如下:
代码如下 | 复制代码 |
var add_level = (add_step==5 && 1) || (add_step==10 && 2) || (add_step==12 && 3) || (add_step==15 && 4) || 0; |
更强大的,也更优的:
代码如下:
代码如下 | 复制代码 |
var add_level={'5':1,'10':2,'12':3,'15':4}[add_step] || 0; |
第二个需求:
代码如下:
代码如下 | 复制代码 |
var add_level = (add_step>12 && 4) || (add_step>10 && 3) || (add_step>5 && 2) || (add_step>0 && 1) || 0; |
首先我们来梳理一下一个概念,请你一定要记住:在js逻辑运算中,0、""、null、false、undefined、NaN都会判为false,其他都为true(好像没有遗漏了吧,请各位确认下)。
这个一定要记住,不然应用||和&&就会出现问题。
这里顺便提下:经常有人问我,看到很多代码if(!!attr),为什么不直接写if(attr);
其实这是一种更严谨的写法:
请测试 typeof 5和typeof !!5的区别。!!的作用是把一个其他类型的变量转成的bool类型。
下面主要讨论下逻辑运算符&&和||。
几乎所有语言中||和&&都遵循“短路”原理,如&&中第一个表达式为假就不会去处理第二个表达式,而||正好相反。
js也遵循上述原则。但是比较有意思的是它们返回的值。
代码:var attr = true && 4 && “aaa”;
那么运行的结果attr就不是简单的true或这false,而是”aaa”
再来看看||:
代码:var attr = attr || “”;这个运算经常用来判断一个变量是否已定义,如果没有定义就给他一个初始值,这在给函数的参数定义一个默认值的时候比较有用。因为js不像php可以直接在型参数上定义func($attr=5)。再次提醒你记住上面的原则:如果实参需要是0、""、null、false、undefined、NaN的时候也会当false来处理。
代码如下 | 复制代码 |
if(a >=5){ alert("你好"); } 可以写成: a >= 5 && alert("你好"); |
这样只需一行代码就搞定。但是需要注意的一点就是:js中||和&&的特性帮我们精简了代码的同时,也带来了代码可读性的降低。这就需要我们自己来权衡了。
一方面精简js代码,能实质性的减少网络流量,尤其是大量应用的js公用库。个人比较推荐的做法是:如果是相对复杂的应用,请适当地写一些注释。这个和正在表达式一样,能够精简代码,但是可读性会降低,对读代码的人要求会高些,最好的办法就是写注释。
我们可以不使用这些技巧,但是我们一定要能看懂,因为这些技巧已经广泛应用,尤其是像JQuery等js框里的代码,不理解这些你就很难看懂别人的代码。
像var Yahoo = Yahoo || {};这种是非常广泛应用的。
ok,最后让我们来看一段jQuery中的代码吧:
代码如下:
代码如下 | 复制代码 |
var wrap = !tags.indexOf("<opt") && [ 1, "<select multiple='multiple'>", "</select>" ] ||
!tags.indexOf("<leg") && [ 1, "<fieldset>", "</fieldset>" ] ||
tags.match(/^<(thead|tbody|tfoot|colg|cap)/) && [ 1, "<table>", "</table>" ] ||
!tags.indexOf("<tr") && [ 2, "<table><tbody>", "</tbody></table>" ] ||
(!tags.indexOf("<td") || !tags.indexOf("<th")) && [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ] ||
!tags.indexOf("<col") && [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ] ||
// IE can't serialize <link> and <script> tags normally
// Go to html and back, then peel off extra wrappers
// Move to the right depth
|
这段代码是作者用来处理 $(html) 时,有些标签必须要约束的,如<option>必须在<select></select>之内的
国外一些参考
The basic theory
In Boolean logic, a statement can have two values, true or false. When using Boolean logic in philosophy, the statement can be a sentence, like
It rains today.
In more down-to-earth applications like JavaScript, a statement is something like
代码如下 | 复制代码 |
x == 4 |
Both statements can be either true or false. When writing a program it is often necessary to see if a statement is true or false. Usually this is done by an if() statement. If the statement x == 4 is true, then do something:
代码如下 | 复制代码 |
if (x==4) { do something } |
All this is not surprising. Boolean logic, however, also offers possibilities to evaluate a whole string of statements and see whether the whole string is true or false. Like:
It rains today AND my feet are getting wet
In Boolean logic, this longer statement is true if it rains today is true AND my feet are getting wet is true.
It rains today OR my feet are getting wet
In Boolean logic, this statement is true if it rains today is true OR if your feet are getting wet is true OR if both statements are true.
This is also very useful when writing programs. For instance, suppose you want to do something if x==4 OR y==1. Then you write:
代码如下 | 复制代码 |
if (x==4 || y==1) { do something } |
The statement (x==4 || y==1) is true when x is 4 OR y is 1.
AND, OR and NOT
For JavaScript purposes, you need to know AND, OR and NOT:
AND (&&): True when both elements are true.
Example: (
代码如下 | 复制代码 |
x==4 && y==1). |
OR (||): True when at least one of the elements is true.
Example:
代码如下 | 复制代码 |
(x==4 || y==1). |
NOT (!): This toggles a statement from true to false or from false to true.
代码如下 | 复制代码 |
Example: (x==4 || !(y==1)). |
This example is true if x is 4 OR y is NOT 1.
Boolean logic also contains the XOR operator, which is true when exactly one statement is true (but not both). JavaScript doesn't support logical XOR.
When you use only two statements, this is all easy. It gets more complicated if you want to use three or more statements, like:
代码如下 | 复制代码 |
if (x==4 && (!(y==1) || z==0) { do something } |
As in mathematics, the bit that's between the brackets () is evaluated first. So this example is true and the code is executed if x is 4 AND (y is NOT 1 OR z is 0 OR both).
Try it
At first sight this seems hideously complicated. I could go on writing more about how Boolean logic works, but it's better to try it for yourself.
In the table below you see three statements, X, Y and Z. All of them can be either true or false. Fill in the AND/OR, the NOT's, where the brackets are and the value of X, Y and Z, then hit Boole() to see how your statement evaluates.
代码如下 | 复制代码 |
X . Y (X . Y) . Z X . (Y . Z) not X Y Z |
Play around with it until you start to understand what it's all about. Later you might try to make a prediction before hitting Boole().
Checking a variable
Above we have seen that we can use Boolean logic in a statement like
代码如下 | 复制代码 |
if (x==4 && (!(y==1) || z==0) { do something } |
A second way to use Boolean logic is to see if something exists or not. For instance
代码如下 | 复制代码 |
if (!x) { do something } |
In this example the code is executed if x does NOT exist (x=false).
x is false