javascript —— 運算符

算術運算符

javascript中的算術操做主要經過算術運算符來實現,算術運算符包括一元算術運算符和二元算術運算符兩種。javascript

一元算術運算符

一元算術運算符用於一個單獨的操做數,併產生一個新值。在javascript中,一元運算符具備很高的優先級,並且都是右結合(right-associative)java

一元算術運算符包括一元加法(+)、一元減法(-)、遞增(++)和遞減(--)

一元加(+)

一元加運算符以一個加號(+)表示,放在數值前面,對數值不會產生任何影響express

var num = 25;
num = +num; //25

在對非數值應用一元加運算符時,會調用Number()轉型函數對這個值進行轉換數組

var s1 = '01';
var s2 = '1.1';
var s3 = 'z';
var b = false;
var f = 1.1;
var o = {
    valueOf:function(){
        return -1;
    }
};

s1 = +s1;//1
s2 = +s2;//1.1
s3 = +s3;//NaN
b = +b;//0
f = +f;//1.1
o = +o;//-1

在new Date()前面使用一元加符號,能夠把日期字符串,轉換爲日期毫秒數函數

console.log(new Date());//on Jul 11 2016 20:25:54 GMT+0800 (中國標準時間)
console.log(+new Date());//1468239954076

一元減(-)

一元減運算符主要用於表示負數post

var num = 25;
num = -num;//-25

當一元減運算符用於非數值時,會對該值使用Number()轉型函數進行轉換,再將獲得的數值轉換成負數測試

var s1 = '01';
var s2 = '1.1';
var s3 = 'z';
var b = false;
var f = 1.1;
var o = {
    valueOf:function(){
        return -1;
    }
};

s1 = -s1;//-1
s2 = -s2;//-1.1
s3 = -s3;//NaN
b = -b;//0
f = -f;//-1.1
o = -o;//1
一元加和一元減運算符主要用於基本的算術運算,也能夠用於轉換數據類型

遞增(++)

遞增++運算符對其操做數進行增量(加1)操做,操做數是一個左值(lvalue)(變量、數組元素或對象屬性)。運算符經過Number()轉型函數將操做數轉換爲數字,而後給數字加1,並將加1後的數值從新賦值給變量、數字元素或者對象屬性設計

var age = 29;
++age;
//至關於
var age = 29;
age = age +1;
遞增++運算符的返回值依賴於它相對於操做數的位置。當運算符在操做數以前,稱爲前增量(pre-increment)運算符,它對操做數進行增量計算,並返回計算後的值。當運算符在操做數以後,稱爲後增量(post-increment)運算符,它對操做數進行增量計算,但返回未作增量計算的(unincremented)值
var i = 1, j = ++i;
//i=2 j=2

var i = 1, j = i++;
//i=2 j=1

遞減(--)

遞減--運算符的操做數也是一個左值,它經過Number()轉型函數把操做數轉換爲數字,而後減1,並將計算後的值從新賦值給操做數code

和遞增++運算符同樣,遞減--運算符的返回值依賴於它相對操做數的位置,當遞減運算符在操做數以前,操做數減1並返回減1以後的值。當遞減運算符在操做數以後,操做數減1並返回減1以前的值對象

var age = 29;
--age;
//至關於
var age = 29;
age = age - 1;
前增量操做符與執行語句優先級相同,整個語句會從左向右求值
var num1 = 2;
var num2 = 20;
var num3 = --num1 + num2;//21
var num4 = num1 + num2;//21
後增量操做符在包含它們的語句被求值以後才執行
var num1 = 2;
var num2 = 20;
var num3 = num1-- + num2;//22
var num4 = num1 + num2;//21

二元算術運算符

二元算術運算符包括加法(+)、減法(-)、乘法(*)、除法(/)和求餘(%)

加法(+)

在多數程序設計語言中,加法一般是簡單的數字運算符,但在ECMAScript中,加法運算有大量的特殊行爲,不只能夠進行數值加法運算,也能夠進行字符串鏈接

【1】若是其中一個操做數是對象,則對象會轉換爲原始值:日期對象經過toString()方法執行轉換,其餘對象經過valueOf()方法執行轉換。因爲多數對象valueOf()方法沒法返回一個原始值,因而會經過toString()方法來執行轉換

[注意]除了單數值數組會轉換爲數字外,其餘原生對象都會經過toString()方法轉換爲字符串形式

【2】在進行了對象到原始值的轉換後,若是其中一個操做數是字符串的話,另外一個操做數也會轉換成字符串,進行字符串鏈接,不然,兩個操做數都將轉換成數字或NaN,進行加法操做

//單數值數組和valueOf()返回值爲數值的自定義對象會轉換爲數值
console.log(1 + []);//1
var o = {
    valueOf: function(){
        return -1;
    }
}
console.log(1 + o);//0
//其餘原生對象則轉換爲字符串
console.log(1 + {});//'1[object Object]'
console.log(1 + [1,2]);//'11,2'
console.log(1 + new Date());//'1Thu Jun 16 2016 10:27:13 GMT+0800 (中國標準時間)'
console.log(1 + /0/);//'1/0/'

若是進行算術加法運算,undefined轉換爲NaN,null轉換爲0,false轉換爲0,true轉換爲1

console.log('' + undefined);//'undefined'
console.log('' + null);//'null'
console.log('' + false);//'false'
console.log('' + true);//'true'

所以,利用加號運算符的特性,能夠利用''+任意類型值轉換爲字符串

減法(-)

相對於加法,減法就簡單的多,只涉及到數字的減法運算。使用Number()轉型函數將非數值類型轉換爲數值或NaN

console.log(1 - {});//NaN
console.log(1 - [1,2]);//NaN
console.log(1 - /0/);//NaN
console.log(1 - []);//1
加法有一個特殊之處,在於時間Date對象進行加法運算時使用toString()轉換爲字符串,而在其餘數學運算,包括減法、乘法、除法、求餘等運算中,都是使用Number()轉換函數將時間Date對象使用valueOf()轉換爲數字
console.log(new Date() + 1);//'Thu Jun 16 2016 11:11:49 GMT+0800 (中國標準時間)1'
console.log(new Date() - 1);//1466046941641

undefined轉換爲NaN,null轉換爲0,false轉換爲0,true轉換爲1

console.log(1 - undefined);//NaN
console.log(1 - null);//1
console.log(1 - false);//1
console.log(1 - true);//0

乘法(*)

乘法操做符由一個星號(*)表示,用於計算兩個數值的乘積,會經過Number()轉型函數將非數值類型轉換爲數值或NaN

+ Infinity * 0;//NaN
- Infinity * 0;//NaN
Infinity * 非0數值;//Infinity或-Infinity
Infinity * Infinity;//Infinity

除法(/)

除法操做符由一個斜線(/)表示,執行第一個操做數除以第二個操做數的運算,也會經過Number()轉型函數將非數值類型轉換爲數值或NaN

Infinity / Infinity;//NaN
0 / 0;//NaN
非0數值 / 0;//Infinity或-Infinity
Infinity / 0;//Infinity
Infinity / 非0數值;//Infinity

求模(%)

求模(餘數)操做符是由一個百分號(%)表示,是第一個操做數除以第二個操做數的餘數

//r是餘數,n是被除數,d是除數,
//q是整數,在n/d爲負時爲負,在n/d爲正時爲正,它應該在不超過n和d的商的前提下儘量大
r = n - (d * q)

求模結果與第一個操做數的符號保持一致

console.log(5 % 2);//1
console.log(5 % -2);//1
console.log(-5 % 2);//-1
console.log(-5 % -2);//-1

關係運算符

關係運算符用於測試兩個值之間的關係,根據關係是否存在而返回true或false,關係表達式老是返回一個布爾值,一般在if、while或for語句中使用關係表達式,用以控制程序的執行流程

javascript提供了===、!==、==、!=、<、<=、>、>=8個關係運算符,分爲4類介紹關係運算符

恆等運算符

恆等運算符'===',也叫嚴格相等運算符,首先計算其操做數的值,而後比較這兩個值,比較過程沒有任何類型轉換,比較過程以下:

【1】若是兩個值的類型不相同,則返回false

console.log(1 === '1');//false
console.log(1 === [1]);//false

【2】若是兩個值都是Undefined、Null、Boolean、Number、String相同原始類型的值,值相同,就返回true,不然,返回false

console.log(undefined === undefined);//true
console.log(null === null);//true
console.log(true === true);//true
console.log(false === false);//true
console.log(1 === 1);//true
console.log(2.5 === 2.5);//true

[注意]不論什麼進制的數字,在進行關係比較時,最終都轉換爲十進制進行運算

console.log(10 === 0xa);//true

在數字Number類型中,有一個值比較特殊,是NaN(not a number),它與任何值都不相等;此外,數字Number類型中存在着+0和-0,雖然其符號不一樣,但值相等

console.log(NaN === NaN);//false
console.log(+0 === -0);//true

兩個相同字符串值表現爲:相同的長度和相同的字符對應相同的位置

console.log('abc' === 'abc');//true
console.log('abc' === 'acb');//false

【3】若是兩個值引用同一個對象,則返回true,不然,返回false

[注意]更詳細的解釋是,javascript對象的比較是引用的比較,而不是值的比較。對象和其自己是相等的,但和其餘任何對象都不相等。若是兩個不一樣的對象具備相同數量的屬性,相同的屬性名和值,它們依然是不相等的

console.log([] === []);//false
console.log({} === {});//false    
console.log(function(){} === function(){});//false
var a = {};
b = a;
console.log(a === b);//true

恆不等運算符(!==)又叫嚴格不等於運算符,操做數的比較過程與恆等運算符相同,結果取反。若是'==='的比較結果是true,則'!=='的比較結果是false;若是'==='的比較結果是false,則'!=='的比較結果是true

console.log(1 !== '1');//true
console.log(1 !== 1);//false
console.log(true !== false);//true
console.log({} !== {});//true

相等運算符

相等運算符'=='和恆等運算符類似,但相等運算符的比較並不嚴格,若是兩個操做數不是同一類型,相等運算符會嘗試進行一些類型轉換,而後再進行比較

當兩個操做數類型相同時,比較規則和恆等運算符規則相同

console.log(undefined == undefined);//true
console.log(10 == 0xa);//true
console.log(NaN == NaN);//false
console.log([] == []);//false

當兩個操做數類型不一樣時,相等運算符'=='會遵照以下規則:

【1】若是一個值是對象類型,另外一值是原始類型,則對象類型會先使用valueOf()轉換成原始值,若是結果還不是原始值,則再使用toString()方法轉換,再進行比較

[注意]日期類只容許使用toString()方法轉換爲字符串。相似地,時間Date對象進行加法運算時使用toString()轉換爲字符串,而在其餘數學運算,包括減法、乘法、除法、求餘等運算中,都是使用Number()轉換函數將時間Date對象使用valueOf()轉換爲數字

【2】在對象轉換爲原始值以後,若是兩個操做數都是字符串,則進行字符串的比較

console.log(new Date() == 'Sat Jun 25 2016 11:07:20 GMT+0800 (中國標準時間)');//true

【3】在對象轉換爲原始值以後,若是至少有一個操做數不是字符串,則兩個操做數都將經過Number()轉型函數轉換成數字進行數值比較

console.log(true == 1);//true
console.log(true == 0);//false
console.log(false == '1');//false
console.log(false == '0');//true
console.log(true == 'true');//false,至關於1 == NaN

console.log([1] == 1);//true,至關於1 == 1
console.log([1] == '1');//true,至關於'1' == '1'
console.log([] == 0);//true,至關於0 == 0
console.log([] == '0');//false,至關於'' == '0'

console.log([] == true);//false,至關於0 == 1
console.log([1] == true);//true,至關於1 == 1
var a = {
    valueOf:function(){
        return 1;
    },
    toString:function(){
        return '2';
    }
} 
console.log( a == '1');//true,至關於1 == 1

var a = {
    valueOf:function(){
        return {};
    },
    toString:function(){
        return '1';
    }
} 
console.log( a == 1);//true,至關於1 == 1

[注意]若是一個值是null,另外一個值是undefined,則返回true。雖然Number(null)是0,但null和0並不相等

console.log(null == undefined);//true
console.log(null == 0);//false

[注意]空字符串或空格字符串會轉成0

console.log(null == []);//false
console.log(null == '');//false
console.log([] == ' ');//false,至關於'' == ' '
console.log([] == '');//true,至關於'' == ''
console.log(0 == '');//true

不相等運算符(!=)的操做數比較過程與相等運算符相同,結果取反。若是'=='的比較結果是true,則'!='的比較結果是false;若是'=='的比較結果是false,則'!='的比較結果是true

console.log(1 != '1');//false,至關於1 != 1
console.log(true != '1');//false,至關於1 != 1
console.log('true' != 1);//true,至關於NaN != 1
console.log([1] != '1');//false,至關於'1' != '1'
console.log([1] != true);//false,至關於1 != 1

大於運算符

大於運算符(>)用於比較兩個操做數,若是第一個操做數大於第二個操做數,則大於運算符的計算結果爲true,不然爲false

大於運算符的操做數多是任意類型,然而,只有數字和字符串才能真正執行比較操做,所以那些不是數字和字符串的操做數都將進行類型轉換,類型轉換規則以下:

【1】若是操做數是對象,則這個對象將先使用valueOf()轉換成原始值,若是結果還不是原始值,則再使用toString()方法轉換

[注意]實際上,在原生對象中,使用valueOf()方法轉換爲原始值的,只有轉換爲數字Number類型的時間Date對象,其餘對象都經過toString()方法轉換爲字符串

【2】在對象轉換爲原始值以後,若是兩個操做數都是字符串,則按照字母表的順序對兩個字符串進行比較,這裏提到的字母表順序是指組成這個字符串的16位unicode字符的索引順序

console.log('b' > 'a');//true
console.log('B' > 'a');//false

console.log({} > '[a]');//true,至關於'[object Object]' > '[a]'
console.log({} > '[p]');//false,至關於'[object Object]' > '[p]'

console.log(['a'] > ['b']);//false,至關於'a' > 'b'
console.log([2] > [11]);//true,至關於'2' > '11'

【3】在對象轉換爲原始值以後,若是至少有一個操做數不是字符串,則兩個操做數都轉換成數字進行比較

[注意]在等於操做符中,時間Date()對象只容許經過toString()方法轉換爲字符串,而不容許經過valueOf()方法轉換爲數字;而在大於操做符中,時間Date()對象容許優先使用valueOf()方法轉換爲數字

console.log(new Date() > 100);//true,至關於1466826928667 > 100
console.log(true > [0]);//true,至關於 1 > 0

console.log(2 > 1);//true
console.log(11 > '2');//true,至關於11 > 2

console.log(NaN > 1);//false
console.log(1 > NaN);//false
console.log({} > true);//false,至關於 NaN > 1

對於數字和字符串來講,加號運算符和比較運算符的行爲有所不一樣,加號運算符更偏心字符串,若是它的一個操做數是字符串,就進行字符串鏈接。而比較運算符則更偏心數字,只有在兩個操做數都是字符串時,才進行字符串的比較

console.log(1 + 2);//3
console.log('1' + '2');//'12'
console.log('1' + 2);//'12',至關於 '1' + '2'

console.log(2 > 1);//true
console.log('2' > '1');//true
console.log('2' > 1);//true,至關於 2 > 1

小於等於運算符(<=)並不依賴於小於或等於運算符的比較規則,而是遵循大於運算符的比較規則,結果取反。若是'>'的比較結果是true,則'<='的比較結果是false;若是'>'的比較結果是false,則'<='的比較結果是true

console.log(1 <= '0');//false,至關於1 <= 0
console.log(true <= '0');//false,至關於1 <= 0
console.log('true' <= 0);//false,至關於NaN <= 0
console.log([1] <= '0');//false,至關於'1' <= '0'
console.log([0] <= true);//true,至關於0 <= 1
console.log(1 <= 1);//true

小於運算符

小於運算符(<)用於比較兩個操做數,若是第一個操做數小於第二個操做數,則小於運算符的計算結果爲true,不然爲false

小於運算符與大於運算符的類型轉換規則相似,就再也不贅述

一樣地,大於等於運算符(>=)並不依賴於大於或等於運算符的比較規則,而是遵循小於運算符的比較規則,結果取反。若是'<'的比較結果是true,則'>='的結果是false;若是'<'的比較結果是false,則'>='的結果是true

邏輯運算符

邏輯運算符對操做數進行布爾運算,常常和關係運算符同樣配合使用。邏輯運算符將多個關係表達式組合起來組成一個更復雜的表達式。邏輯運算符分爲邏輯非'!'、邏輯與'&&'、邏輯或'||'3種。

邏輯非

邏輯非操做符由一個歎號(!)表示,能夠應用於ECMAScript中的任何值。不管這個值是什麼數據類型,這個操做符都會返回一個布爾值。邏輯非操做符首先會將它的操做數轉換成一個布爾值,而後再對其求反

邏輯非對操做數轉爲布爾類型的轉換類型與Boolean()轉型函數相同,只不過最後再將其結果取反。而若是同時使用兩個邏輯非操做符,實際上就會模擬Boolean()轉型函數的行爲

console.log(!!undefined);//false
console.log(!!null);//false
console.log(!!0);//false
console.log(!!-0);//false
console.log(!!NaN);//false
console.log(!!'');//false
console.log(!!false);//false

console.log(!!{});//true
console.log(!![]);//true

console.log(!!new Boolean(false));//true
console.log(!!false);//false
console.log(!!new Boolean(null));//true
console.log(!!null);//false

邏輯與

邏輯與運算符由兩個和號(&&)表示,有兩個操做數,只有在兩個操做數都爲true時,結果才返回true,不然返回false

//邏輯與(&&)的真值表
第一個操做數        第二個操做數        結果
true              true               true
true              false              false
false             true               false
false             false              false
邏輯與操做能夠應用於任何類型的操做數,而不只僅是布爾值。若是其中一個操做數不是布爾值,則邏輯與操做不必定返回布爾值

邏輯與操做屬於短路操做,若是第一個操做數可以決定結果,那麼就不會再對第二個操做數求值

對於邏輯與而言:
若是第一個操做數是false,則不管第二個操做數是什麼值,結果都是false,則返回第一個操做數;
若是第一個操做數爲true,則結果的真假和第二個操做數的真假相同,則返回第二個操做數

//除了false、undefined、null、+0、-0、NaN、''這7個假值,其他都是真值

console.log('t' && ''); //由於't'是真值,因此返回''
console.log('t' && 'f'); //由於't'是真值,因此返回'f'
console.log('t' && 1 + 2); //由於't'是真值,因此返回3
console.log('' && 'f'); //由於''是假值,因此返回''
console.log('' && ''); //由於''是假值,因此返回''
var i = 1;
var result = (true && i++);
console.log(result,i);//由於true是真值,因此執行i++,i是2,result是1

var i = 1;
var result = (false && i++);
console.log(result,i);//由於false是假值,因此不執行i++,i是1,result是false

邏輯與運算符能夠多個連用,返回第一個布爾值爲false的表達式的值

console.log(true && 'foo' && '' && 4 && 'foo' && true);// ''

邏輯或

邏輯或運算符由兩個豎線(||)表示,有兩個操做數,只有在兩個操做數都是false時,結果才返回false,不然返回true

//邏輯或(||)的真值表
第一個操做數        第二個操做數        結果
true              true              true
true              false             true
false             true              true
false             false             false
一樣地,邏輯或操做也能夠應用於任何類型的操做數,而不只僅是布爾值。若是其中一個操做數不是布爾值,則邏輯或操做不必定返回布爾值

邏輯或操做也屬於短路操做,若是第一個操做數可以決定結果,那麼就不會再對第二個操做數求值

對於邏輯或而言:
若是第一個操做數是true,則不管第二個操做數是什麼值,結果都是true,則返回第一個操做數;
若是第一個操做數是false,則結果的真假和第二個操做數的真假相同,則返回第二個操做數

console.log('t' || '');//由於't'是真值,因此返回"t"
console.log('t' || 'f');//由於't'是真值,因此返回"t"
console.log('' || 'f');//由於''是假值,因此返回"f"
console.log('' || '');//由於''是假值,因此返回""
var i = 1;
var result = (true || i++);
console.log(result,i);//由於true是真值,因此不執行i++,result是true,i是1

var i = 1;
var result = (false || i++);
console.log(result,i);//由於false是假值,因此執行i++,i是2,result是1

一樣地,邏輯或運算符也能夠多個連用,返回第一個布爾值爲true的表達式的值

console.log(false || 0 || '' || 4 || 'foo' || true);// 4

條件運算符

條件運算符是javascript中惟一的一個三元運算符(三個操做數),有時直接稱作三元運算符。一般這個運算符寫成?:,固然在代碼中每每不會這麼簡寫,由於這個運算符擁有三個操做數,第一個操做數在?以前,第二個操做數在?和:之間,第三個操做數在:以後

variable = boolean_expression ? true_value : false_value;

本質上,這就是基於對boolean_expression求值的結果,決定給變量variable賦什麼值。若是求值結果是true,則給變量variable賦值true_value;若是求值結果是false,則給變量variable賦值false_value

條件運算符的操做數能夠是任意類型,第一個操做數當成布爾值,若是它是真值,那麼將計算第二個操做數,並返回其計算結果。不然,若是第一個操做數是假值,那麼將計算第三個操做數,並返回其計算結果。第二個和第三個操做數老是會計算其中之一,不可能二者同時執行

其實使用if語句也會帶來一樣的效果,'?:'運算符只是提供了一種簡寫形式。下面是一個'?:'的典型應用場景,判斷一個變量是否有定義(並擁有一個有意義的真值),若是有定義則使用它,若是無定義則使用一個默認值:

greeting = 'hello ' + (username ? username : 'there');

圓括號運算符

圓括號運算符也叫分組運算符,它有兩種用法:若是表達式放在圓括號中,做用是求值;若是跟在函數後面,做用是調用函數

把表達式放在圓括號之中,將返回表達式的值

console.log((1));  //1
console.log(('a')); //'a'
console.log((1+2)); // 3

把對象放在圓括號之中,則會返回對象的值,即對象自己

var o = {p:1};
console.log((o));// Object {p: 1}

將函數放在圓括號中,會返回函數自己。若是圓括號緊跟在函數的後面,就表示調用函數,即對函數求值

function f(){return 1;}
console.log((f));// function f(){return 1;}
console.log(f()); // 1

[注意]圓括號運算符不能爲空,不然會報錯

相關文章
相關標籤/搜索