【前端】JavaScript表達式-新手必看


轉載請注明出處:http://www.cnblogs.com/shamoyuu/p/6145384.html

 

 

一、什么是表達式

表達式就是JavaScript里一個短句,JavaScript解釋器會將其計算出一個結果

二、表達式分類

 

1、原始表達式

原始表達式是最簡單的表達式,它也是表達式最簡單的類型,復雜的表達式都是由原始表達式組合起來的。

JavaScript中原始表達式包含常量、直接量、關鍵字和變量。

例如:

1.23 // 數字直接量
"hello" // 字符串直接量
/\d/ // 正則表達式直接量
true // 關鍵字
false // 關鍵字
null // 關鍵字
this // 關鍵字

 

 

2、對象和數組的初始化表達式

對象和數組的初始化表達式實際上是一個新創建的對象和數組,這些初始化表達式有時稱作“對象直接量”和“數組直接量”。然而和原始表達式不同的是,它不是原始表達式,因為它所包含的成員或者元素都是子表達式。

例如:

[] // 一個空數組
[1 + 2, 3 + 4] //兩個元素的數組
{} // 一個空對象
{x: 2.3, y: -1.2} //有兩個屬性的對象

 

 

3、函數定義表達式

函數定義表達式定義一個JavaScript函數,表達式的值是這個新定義的函數,從某種意義上講,函數定義表達式也可以稱為“函數直接量”。

例如:

function(x){ return x * x; } // 返回一個包含了一個參數的函數

 

 

4、屬性訪問表達式

屬性訪問表達式運算得到一個對象屬性或者一個數組元素的值,它有兩種語法。

例如:

obj.x    // 返回obj對象的x屬性
obj["x"] // 同上。這里可以傳入變量,例如var str = "x"; obj[str] === obj["x"]
arr[0]   // 返回數組的第一個元素

 

 

5、調用表達式

調用表達式是一種調用函數或方法的語法表示,它以一個函數表達式開始,后面跟隨一對小括號,括號里是逗號隔開的參數。

例如:

foo() // 調用foo方法,沒有參數
Math.max(1, 2, 3) // 調用Math對象的max方法,傳入3個參數

 

 

6、對象創建表達式

對象創建表達式創建一個對象並調用一個函數初始化新對象的屬性(這個函數稱作構造函數)。對象創建表達式和調用表達式非常類似,只是對象創建表達式前面多了一個關鍵字new。

例如:

new Object() // 創建一個Object對象
new Point(2, 3) //創建一個Point對象,並傳入兩個參數

 

 

如果一個對象創建表達式不需要傳入任何參數給構造函數的話,那么這對小括號是可以省略的。

例如:

new Object // 創建一個Object對象
new Date //創建一個日期對象

 

 

7、算術表達式

算術表達式是將基礎表達式通過運算符進行運算的復合型表達式。

算術表達式根據不同的運算符可以分為下面幾類:

a) "+"運算符

可以用作數字加法,也可以用來連接字符串。

例如:

1 + 2 // => 3
"hello" + " " + "world" // => "hello world"
 1 + "2" // => "12"

 

 

b) 一元算術運算符

一元算術運算符作用於一個單獨的操作數,並產生一個新值,它擁有非常高的優先級,而且是右結合。需要注意的是,在必要時,它會把操作數轉換為數字“+”和“-”是一元運算符,也是二元運算符。

例如:

i++ // => 先返回i再對i+1
++i // => 先計算結果再返回i
i--
--i
+”1” // => 1
-”1” // => -1

 

 

c) 位運算符

位運算符可以對由數字表示的二進制數據進行更低層的按位運算。

因為不常用,這里就不一一講解了,有興趣的同學可以自己網上搜一下。主要有:

按位與(&)

按位或(|)

按位異或(^)

按位非(~)

左移(<<)

帶符號右移(>>)

無符號右移(>>>)

 

8、關系表達式

關系運算法用於測試兩個值之間的關系(例如“相等”,“小於”,或“是...的屬性”),根據關系是否成立而返回true或false。關系表達式總是返回一個布爾值。

例如:

1 > 2 // => false
3 <= 4 // => true
1 == "1" // => true
1 === "1" // => false
2 != 2 // => false
2 !== "2" // => true
“a” < “b” // => true 通過ASCII編碼進行比較("a"是97,"b"是98)
null == null // => true
null === null // => true
undefined == undefined // => true
undefined === undefined // => true
null == undefined // => true
null === undefined // => false
Infinity == Infinity // => true
Infinity === Infinity // => true
NaN == NaN // => false
NaN === NaN // => false
"toString" in new Object // => true
new Object instanceof Object // => true

 注:“==”運算符的運算規則請點擊此處查看

 

9、邏輯表達式

邏輯表達式是對操作數進行布爾算術運算,但它的返回值類型由兩個操作數來決定

例如:

true && false // => false
true && true // => true
1 && true // => true
true && 1 // => 1
(x == y) && stop() // 只有x 等於 y 的時候才會執行stop()方法
true || false // => true
false || true // => true
undefined || 3 // => 3 可以用來設置默認值
!true // => false
!false // => true
!-1 // => false
!0 // => true
!undefined // => true
!null // => true
!NaN // => true
![] // => false
!!true // => true
!!0 // => false

 

 

10、賦值表達式

JavaScript使用“=”運算符來給變量或者屬性賦值。“=”運算符希望它的左操作數是一個左值——一個變量或者對象屬性。它的右操作數可以是任意類型的任意值。賦值表達式的值就是右操作數的值。賦值表達式的副作用是,右操作數會賦值給左側的變量或對象屬性。它具有非常低的優先級。

例如:

obj.x = 1 // 為obj的x屬性賦值為1
a = 1 // 為a賦值為1
b = a = 3 // a是3,然后返回3,然后b也是3
a += 2 // 相當於a = a + 2
b = a -= 6 // 相當於 b = a = a - 6

 

 

12、表達式計算

和其他很多解釋性語言一樣,JavaScript同樣可以解釋運行由JavaScript源代碼組成的字符串,並產生一個值。JavaScript通過全局函數eval()來完成這個工作。需要注意的是,eval里並不是所有的語句都可以執行,例如return、break等會報錯。

例如:

eval("3 + 2") // => 5
eval("if(true){ 1 + 2 }") // => 3
eval("{x: 1, y: 2}") // => 會報錯,因為eval把大括號看作塊區域
eval("({x: 1, y: 2})") // => 返回正確的對象

 

 

13、其他運算符

a) 條件運算符(?:

條件運算符是JavaScript里唯一一個三元運算符,有時也直接稱它為“三元運算符”。第一個操作數在“?”之前,第二個操作數在“?”和“:”之間,第三個操作數在“:”之后。當“?”之前的表達式運算結果為true則返回“:”之前的內容,否則返回“:”之后的內容。

例如:

x >= 0 ? x : -x // 求x的絕對值

 

 

b) typeof運算符

typeof是一元運算符,放在單個操作數前面,操作數可以是任意類型。

返回值為表示操作數類型的一個字符串,它的值為"number","boolean","string","function","object","undefined" 這六個之一

例如:

typeof 1 // => “number”
typeof true // => “boolean”
typeof "abc" // => “string”
typeof function(){} // => “function”
typeof undefined // => “undefined”
typeof new Object // => “object”
typeof null // => “object”
typeof [] // => “object”
typeof NaN // => “number”
typeof Infinity // => “number”
typeof /\d{1, 3}/ // => “object”

 

 

c) delete運算符

delete是一元運算符,它用來刪除對象的屬性或者數組元素,刪除失敗則返回false,其他情況下(例如屬性不存在)返回true。需要注意的是,刪除數組的屬性並不會改變數組的lengthdelete並不是簡單地將屬性值置為undefined,delete之后的屬性使用in運算符判斷會返回false。

例如:

delete obj.x // 刪除obj對象的x屬性
delete arr[1] // 刪除數組第2個位置上的元素,但不會改變數組的長度

 

 

d) void運算符

void是一元運算符,它出現在操作數之前,操作數可以是任意類型,操作數可以正常計算,但是會忽略計算結果並返回undefined。

例如:

void 0 // => undefined

 

 

e) 逗號運算符

逗號運算符是一個二元運算符,它的操作數可以是任意類型。它首先計算左操作數,然后計算右操作數,然后返回右操作數的值。左側表達式的計算結果會被忽略

例如:

x = 1, y = 2, z = 3; // 返回3
a = (x = 1, y = 2, z = 3) // a的值是3

 

 

三、其他

上面講了數組是一個object,它的typeof返回的的確是”object”,![]也的確是返回false的。那么看下面這段代碼

var arr = [];

if(arr == true){

    alert(1);

}

這個alert(1)會不會執行呢?

答案是不會。為什么呢?因為“==”運算符會轉換數據的類型,以盡量保證他們倆相同,這個在JavaScript里有一套完整的轉換類型的規則[詳情請點擊此處]。數組並不是通過兩個非運算符轉換它,而是通過“+”來轉換,而+[]是0。然后就會變成 0==true,0又可以轉換為false,所以這里的alert(1)不會執行。

如果這里改成if(!!arr == true),則alert(1)會執行。

 

 

四、習題

來看一道習題,看看上面的這些你是否都融會貫通。

下面這段模擬代碼有一個很嚴重的bug,不知道你能不能看出來

function foo(){
    
    var rep = ajaxGet("/xxx.do");
    
    //如果后台成功返回了type
    if(rep.type){
        //打印信息
        console.info(rep.message);
    }
    
}

//模擬網絡請求(不考慮異步)
function ajaxGet(){
    
    return {
        //類型 -1 ~ 3
        type: 3,
        //請求信息
        message: "請求成功"
    }
    
}

自己想3分鍾,如果想不出來,就去評論區看答案吧。

 

 

 


 

參考文獻

《JavaScript權威指南》第五版

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM