Javascript 的邏輯運算符的使用技巧和其內在邏輯

      Javascript是一個弱類型的語言,也體現在了對表達式的邏輯計算上。對於Java等強類型的語言,進行邏輯判斷時,如 if(condition) 中condition所表示的表達式,其結果必須是返回的爲true或false的表達式,而javascript 則不然,它可以允許condition是 Number,String,或者Object對象,也可以是undefined 或null的變量,在這方面體現了很大的靈活性。JavaScript引擎會對if(condition) 中condition 的值先進行ToBoolean操作,即將condition的值轉換成boolean邏輯值,其ToBoolean的規則如下:


      本文主要詳細討論上述的condition參數類型的轉換,以及更爲"詭異"的 與(&&) 和 或(||)運算符,以及它們的內在邏輯。

 1. ToBoolean 邏輯值自動轉換

使用過強類型的語言的讀者應該知道,在使用邏輯判斷時,我們提供的邏輯表達式一定是能夠返回true或者是false的,如下的Java代碼所示:

	String s;
	if(s==null)
	{
	   //some logic ....
	}
對於上述的s,在if()內的表達式,必須能夠返回true或者false,我們不能寫成if(s),否則Java編譯器會報錯。對於若類型的JavaScript語言而言,它有着不同的認識角度:它認爲沒有被定義的變量或者值爲null 的變量,用在邏輯判斷時,應該返回false;而對於存在的Object對象而言,應該返回true;對於數字而言,+0,-0,或者NaN,應該是返回false,反之返回true;而對於String,如果是空字符換,則認爲是false,否則爲true。

2. ! 和!! 運算符 與類型強制轉換

通常,我們可以在if(condition) 的condiction直接使用Object、String、Number、null、undefined值或者變量,Javascript引擎會自動地將condition進行ToBoolean操作比如,對於一個var  s="abc" 的字符串,如果進行if(s),Javascript引擎會計算s的boolean值,由於s 不是空字符串,則會返回true:

	var s="abc";
	if(s)
	{
	   alert("true");
	}
當然,我們也可以手動地轉換它。我們可以使用 非運算符! 讓表達是轉換成對應的boolean值的相反值。如下所示:
	var s="abc";
	var flag = !s;
	console.log(flag);//~output:false
	console.log(typeof flag);//~output:boolean
由上可知,經過對s進行了!操作後,flag值爲boolean類型的,並且值爲false,這就是強制類型轉換!但是這裏的結果值和實際值相反,所以,我們用!!s 還原成原始的邏輯值:
	var s="abc";
	var flag = !!s;
	console.log(flag);//~output:true
	console.log(typeof flag);//~output:boolean
注意 !!s中的!!這兩個非運算符,它們起到的作用有很大的不同哦,最右邊的 !運算符,首先是Javascript首先對s進行了強制類型轉換,然後再進行非操作,左邊的!非操作符則是簡單的非運算。 如果大家有閱讀過Javascript框架如prototype或者jquery的經歷,對於代碼中的 兩個!形式的運算符!! 就不足爲奇了。 !! 運算符的作用就是將不同類型的參數轉換成對應的表示的邏輯值,如下代碼所示:
	//1.x未被定義賦值,值爲undefined
	var x;
	var flag1 = !!x;
    console.log(flag1);	//~output: false
    
	//2. y 爲null
	var y= null;
	var flag2 = !!y;
	console.log(flag2);//~output: false
	
	//3. number類型的值分別爲:+0,-0,NaN,34
	var z1 = (+0),
		z2=(-0),
		z3=NaN,
		z4=34;
	var flag3=!!z1,
		flag4=!!z2,
		flag5=!!z3,
		flag6=!!z4;
	console.log(flag3,flag4,flag5,flag6);//~output: false,false,false,true
	
	//4.string類型的值,爲"" 和"abc"
	var s1="",
		s2="abc";
	var flag7= !!s1,
		flag8=!!s2;
	console.log(flag7,flag8);//~output: false,true
	
	//5.object 對象
	var obj ={};
	var flag9=!!obj;
	console.log(flag9);//~output: true

  3. && 和|| 運算符

 短路與 &&運算符 

Javascript 的雙目運算符&& 和|| 分別完成 短路與 和 短路或 的功能。現在先看 && 運算符。一般&& 運算符的使用有以下格式:

	 if(statement1 && statement2 )
	 {
	    //some logic ...
	 }
上述的 statemetnt1 && statement2 語句,只有當statement1 和statement2 同時爲true時,statemetnt1 && statement2 纔會返回true。 若statement1 和statement2 有任何一個爲false,statemetnt1 && statement2都爲false。不過短路與 更加智能化,javascript在解析statemetnt1 && statement2 語句時,按照從左到右的順序解析,如果statement1 爲false,則statemetnt1 && statement2返回必然爲false,於是javascript不再解析statement2,直接返回false。

如下所示:

	 var object ={};
	 if(object && true)
	 {
	    console.log("true");//~output:true
	 }
	 console.log(false && object)//~output:false

statemetnt1 && statement2 語句的執行邏輯

實際上,  statemetnt1 && statement2 的語句返回值並不是準確意義上的true或者false。

來看下面的例子:

    var object ={};
    var result = (true && object);	
    console.log(typeof result);//~output: object
    console.log(result === object);//~output: true
    var result1 = (null && false);
    console.log(result1 ===null);
從上述的代碼可以看出,true && object 返回的是第二個參數object,而不是經過計算過的Boolean值;另外,如果第一個參數的Boolean值爲false,其返回的也不是參數對應的Boolean值,而是參數本身,null 的Boolean的值爲false,但是result1的值爲null,而不是對應的boolean值。

其實 statement1 && statement2 語句的執行邏輯是這樣的:

	// statement1 && statement2 等價於:
	{
	    if(statement1)
		{
		    return statement2;
		}
	    return statement1;
	}
如果statement對應的邏輯值 爲true,則返回statement2;否則返回statement1(儘管statement1 的邏輯boolean值爲false,但是還是返回statement1本身)

當然,如果使用者想強制獲取到 statemetnt1 && statement2 的boolean 值,可以使用!!,即!!(statemetnt1 && statement2)。



短路或 || 運算符 以及它的執行邏輯

一般 || 運算符使用格式如下所示:

	if(statement1 || statement2)
	{
	  // some logic .....
	}

和&& 運算符想對應,||運算符的執行邏輯如下:
	// statement1 || statement2 等價於:
	{
	    if(statement1)
		{
		    return statement1;
		}
	    return statement2;
	}

即|| 運算符的邏輯爲,如果statement1 對應的Boolean值爲true,則直接返回statement1 否則返回statement2。

例子如下:

	var object ={};	
	var result = (object||false);
	var result2 = (false ||object);
	console.log(result === object); //~output: true
	console.log(result2 === object);//~output: true
	console.log(typeof result);//~output: object
	console.log(typeof result2);//~output: object











發佈了60 篇原創文章 · 獲贊 2069 · 訪問量 105萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章