1.原始表達式
常量或直接量:
2.1//數字直接量
"hello"http://字符串直接量
/pattern/ //正則表達式直接量
保留字:
true ,false ,null ,this
在一個方法體內,this返回調用這個方法的對象。
變量:
i //返回變量i的值
sum //返回sum的值
undefined //undefined是一個全局變量,和null不同,他不是關鍵字
2.對象和數組初始化表達式
數組初始化方式:
[];
[1,2];
var x= [[1,2],[1,1],[3,3]];
var x=[1,,,5];//其中未填數字部分是undefined
對象初始化方式:
var p ={x:2 ,y:2}//一個擁有兩個屬性成員的對象
var q={} //一個空對象
a.x=2;a.y=2 //a的屬性成員和p一樣
花括號內可以是JavaScript表達式
var pp ={upperleft:{a:1,q;1},Lowerright:{a:1,q;1}};
3.函數定義表達式
定義函數的方法:
var square = function(x){return x *x;}
4.屬性訪問表達式
屬性訪問表達式運算得到一個對象的屬性或者數組的值。語法如下
expression.identifier
expression[ expression ]
var o ={x:1,y:{z:3}};
var a=[o,4,[5,6]];
o.x //1
o.y.z; //3
o["x"];//1
a[2]["1"];//6
a[0].x;//1
5.調用表達式
指的是調用(執行)函數或方法的語法表達式,以函數表達式開始,隨后跟隨一對圓括號,調用方式如下:
f(o) //是函數表達式,o是參數表達式
Math.max(x,y,z);//Math.max是函數,x y z 是參數
a.sort() //a.sort 是函數,沒有參數
6.對象創建表達式
創建一個對象并調用一個函數(這個函數稱作構造函數)初始化新對象的屬性。
new object()
new object(2,2)
如果不用給任何參數給構造函數的話,可以省略()
7.運算符
+-*/是一元運算符,“?:”是三元運算符。a?b:c(a是否為真,為真則執行b,否則執行c)
圖中出現了lval類型,他們是左值,是指 表達式只能出現在賦值運算符的左側
8.運算符副作用:
1.用===,而不用==
JavaScript有兩組相等運算符:===和!==、==和!=。===和!==這一組運算符會按照期望的方式工作。如果兩個運算數類型一致且擁有相同的值,那么===返回true,而!==返回false。==和!=只有在兩個運算數類型一致時才會做出正確的判斷,如果兩個運算數是不同的類型,會試圖強制轉換運算數的類型。轉換的規則復雜且難以記憶,具體規則如下:
'' == '0' // false
0 == '' // true
0 == '0' // true
false == 'false' // false
false == '0' // true
false == undefined // false
false == null // false
null == undefined // true
上面表達式如果全部使用===運算符,則都會返回true。
==和!=運算符缺乏傳遞性,需要引起警惕。所謂傳遞性就是:如果a==b為true,b==c為true,則a==c也為true。因此,在JavaScript開發中,建議永遠不要使用==和!=,而選用===和!==運算符。
下面分別介紹一下===和==運算符的算法。
(1)===運算符的算法
在使用===來判斷兩個值是否相等時,如判斷x===y,會先比較兩個值的類型是否相同,如果不相同,直接返回false。如果兩個值的類型相同,則接著根據x的類型展開不同的判斷邏輯:
如果x的類型是Undefined或Null,則返回 true。
如果x的類型是Number,只要x 或y中有一個值為NaN,就返回 false;如果x和y的數字值相等,就返回 true;如果x或y中有一個是+0,另外一個是–0,則返回 true。
如果x的類型是String,當x和y的字符序列完全相同時返回 true,否則返回 false。
如果x的類型是Boolean,當x和y同為true或false時返回 true,否則返回 false。
當x和y引用相同的對象時返回 true,否則返回 false。
(2)==運算符的算法
在使用==來判斷兩個值是否相等時,如判斷x==y,如果x和y的類型一樣,判斷邏輯與=== 一樣;如果x和y的類型不一樣,==不是簡單地返回false,而是會進行一定的類型轉換。
如果x和y中有一個是 null,另外一個是undefined,返回true,如null == undefined。
如果x和y中有一個類型是String,另外一個類型是Number,會將String類型的值轉換成 Number來比較,如3 == "3"。
如果x和y中有一個類型是Boolean,會將Boolean類型的值轉換成Number來比較,如true == 1、true == "1"。
如果x和y中有一個類型是String或Number,另外一個類型是Object,會將Object類型的值轉換成基本類型來比較,如[3,4] == "3,4"。
2.謹慎使用++和--
遞增(++)和遞減(--)運算符使程序員可以用非常簡潔的風格去編碼,如在C語言中,它們使得通過一行代碼實現字符串的復制成為可能,例如:
for (p = src, q = dest; !*p; p++, q++) *q = *p;
事實上,這兩個運算符容易形成一種不謹慎的編程風格。大多數的緩沖區溢出錯誤所造成的安全漏洞都是由于這種編碼導致的。
當使用++和--時,代碼往往變得過于緊密、復雜和隱晦。因此,在JavaScript程序設計中不建議使用它們,從而使代碼風格變得更為整潔。
++和--運算符只能夠作用于變量、數組元素或對象屬性。下面的用法是錯誤的。4++;
正確的用法如下:var n = 4;n++;
++和--運算符的位置不同所得運算結果也不同。例如,下面的遞增運算符是先執行賦值運算,然后再執行遞加運算。var n = 4;n++; // 4
而下面的遞增運算符是先執行遞加運算,再進行賦值運算。var n = 4;++n;
3.小心逗號運算符
逗號在JavaScript語言中表示連續運算,并返回最后運算的結果。例如,在下面這個示例中,JavaScript先運算第一個數值直接量,再運算第二個數值直接量,然后運算第三個數值直接量,最后運算第四個數值直接量,并返回最后一個運算值4。
var a = ( 1, 2, 3, 4);
alert(a); //4
再如:
a = 1, b = 2, c = 3;
等價于:
a = 1;
b = 2;
c = 3;
作為運算符,逗號一般用在特殊環境中,即在只允許出現一個句子的地方,把幾個不同的表達式句子合并成一個長句。在JavaScript實際開發中,逗號運算符常與for循環語句聯合使用。例如,在下面這個簡單的for循環結構中,通過連續的運算符在參數表達式中運算多個表達式,以實現傳遞或運算多個變量或表達式。
for(var a = 10 , b = 0; a > b; a++ , b+=2){
document.write("a = " + a +" b = " + b + "
");
}
逗號運算符比較“怪異”,稍不留心就會出錯。例如,在下面這個簡單的示例中,變量a的返回值為1,而不是連續運算后的返回值4。
a = 1, 2, 3, 4;
alert(a); //1
第一個數值1先賦值給變量a,然后a再參與連續運算,整個句子的返回值為4,而變量a的返回值為1,代碼演示如下:
alert((a = 1, 2, 3, 4)); //4
alert(a = (1, 2, 3, 4)); //4
要確保變量a的值為連續運算,可以使用小括號邏輯分隔符強迫4個數值先進行連續運算,然后再賦值。
a = (1, 2, 3, 4);
alert(a); //4
當使用var關鍵字來定義變量時,會發現a最終沒有返回值。
var a = 1, 2, 3, 4;
alert(a); //null
要確保var聲明的變量正確返回連續運算的值,需要使用小括號先強迫數值進行計算,最后再把連續運算的值賦值給變量a。
var a = (1, 2, 3, 4);
alert(a); //4
4.警惕運算符的副作用
JavaScript運算符一般不會對運算數本身產生影響,如算術運算符、比較運算符、條件運算符、取逆、“位與”等。例如,a = b + c,其中的運算數b和c不會因為加法運算而導致自身的值發生變化。
但在JavaScript中還有一些運算符能夠改變運算數自身的值,如賦值、遞增、遞減運算等。由于這類運算符自身的值會發生變化,在使用時會具有一定的副作用,特別是在復雜表達式中,這種副作用更加明顯,因此在使用時應該時刻保持警惕。例如,在下面代碼中,變量a經過賦值運算和遞加運算后,其值發生了兩次變化。
var a;
a = 0;
a++;
alert(a); //1
再如:
var a;
a = 1;
a = (a++)+(++a)-(a++)-(++a);
alert(a); //-4
如果直觀地去判斷,會錯誤地認為返回值為0,實際上變量a在參與運算的過程中,變量a的值是不斷發生變化的。這種變化很容易被誤解。為了方便理解,進一步拆解(a++)+(++a)–(a++)–(++a)表達式:
var a;
a = 1;
b = a++;
c = ++a;
d = a++;
e = ++a;
alert(b+c-d-e); //-4
如果表達式中還包含其他能夠引起自身值發生變化的運算,那么整個表達式的邏輯就無法用人的直觀思維來描述了。因此,從代碼可讀性角度來考量:在一個表達式中不能夠對相同操作數執行兩次或多次引起自身值變化的運算,除非表達式必須這樣執行,否則應該避免產生歧義。這種歧義在不同編譯器中會產生完全不同的解析結果。例如,下面的代碼雖然看起來讓人頭疼,但由于每個運算數僅執行了一次引起自身值變化的運算,所以不會產生歧義。
a = (b++)+(++c)-(d++)-(++e);
9.運算符優先級
w=(x+y)x //括號內優先
w=x+yz //*比+優先
10.運算符結合性
w=x-y-z;
w=((x-y)-z);這兩個相同的
11.運算順序
自左向右
12.關系表達式
= 賦值 == 相等 ===恒等
!=不相等 !==不嚴格相等
<小于 >大于 <= >=
1+2 //3
"1" + "2" //12
"12" < 3 //"12"轉換成12 false
12 <3 //false