第四章、表示式和運算子
原始表示式(primary expression),包括常量或直接量,關鍵字和保留字
1.直接量
1.23 //數字直接量
"hello" //字串直接量
/pattern/ //正規表示式直接量複製程式碼
2.保留字
true //返回一個布林值:真
false //返回一個布林值:假
null //返回一個值:空
this //返回"當前"物件複製程式碼
3.變數
i //返回變數i的值
sum //返回sum的值
undefined //undefined是全域性變數,和null不同,他不是一個關鍵字複製程式碼
物件和陣列的初始化表示式
1.陣列初始化表示式
[] //一個空陣列:[]內留空即表示該陣列沒有任何元素
[1+2,3+4] //擁有兩個元素的陣列,第一個是3,第二個是7
var mamtrix = [[1,2,3],[4,5,6],[7,8,9]] //巢狀
var sparseArray = [1,,,,5]; //省略的空位會填充值undefined複製程式碼
2.物件初始化表示式
var p = {x:2.3,y:-1.2}; //一個擁有兩個屬性成員的物件
var q={}; //一個空物件
q.x = 2.3; q.y = 1.2; //q的屬性成員和p的一樣
var rectangle ={
upperLeft:{x:2,y:2},
lowerRight:{x:4,y:5}
} //巢狀複製程式碼
函式定義表示式
var square = function(x){return x*x} //這個函式返回傳人蔘數值的平方複製程式碼
屬性訪問表示式
屬性訪問表示式運算得到一個物件屬性或一個陣列元素的值
expression.identifier //表示式指定物件,識別符號則指定需要訪問的屬性的名稱
expression[expression] //表示式指定要訪問的屬性的名稱或者代表要訪問陣列元素的索引複製程式碼
eg:
var o = {x:1,y:{z:3}}; //一個示例物件
var a = [0,4,[5,6]]; //一個包含這個物件的示例陣列
o.x //=>1:表示式o的x屬性
o.y.z //=>3:表示式o.y的z屬性
o["x"] //=>1:物件o的x屬性
a[1] //=>4:表示式a中索引為1的元素
a[2]["1"] //=>6:表示式a[2]中索引為1的元素
a[0].x //=>1:表示式a[0]的x屬性複製程式碼
物件建立表示式
new Object();
new Point(2,3);複製程式碼
運算子概述
1.運算元的個數
一元運算子
二元運算子
三元運算子
2.運算元型別和結果型別
3.左值
4.運算子的副作用
5.運算子優先順序
6.運算子的結合性
7.運算順序
算術表示式
1."+"運算子
(1).加法
(2).字串連線
1 + 2 //=>3:加法
"hello" +" "+ "world" //=>"hello world":字串連線
"1" + 2 //=>"12":數字轉換為字串後進行字串連線
1 + {} //=>"1[object object]":物件轉換為字串後進行字串連線
true + true //=>2:布林值轉換為數字後做加法
2 + null //=>2:null轉換為0後做加法
2 + undefined //=>NaN:undefined轉換為NaN後做加法
1 + 2 + " blind mice"; //=>"3 blind mice"
1 + (2 + " blind mice") //=>"12 blind mice"複製程式碼
(3)."+"運算子具有從左至右的結合性
2.一元算術運算子
(1).一元加法(+)
(2).一元減法(-)
(3).遞增(++)
前增量
var i=1,j=++i //i和j的值都是2複製程式碼
後增量
var i=1,j=i++ //i是2,j是1複製程式碼
(4).遞減(--)
3.位運算子
-----2017.6.26--------
(1).位運算子要求它的運算元是整數
(2).位運算子會將NaN、Infinity和-Infinity都轉換為0
(3).按位與(&)
只有兩個運算元中相對應的位都是1,結果中的這一位才是1
(4).按位或(|)
如果其中一個運算元相應的位為1,或者兩個運算元相應位都是1,那麼結果中的這一位就是1
(5).按位異或(^)
異或是指第一個運算元為true或第二個運算元為true,但兩者不能同時為true。如果兩個運算元中只有一個相應位為1(不能同時為1),那麼結果中的這一位就是1。
(6).按位非(~)
(7).左移(<<)
(8).帶符號右移(>>)
(9).無符號右移(>>>)
關係表示式
關係表示式總是返回一個布林值
1.相等和不等運算子
(1)."=" //=>得到或賦值
(2)."==" //=>相等,定義非常寬鬆,可以允許進行型別轉換
(3)."===" //=>恆等,嚴格相等
(4)."!=" //=>不相等
(5)."!==" //=>不嚴格相等
2.比較運算子
比較運算子用來檢測兩個運算元的大小關係(數值大小或者字母表的順序)
(1).小於(<)
(2).大於(>)
(3).小於等於(<=)
(4).大於等於(>=)
加號運算子中一個運算元是字串的話,則進行字串連線操作。比較運算子只有在兩個運算元都是字串的時候,才會進行字串的比較。
1 + 2 //=>3:加法
"1" + "2" //=>12:字串連線
"1" + 2 //=>12:字串連線,2轉換為"2"
11 < 3 //=>false:數字的比較
"11" < "3" //=>true:字串的比較
"11" < 3 //=>false:數字的比較,"11"轉換為11
"one" < 3 //=>false:數字的比較,"one"轉換為NaN複製程式碼
3.in運算子
in運算子希望它的左操作符是一個字串或可以轉換為字串,希望它的右操作符是一個物件。如果右側的物件擁有一個名為左運算元值的屬性名,那麼表示式返回true
var point = {x:1,y:1}; //定義一個物件
"x" in point //=>true:物件有一個名為"x"的屬性
"z" in point //=>false:物件中不存在名為"z"的屬性
"toString" in point //=>true:物件繼承了toString()的方法
var data = [7,8,9]; //擁有三個元素的陣列
"0" in data //=>true:陣列包含元素"0"
1 in data //=>true:數字轉換為字串
3 in data //=>false:沒有索引為3的元素複製程式碼
4.instanceof運算子
instanceof運算子希望左運算元是一個物件,右運算元標識物件的類。如果左側的物件是右側類的例項,則表示式返回true,否則返回false
var d = new Date(); //通過Date()建構函式來建立一個新物件
d instanceof Date; //=>true:d是由Date()建立的
d instanceof Object; //=>true:所有的物件都是Object的例項
d instanceof Number; //=>false:d不是一個Number物件
var a = [1,2,3]; //通過陣列直接量的寫法建立一個陣列
a instanceof Array; //=>true:a是一個陣列
a instanceof Object; //=>true:所有的陣列都是物件
a instanceof RegExp; //=>false:陣列不是正規表示式複製程式碼
所有的物件都是Object的例項
邏輯表示式
---------2017.6.27---------
1.邏輯與(&&) =>AND
(1)."&&"運算子可以從三個不同的層次進行理解
A.第一層:當運算元都是布林值的時候,並且兩個都為true,它才返回true
x == 0 && y == 0 //只有在x和y都是0的時候,才返回true複製程式碼
關係運算子的優先順序比"&&"(和"||")要高,因此類似這種表示式可以放心地書寫,而不用補充圓括號
B.第二層:但並沒有說明這個"真值"或者"假值"到底是什麼值。
C.第三層:會先根據左運算元的值進行計算,若為假,就為假;若為真,根據右運算元的值進行計算。
var o ={x:1};
var p = null;
o && o.x //=>1:o是真值,因此返回值為o.x
p && p.x //=>null:p是假值,因此將其返回,而不去計算p.x複製程式碼
(2)."&&"的行為有時稱做"短路"(shot circuiting)
if(a == b){
stop() //只有在a == b的時候才呼叫stop()
}
(a == b) && stop(); //同上複製程式碼
2.邏輯或(||) =>OR
-------2017.6.28----------
"||"運算子對兩個運算元做布林或(OR)運算。如果其中一個或者兩個運算元是真值,它返回一個真值。如果兩個運算元都是假值,它返回一個假值。
var max = max_width || preferences.max_width || 500;
//如果max_width已經定義了,直接使用它,否則在preferences物件中查詢max_width
//如果沒有定義它,則使用一個寫死的常量
//將o的成員屬性複製到p中,並返回p
function copy(o,p){
p = p || {}; //如果向引數p沒有傳人任何物件,則使用一個新建立的物件
//函式體內的主邏輯
}複製程式碼
3.邏輯非(!)
"|"運算子是一元運算子。它放置在一個單獨的運算元之前。它的目的是將運算元的布林值進行求反。
//對於p和q取任意值,這兩個等式都永遠成立
!(p && q) === !p || !q
!(p || q) === !p && !q複製程式碼
賦值表示式
1.JavaScript使用"="運算子來給變數或者屬性賦值
i = 0; //將變數i設定為0
o.x = 1; //將物件o的屬性x設定為1
(a = b) == 0; //"="具有非常低的優先順序,需要補充圓括號以保證正確的運算順序複製程式碼
2.賦值操作符的結合性是從右至左,運算順序是從右到左
i = j = k = 0; //把三個變數初始化為0複製程式碼
3.帶操作的賦值運算
運算子"+="執行的是加法運算和賦值操作
total += sales_tax
total = total + sales_tax複製程式碼
4.如果其運算元是數字,它將執行加法運算和賦值操作;如果其運算元是字串,它將執行字串連線操作和賦值操作;
表示式計算
1.JavaScript通過全域性函式eval()解釋執行由JavaScript原始碼組成的字串,併產生一個值。
eval("3+2") //=>5複製程式碼
2.eval()是一個函式還是一個運算子
(1).eval()只有一個引數。如果傳人的引數不是字串,它直接返回這個引數。如果引數是字串,它會把字串當成JavaScript程式碼進行編譯。
(2).它使用了呼叫它的變數作用域環境。也就是說,它查詢變數的值和定義新變數和函式的操作和區域性作用域中的程式碼完全一樣。
eval("function f(){ return x+1; }") //宣告一個區域性函式複製程式碼
(3).全域性eval()
var geval = eval; //使用別名呼叫eval將是全域性eval
var x = "global",y = "global"; //兩個全域性變數
function f(){ //函式內執行的是區域性eval
var x = "local"; //定義區域性變數
eval("x += 'changed'"); //直接eval更改了區域性變數的值
return x; //返回更改後的區域性變數
}
function g(){ //這個函式內執行了全域性eval
var y = "local"; //定義區域性變數
geval("y += 'changed'"); //間接呼叫改變了全域性變數的值
return y; //返回未更改的區域性變數
}
console.log(f(),x); //localchanged global
console.log(g(),y); //local globalchanged複製程式碼
-----------2017.7.11---------
(4).嚴格eval()
在嚴格模式下,eval執行的程式碼段可以查詢或更改區域性變數,但不能在區域性作用域中定義新的變數或函式
其他運算子
1.條件運算子(?:)
(1).條件運算子是JavaScript中唯一的一個三元運算子(三個運算元)
x > 0 ? x : -x複製程式碼
第一個運算元當成布林值,如果它是真值,那麼將計算第二個運算元,並返回其計算結果。
否則,如果第一個運算元是假值,那麼將計算第三個運算元,並返回其計算結果。
第二個和第三個運算元總是會計算其中之一,不可能兩者同時執行。
greeting = "hello" + (username ? username : "three");
greeting = "hello";
if(username){
greeting += username;
}else{
greeting += "three";
}複製程式碼
2.typeof運算子
(1).typeof是一元運算子,放在其單個運算元的前面,運算元可以是任意型別。返回值為表示運算元型別的一個字串。
(typeof value == "string") ? "'" + value + "'" : value;複製程式碼
3.delete運算子
(1).delete是一元運算子,它用來刪除物件屬性或者陣列元素。
(2).它是用來做刪除操作的,不是用來返回一個值的
var o = {x : 1, y : 2}; //定義一個物件
delete o.x; //刪除一個屬性
"x" in 0 ; //=>false:這個屬性在物件中不再存在
var a = [1,2,3]; //定義一個陣列
delete a[2]; //刪除最後一個陣列元素
2 in a; //=>false:元素2在陣列中已經不存在了
a.length; //=>3:陣列長度並沒有改變,儘管上一行程式碼刪除了這個元素。
var o ={x:1,y:2}; //定義一個變數,初始化為物件
delete o.x; //刪除一個物件屬性,返回true
typeof o.x; //屬性不存在,返回"undefined"
delete o.x; //刪除不存在的屬性,返回true
delete o ; //不能刪除通過var宣告的變數,返回false;在嚴格模式下,將丟擲一個異常
delete 1; //引數不是一個左值,返回true
this.x = 1; //給全域性物件定義一個屬性,這裡沒有使用var
delete x; //試圖刪除它,在非嚴格模式下返回true;在嚴格模式下會丟擲異常,這時使用"delete this.x"來替代
x; //執行時錯誤,沒有定義x複製程式碼
4.void運算子
(1).void是一元運算子,它出現在運算元之前,運算元可以是任意型別。
運算元會照常計算,但忽略計算結果並返回undefined
<a href="javascript:void window.open();">開啟一個新視窗</a>複製程式碼
5.逗號運算子
(1).逗號運算子是二元運算子,它的運算元可以是任意型別。
它首先計算左運算元,然後計算右運算元,最後返回右運算元的值
i = 0, j = 1, k = 2; //=>2
i = 0; j = 1; k = 2;複製程式碼
總是會計算左側的表示式,但計算結果忽略掉
//for迴圈中的第一個逗號是var語句的一部分
//第二個逗號是逗號運算子
//它將兩個表示式(i++和j--)放在一條(for迴圈中的)語句中
for(var i=0,j=10;i<j;i++,j--){
console.log(i+j);
}複製程式碼
|版權宣告:本文為summer博主原創文章,未經博主允許不得轉載。