《JavaScript 權(quán)威指南(第六版)》二——表達(dá)式運(yùn)算符

第四章:表達(dá)式和運(yùn)算符

2017.02.21-2017.02.22

表達(dá)式和運(yùn)算符

表達(dá)式(expression):JavaScript解釋器會(huì)將其計(jì)算出一個(gè)結(jié)果。

運(yùn)算符(operator):將簡(jiǎn)單表達(dá)式組合成復(fù)雜表達(dá)式最常用的方法就是運(yùn)算符占锯。

原始表達(dá)式

原始表達(dá)式子(primary expression):表達(dá)式的最小單位卓嫂,它們不再包含其他表達(dá)式涡拘。JavaScript中的原始表達(dá)式包含常量或直接量换衬,關(guān)鍵字和變量炸卑。

直接量

1.23 //數(shù)字直接量
"hello" //字符串直接量
/pattern/ //正則表達(dá)式直接量

保留字

true 
false
null
this

變量

i
sum
undefined // undefined是全局變量,與null不同录豺,他不是關(guān)鍵字

對(duì)象和數(shù)組的初始化表達(dá)式

對(duì)象和數(shù)組初始化表達(dá)式實(shí)際上是一個(gè)新創(chuàng)建的對(duì)象和數(shù)組朦肘。這些初始化表達(dá)式有時(shí)稱作“對(duì)象直接量”和“數(shù)組直接量”。它們不是原始表達(dá)式双饥,它們所包含的成員或者元素都是子表達(dá)式媒抠。

數(shù)組初始化表達(dá)式

[] //空數(shù)組
[1+2,3+4] //有兩個(gè)元素的數(shù)組
var matrix=[[1,2,3],[4,5,6],[7,8,9]];

JavaScript對(duì)數(shù)組初始化表達(dá)式進(jìn)行求值的時(shí)候,數(shù)組初始化表達(dá)式中的元素表達(dá)式也都會(huì)各自計(jì)算一次咏花。

var x=1;
var a=[[x+++1,2],[x+++1,2],[x+++1,2]] //結(jié)果[ [ 2, 2 ], [ 3, 2 ], [ 4, 2 ] ]

數(shù)組直接兩種列表逗號(hào)之間的元素可以省略趴生,省略的空位會(huì)填充值undefined。

var arr=[1,,,,5];//arr打印結(jié)果:[ 1, , , , 5 ]
arr[0]; //1
arr[1]; //undefined
arr[4]; //5

數(shù)組直接量的元素列表結(jié)尾可以留下單個(gè)逗號(hào)昏翰,這時(shí)并不會(huì)創(chuàng)建一個(gè)新的值為undefined的元素苍匆。

var arr=[1,,,,5,]; //arr打印結(jié)果[ 1, , , , 5 ] 

對(duì)象初始化表達(dá)式

var p={x:2.3,y:-1.2}; //擁有兩個(gè)屬性成員的對(duì)象
var q={}; //空對(duì)象
q.x=2.3;q.y=-1.2; //此時(shí)q是{x:2.3;y:-1.2}
var rectangle={upperLeft:{x:2,y:2},lowerRight:{x:4,y:4}};
var side=1;
var square={upperLeft:{x:p.x,y:p.y},lowerRight:{x:p.x+side,y:p.y+side}};
var p={"x":2.3,"y":-1.2}; //打印結(jié)果 { x: 2.3, y: -1.2 },參考json
p.x //2.3
p."x" //SyntaxError: Unexpected string
p[x] //undefined,此處x會(huì)被當(dāng)做變量棚菊。倘若var x="x"浸踩,那么p[x] 也是2.3
p["x"] //2.3

函數(shù)定義表達(dá)式

函數(shù)定義表達(dá)式定義一個(gè)新的JavaScript函數(shù)。表達(dá)式的值是新定義的函數(shù)统求。函數(shù)定義表達(dá)是可稱為“函數(shù)直接量”检碗。

一個(gè)典型的函數(shù)定義表達(dá)式包含關(guān)鍵字function,跟隨其后的是一對(duì)圓括號(hào)码邻,括號(hào)內(nèi)是一個(gè)以逗號(hào)分割的列表折剃,列表含有0個(gè)或多個(gè)標(biāo)識(shí)符(參數(shù)名),然后在跟隨一個(gè)由花括號(hào)包裹的代碼段(函數(shù)體)像屋。

var square=function(x){return x*x};

函數(shù)定義表達(dá)式同樣可以包含函數(shù)的名字怕犁。函數(shù)可以通過(guò)函數(shù)語(yǔ)句來(lái)定義,而不是函數(shù)表達(dá)式己莺。

屬性訪問(wèn)表達(dá)式

屬性訪問(wèn)表達(dá)式運(yùn)算得到一個(gè)對(duì)象屬性或一個(gè)數(shù)組元素的值因苹。

【語(yǔ)法】

expression.identifier //用于對(duì)象
expression[expression] //用于對(duì)象、數(shù)組

【示例】

var o={x:1,y:{z:3}};
var a=[o,4,[5,6]];
o.x;//1
o.y.z;//3
o["x"];//1
a[0];//{ x: 1, y: { z: 3 } }
a[1];//4
a[2][1];//6
a[2]["1"];//6    a["2"][1];//6    a["2"]["1"];//6
a[0].x;//1  
a[0]["x"];//1


for(var each in this){console.log(each+":"+this[each])} //打印對(duì)象中所有屬性以及其值

在"."和"["之前的表達(dá)式總是會(huì)首先計(jì)算篇恒。如果計(jì)算結(jié)果是null或undefined扶檐,表達(dá)式會(huì)拋出類型錯(cuò)誤異常。(因?yàn)檫@兩個(gè)值不包含任意屬性)胁艰。如果運(yùn)算結(jié)果不是對(duì)象(或數(shù)組)款筑,JavaScript會(huì)將其轉(zhuǎn)換成對(duì)象。如果對(duì)象表達(dá)式后緊隨句點(diǎn)和標(biāo)識(shí)符腾么,則會(huì)差債有這個(gè)標(biāo)識(shí)符所指定的屬性的值奈梳,并將其作為整個(gè)表達(dá)式的值返回。如果對(duì)象表達(dá)式后緊隨一堆方括號(hào)解虱,則會(huì)計(jì)算方括號(hào)內(nèi)的表達(dá)式的值并將它轉(zhuǎn)換為字符串攘须。如果屬性不存在,返回undefined殴泰。

identitier寫法簡(jiǎn)單于宙,但要注意浮驳,此方式只適用于要訪問(wèn)的屬性名稱合法,并且需要知道要訪問(wèn)的屬性的名字捞魁。如果屬性名稱是一個(gè)保留字或者包含空格和標(biāo)點(diǎn)符號(hào)或是一個(gè)數(shù)字至会,則必須使用方括號(hào)。當(dāng)屬姓名是通過(guò)運(yùn)算得出來(lái)的值而不是固定的值得時(shí)候谱俭,這是必須使用方括號(hào)奉件。

調(diào)用表達(dá)式

調(diào)用表達(dá)式(invocation expression):是一種調(diào)用(或者執(zhí)行)函數(shù)或方法的語(yǔ)法表示。以一個(gè)函數(shù)表達(dá)式開(kāi)始昆著,這個(gè)函數(shù)表達(dá)式指代要調(diào)用的函數(shù)县貌,函數(shù)表達(dá)式后緊隨一對(duì)包含一逗號(hào)隔開(kāi)的參數(shù)列表的圓括號(hào)。

f(0)
Math.max(x,y,z)
a.sort() //關(guān)于這個(gè)函數(shù)凑懂,戳下面鏈接

JavaScript sort() 方法

當(dāng)調(diào)用表達(dá)式進(jìn)行求職的時(shí)候煤痕,首先計(jì)算函數(shù)表達(dá)式,然后計(jì)算參數(shù)表達(dá)式征候,得到一組參數(shù)值杭攻。如果函數(shù)表達(dá)式的值不是一個(gè)可調(diào)用的對(duì)象,則拋出一個(gè)類型錯(cuò)誤異常疤坝。然后兆解,實(shí)參的值被依次賦給形參,接下來(lái)執(zhí)行函數(shù)體跑揉。如果函數(shù)使用return語(yǔ)句給出一個(gè)返回值锅睛,那么這個(gè)返回值就是整個(gè)調(diào)用表達(dá)式的值,否則历谍,調(diào)用表達(dá)式的值就是undefined现拒。

如果調(diào)用表達(dá)式是一個(gè)屬性訪問(wèn)表達(dá)式,則此調(diào)用稱作“方法調(diào)用”望侈。

對(duì)象創(chuàng)建表達(dá)式

對(duì)象創(chuàng)建表達(dá)是(object creation expression):創(chuàng)建一個(gè)對(duì)象并調(diào)用一個(gè)函數(shù)(構(gòu)造函數(shù))初始化新對(duì)象的屬性印蔬。

new Object()
new Point(2,3)

如果一個(gè)對(duì)象創(chuàng)建表達(dá)式不需要傳入任何參數(shù)給構(gòu)造函數(shù)的話,那么這對(duì)空?qǐng)A括號(hào)是可以省略掉的脱衙。

new Object
new Date

當(dāng)計(jì)算一個(gè)對(duì)象創(chuàng)建表達(dá)式的值時(shí)侥猬,和對(duì)象初始化表達(dá)式通過(guò){}創(chuàng)建對(duì)象的做法一樣,JavaScript首先創(chuàng)建一個(gè)新的空對(duì)象捐韩,然后JavaScript通過(guò)傳入指定的參數(shù)并將這個(gè)新對(duì)象當(dāng)做this的值來(lái)調(diào)用一個(gè)指定的函數(shù)退唠。這個(gè)函數(shù)可以使用this來(lái)初始化這個(gè)新創(chuàng)建對(duì)象的屬性。那些被當(dāng)做構(gòu)造函數(shù)的函數(shù)不會(huì)反悔一個(gè)值荤胁,并且這個(gè)新創(chuàng)建并被初始化后的對(duì)象就是整個(gè)對(duì)象創(chuàng)建表達(dá)式的值瞧预。如果一個(gè)構(gòu)造函數(shù)確實(shí)返回了一個(gè)對(duì)象值,那么這個(gè)對(duì)象就作為整個(gè)對(duì)象創(chuàng)建表達(dá)式的值,而新創(chuàng)建的對(duì)象就廢棄了垢油。

運(yùn)算符概述

JavaScript中的運(yùn)算符用于算術(shù)表達(dá)式盆驹、比較表達(dá)式、邏輯表達(dá)式秸苗、復(fù)制表達(dá)式等召娜。

包括關(guān)鍵字運(yùn)算符(delete运褪,instanceof)和標(biāo)點(diǎn)符號(hào)(+惊楼,=)所表示的運(yùn)算符摘符。

JavaScript 運(yùn)算符

操作數(shù)的個(gè)數(shù)

  • 一元運(yùn)算符 unary operator
  • 二元運(yùn)算符 binary operator
  • 三元運(yùn)算符 ternary operator

操作數(shù)類型和結(jié)果類型

一些運(yùn)算符可以作用于任何數(shù)據(jù)類型尉辑,但仍希望它們的操作數(shù)是指定類型的數(shù)據(jù)铡俐,并大多數(shù)運(yùn)算符返回一個(gè)特定類型的值腰奋。

左值

左值是指:表達(dá)式只能出現(xiàn)在賦值運(yùn)算符的左側(cè)蚀之。在JavaScript中袱院,變量嘁字、對(duì)象屬性和數(shù)組元素均是左值蒿往。

ECMAScript規(guī)范允許內(nèi)置函數(shù)返回一個(gè)左值劣欢,但自定義的函數(shù)則不能返回左值棕诵。(?)

運(yùn)算優(yōu)先級(jí)

屬性訪問(wèn)表達(dá)式和調(diào)用表達(dá)式的優(yōu)先級(jí)比表中運(yùn)算符都要高。

運(yùn)算順序

JavaScript總是嚴(yán)格按照從左至右的順序來(lái)計(jì)算表達(dá)式凿将。

算術(shù)表達(dá)式

* / % -無(wú)法轉(zhuǎn)換為數(shù)字的操作數(shù)都轉(zhuǎn)換為NaN校套,結(jié)果也是NaN。

對(duì)于除法/牧抵,JavaScript中所有數(shù)字都是浮點(diǎn)型的笛匙,除法運(yùn)算的結(jié)果也是浮點(diǎn)型。

5/2 //2.5
0/0 //NaN
1/0 //Infinity
-1/0 //-Infinity

對(duì)于取模%犀变,結(jié)果和第一個(gè)操作數(shù)的符號(hào)保持一致妹孙。操作數(shù)通常是整數(shù),但也適用于浮點(diǎn)數(shù)获枝。

5%2 //1
-5%2 //-1
6.5%2.1 //0.19999999999999973

+運(yùn)算符

1+2 //3
"hello"+" "+"there" //"hello there"
"1"+"2" //"12"
  • 如果其中一個(gè)操作數(shù)是對(duì)象蠢正,則對(duì)象會(huì)遵循對(duì)象到原始值的轉(zhuǎn)換規(guī)則轉(zhuǎn)換為原始類值。日期獨(dú)享通過(guò)toString()方法轉(zhuǎn)換省店,群毆他對(duì)象通過(guò)valueOf()轉(zhuǎn)換(如果valueOf()返回原始值的話)嚣崭。由于多數(shù)都不具備valueOf()方法,因此會(huì)通過(guò)toString()轉(zhuǎn)換萨西。
  • 在進(jìn)行了對(duì)象到運(yùn)勢(shì)值的轉(zhuǎn)換之后有鹿,如果一個(gè)操作數(shù)是字符串,另一個(gè)操作數(shù)也會(huì)轉(zhuǎn)換為字符串谎脯,然后進(jìn)行字符串連接葱跋。
  • 否則,兩個(gè)操作數(shù)都轉(zhuǎn)換為數(shù)字(或NaN),然后進(jìn)行加法運(yùn)算

【示例】

1+2 //3;加法
"1"+"2" // "12";字符串連接
"1"+2 //"12";數(shù)字轉(zhuǎn)換為字符串后進(jìn)行字符串連接
1+{} //"1[object Object]" ;對(duì)象轉(zhuǎn)換為字符串后進(jìn)行字符串連接
true+true //2;布爾值轉(zhuǎn)換為數(shù)字后加法
2+null; //2;null轉(zhuǎn)換為0后加法
2+undefined //NaN;undefined轉(zhuǎn)換為NaN后加法

需要注意的是娱俺,加號(hào)運(yùn)算符和字符串和數(shù)字一起使用時(shí)稍味,需要考慮加法的結(jié)核性對(duì)運(yùn)算順序的影響。

1+2+"hello" // "3hello"
1+(2+"hello") //"12hello"

一元算術(shù)運(yùn)算符

一元運(yùn)算符作用域一個(gè)單獨(dú)的操作數(shù)荠卷,產(chǎn)生一個(gè)新值模庐。一元運(yùn)算符優(yōu)先級(jí)很高,右結(jié)合(right-associative)油宜。

+

把操作數(shù)轉(zhuǎn)換為數(shù)字(或NaN)掂碱,并返回轉(zhuǎn)換后的數(shù)字。如果操作數(shù)本身就是數(shù)字慎冤,則直接返回?cái)?shù)字疼燥。

-

把操作數(shù)轉(zhuǎn)換為數(shù)字,然后改變運(yùn)算結(jié)果的符號(hào)蚁堤。

++

加一醉者,操作數(shù)是一個(gè)左值。將操作數(shù)轉(zhuǎn)換為數(shù)字披诗,然后給數(shù)字加一撬即,并將加一后的數(shù)值重新賦值給操作數(shù)(變量、數(shù)組元素或者對(duì)象屬性)呈队。

前增量:運(yùn)算符在操作數(shù)之前的剥槐。

后增量:運(yùn)算符在操作數(shù)之后的。不允許后增量運(yùn)算符和操作數(shù)之間插入換行符掂咒。

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

x++不等于x=x+1才沧,++從不進(jìn)行字符串連接操作。

var x='1';
x++; //2
x=x+1; // 11
--

減一绍刮,操作數(shù)是一個(gè)左值温圆。將操作數(shù)轉(zhuǎn)換為數(shù)字,然后減一孩革,并將減一后的數(shù)值重新賦值給操作數(shù)(變量岁歉、數(shù)組元素或者對(duì)象屬性)。

運(yùn)算符在操作數(shù)之前膝蜈,操作數(shù)減一并返回減一后的值锅移。

運(yùn)算符在操作數(shù)之后,操作數(shù)減一并返回減一前的值饱搏。不允許運(yùn)算符和操作數(shù)之間有換行符非剃。

位運(yùn)算符

位運(yùn)算符要求其操作數(shù)是整數(shù),這些證書(shū)表示為32位整型而不是64位浮點(diǎn)型推沸。必要時(shí)备绽,位運(yùn)算符首先將操作符轉(zhuǎn)換為數(shù)字券坞,并將數(shù)字強(qiáng)制表示為32位整型,這會(huì)忽略原格式中的小數(shù)部分和任何超過(guò)32位的二進(jìn)制位肺素。移位運(yùn)算符要求又操作數(shù)在0-31之間恨锚。在將其操作數(shù)轉(zhuǎn)換為無(wú)符號(hào)32位整數(shù)后,它們將舍棄第5位之后的二進(jìn)制位倍靡,以便生成一個(gè)位數(shù)正確的數(shù)字猴伶。位運(yùn)算符將NaN、Infinity塌西、-Infinity轉(zhuǎn)換為0他挎。

  • & 按位與
  • | 按位或
  • ^ 按位異或
  • ~ 按位非,相當(dāng)于改變符號(hào)并減一雨让。 ~0x0f=0xfffffff0 即15按位非后是-16
  • << 左移雇盖,新的位用0補(bǔ)充忿等,并舍棄高位栖忠。左移n位相當(dāng)于乘以2^n
  • >> 帶符號(hào)右移,如果第一個(gè)操作數(shù)是正數(shù)贸街,用0填補(bǔ)最高位庵寞;如果第一個(gè)操作室是負(fù)數(shù),用1填補(bǔ)最高位薛匪。將一個(gè)值右移n位捐川,相當(dāng)于除以2^n(忽略余數(shù))。7>>1=3;-7>>1=-4
  • >>> 無(wú)符號(hào)右移逸尖,最高位總是補(bǔ)0古沥。 -1>>4=1-;-1>>>4=0x0FFFFFFF

關(guān)于無(wú)符號(hào)數(shù),有符號(hào)數(shù)娇跟。

> 0xFFFFFFFF
4294967295
> 0xFFFFFFFF>>>0
4294967295
> 0xFFFFFFFF<<0
-1
> 0xFFFFFFFF>>0
-1

關(guān)系表達(dá)式

相等岩齿,不相等

===嚴(yán)格相等運(yùn)算符(恒等運(yùn)算符),用來(lái)檢測(cè)兩個(gè)操作數(shù)是否嚴(yán)格相等苞俘。對(duì)應(yīng)的有!==

==相等運(yùn)算符盹沈,用來(lái)檢測(cè)兩個(gè)操作數(shù)是否相等,可以允許進(jìn)行類型轉(zhuǎn)換吃谣。對(duì)應(yīng)的有!=

===
  • 如果兩個(gè)值類型不相同乞封,則它們不相等。
  • 如果兩個(gè)值都是null或者都是undefined岗憋,則它們相等肃晚。null===null(true)undefined===undefined(true) 。(注意:中文版仔戈,淘寶團(tuán)隊(duì)翻譯的有錯(cuò)誤关串。翻譯為不想等了惋鸥。)null,undefined,Infinity,-Infinity只要兩者本身值或者計(jì)算后的值相等,那么他們就恒等悍缠。
  • 如果兩個(gè)值都是布爾值true或者都是布爾值false卦绣,則它們相等
  • 如果其中一個(gè)值是NaN,或者兩個(gè)值都是NaN飞蚓,則它們不相等滤港。NaN和其他任何值都不想等,包括他自己趴拧。通過(guò)x!=x判斷x是否位NaN溅漾,只有在x為NaN時(shí),這個(gè)表達(dá)式的值才是true著榴。
  • 如果兩個(gè)值為數(shù)字且數(shù)值相等添履,則它們相等。如果一個(gè)值為0脑又,另一個(gè)值為-0暮胧,則它們同樣相等。
  • 如果兩個(gè)值為字符串问麸,且所含的對(duì)應(yīng)位上的16位數(shù)完全相等往衷,則它們相等。如果長(zhǎng)度或內(nèi)容不同严卖,則它們不等席舍。兩個(gè)字符串可能含義完全一樣且所顯示出的字符也一樣,但是具有不同編碼的16位值哮笆。JavaScript不對(duì)Unicode進(jìn)行標(biāo)準(zhǔn)化的轉(zhuǎn)換来颤,因此像這樣的字符串通過(guò)=== ==比較的結(jié)果不相等。String.localeCompare()提供了另外一種比較字符串的方法稠肘。
  • 如果兩個(gè)引用值指向同一個(gè)對(duì)象福铅、數(shù)組或函數(shù),則它們相等启具。如果指向不同對(duì)象本讥,則它們不相等,盡管兩個(gè)對(duì)象具有完全一樣的屬性鲁冯。
==
  • 如果兩個(gè)操作數(shù)的類型相同拷沸,則和上文所述的比較規(guī)則一樣。如果嚴(yán)格相等薯演,那么比較結(jié)果相等撞芍,如果不嚴(yán)格相等,則比較結(jié)果不相等跨扮。
  • 如果兩個(gè)操作數(shù)類型不同:
    • 一個(gè)null序无,另一個(gè)undefined验毡,則它們相等。null==undefined
    • 一個(gè)值是數(shù)字帝嗡,另一個(gè)是字符串晶通,現(xiàn)將字符串轉(zhuǎn)換為數(shù)字,然后比較
    • 如果一個(gè)值為true哟玷,則將其轉(zhuǎn)換為1再比較狮辽。如果一個(gè)值位false,則將其轉(zhuǎn)換為0再比較true==1:true;true==2:false;true=="1":true
    • 如果一個(gè)值是對(duì)象巢寡,另一個(gè)值是數(shù)字或字符串喉脖,則使用轉(zhuǎn)換規(guī)則將對(duì)象轉(zhuǎn)換為原始值,然后比較抑月。
    • 其他的不同類型之間的比較均不相等树叽。

比較運(yùn)算符

  • < 小于
  • > 大于
  • <= 小于等于
  • >= 大于等于

只有數(shù)字和字符串才能執(zhí)行比較操作,非數(shù)字和字符串都要進(jìn)行類型轉(zhuǎn)換谦絮。規(guī)則如下:

  • 如果操作數(shù)是對(duì)象题诵,轉(zhuǎn)換為原始值:如果valueOf()返回原始值,那么直接使用這個(gè)原始值挨稿。否則仇轻,使用toString()的轉(zhuǎn)換結(jié)果進(jìn)行比較。
  • 在對(duì)象轉(zhuǎn)換為原始值之后奶甘,如果兩個(gè)操作數(shù)都是字符串,將依照字母表的順序?qū)蓚€(gè)字符串比較祭椰。
  • 在對(duì)象轉(zhuǎn)換為原始值之后臭家,如果至少有一個(gè)操作數(shù)不是字符串,那么兩個(gè)操作數(shù)都將轉(zhuǎn)換為數(shù)字進(jìn)行述職比較方淤。0和-0相等钉赁。Infinity大于任何數(shù)字(除了自己)。-Infinity小于任何數(shù)字(除了自己)携茂。如果其中一個(gè)操作數(shù)是NaN(或轉(zhuǎn)換后是NaN)你踩,那么比較操作符總是返回false。

所有的大寫的ASCII字母都小魚(yú)小寫的ASCII字母讳苦。 'Zoo'<'apple'返回true

in 運(yùn)算符

in運(yùn)算符希望它的左操作數(shù)是一個(gè)字符串還或可以轉(zhuǎn)換為字符串带膜,希望它的右操作數(shù)是一個(gè)對(duì)象。如果右側(cè)的對(duì)象擁有一個(gè)名為左操作數(shù)值得屬性名鸳谜,那么表達(dá)式返回true膝藕。

var point={x:1,y:2}; //定義一個(gè)對(duì)象
"x" in point; //true
"z" in point; //false
"toString" in point  //true ,對(duì)象繼承了toString()方法

var data=[7,8,9];//定義一個(gè)數(shù)組
"0" in data; //true
1 in data; //true,數(shù)字轉(zhuǎn)換為字符串
3 in data; //false咐扭,不存在索引3的元素
"toString" in t //true芭挽,數(shù)組有toString()方法

instanceof 運(yùn)算符

instanceof運(yùn)算符希望左操作數(shù)是一個(gè)對(duì)象滑废,右操作數(shù)標(biāo)識(shí)對(duì)象的類。如果左側(cè)的對(duì)象是右側(cè)類的實(shí)例袜爪,則表達(dá)式返回true蠕趁,否則返回false。

var d = new Date(); 
d instanceof Date;//true
d instanceof Object; //true
d instanceof Number; //false
var a = [1, 2, 3];
a instanceof Array;//true 
a instanceof Object; //true
a instanceof RegExp;//false

所有的對(duì)象都是Object的實(shí)例辛馆,當(dāng)通過(guò)instanceof判斷一個(gè)對(duì)象是否是一個(gè)類的實(shí)例的時(shí)候妻导,這個(gè)判斷也會(huì)對(duì)其父類檢測(cè)。

如果instanceof左操作數(shù)不是對(duì)象怀各,返回false倔韭。如果右操作數(shù)不是函數(shù),拋出類型錯(cuò)誤異常瓢对。

instanceof 工作原理(原型鏈prototype chain):原型鏈?zhǔn)荍avaScript的繼承機(jī)制寿酌。為了計(jì)算表達(dá)式 o instanceof f,JavaScript首先計(jì)算f.prototype硕蛹,然后在原型鏈中查找o醇疼,如果找到,那么o是f的一個(gè)實(shí)例法焰,表達(dá)式返回true秧荆。否則返回false。

邏輯表達(dá)式

&& || !
返回true埃仪,false乙濒。

&& 邏輯與

第一層理解:當(dāng)操作數(shù)都是布爾值的時(shí)候,返回true或false卵蛉。

假值:false颁股,null,undefined傻丝,0甘有,-0,NaN葡缰,""亏掀。所有其他的值包括所有對(duì)象都是真值。

第二層理解:對(duì)真值和假值進(jìn)行與操作泛释。在JavaScript中任何希望使用布爾值的地方滤愕,表達(dá)式和語(yǔ)句都會(huì)將其當(dāng)做真值或者假值來(lái)對(duì)待。因此并不總是返回true或false胁澳。

第三層理解:運(yùn)算符首先計(jì)算左操作數(shù)的值该互,如果是假值,則整個(gè)表達(dá)式也是假值韭畸。因此&&返回左操作數(shù)的值宇智,而不會(huì)對(duì)右操作數(shù)進(jìn)行計(jì)算蔓搞。如果左操作數(shù)是假值,則表達(dá)式結(jié)果取決于右操作數(shù)的值随橘。&&將計(jì)算右操作數(shù)的值并將其返回作為整個(gè)表達(dá)式的計(jì)算結(jié)果喂分。

> 1&&false
false
> 1&&true
true
> 1&&2
2
> 2&&1
1
> 0&&1
0
> true&&1
1
> false&&1
false
> true&&0
0

> var o={x:1}
undefined
> var p=null
undefined
> o&&o.x
1
> p&&p.x
null

&&的行為有時(shí)被稱作“短路”。

if(a==b) stop();
(a==b) && stop();//二者等價(jià)

|| 邏輯或

&&對(duì)比理解机蔗。

如果第一個(gè)操作數(shù)為真蒲祈,則返回真值。否則計(jì)算第二個(gè)操作數(shù)萝嘁,并返回表達(dá)式的計(jì)算結(jié)果梆掸。

> 1||NaN
1
> 0||NaN
NaN

! 邏輯非

!是一元運(yùn)算符。將操作數(shù)的布爾值求反牙言。

首先將其操作數(shù)轉(zhuǎn)換為布爾值酸钦,然后在對(duì)布爾值求反,總是返回true或false咱枉,并且可以通過(guò)兩次邏輯非得到等價(jià)布爾值卑硫。!!x。優(yōu)先級(jí)很高蚕断。

!(p&&q)===!p||!q
!(p||q)===!p&&!q

賦值表達(dá)式

=運(yùn)算符希望它的左操作數(shù)是一個(gè)左值(變量欢伏、對(duì)象屬性或數(shù)組元素),右操作數(shù)是任意值亿乳。

賦值操作符的結(jié)合性是從右到左硝拧。

i=j=k=0; //把三個(gè)變量初始化為0

帶操作的賦值運(yùn)算

+=
-=
*=
/=
%=
<<=
>>=
>>>=
&=
|=
^=

大多數(shù)情況下,a op= b 等價(jià)于a = a op b

表達(dá)式計(jì)算

通過(guò)eval()解釋運(yùn)行由JavaScript源代碼組成的字符串风皿,并產(chǎn)生一個(gè)值河爹。

eval("3+2") //5

eval()只有一個(gè)參數(shù)。如果參數(shù)不是字符串桐款,它直接返回此參數(shù)。如果參數(shù)是字符串夷恍,他會(huì)把字符串當(dāng)成JavaScript代碼進(jìn)行編譯魔眨。編譯失敗將拋出語(yǔ)法異常,編譯成功則執(zhí)行代碼酿雪,并返回字符串中的最后一個(gè)表達(dá)式或語(yǔ)句的值(如果最后一個(gè)表達(dá)式或語(yǔ)句沒(méi)有值遏暴,則最終返回undefined)。如果字符串拋出異常指黎,則異常將把該調(diào)用傳遞給eval()朋凉。

eval()查找變量的值和定義新變量和函數(shù)額操作與局部作用域中的代碼完全一樣。

注意:傳遞給eval()的字符串必須在語(yǔ)法上講得通醋安。不能通過(guò)eval()向函數(shù)中任意粘貼代碼片段杂彭。否則將拋出語(yǔ)法錯(cuò)誤異常墓毒。

var foo=function(a){
    eval(a);
};
foo("return;");// SyntaxError: Illegal return statement

【全局eval實(shí)例】

var geval = eval;
var x = "global", y = "global"; 
function f() {
    var x = "local";
    eval("x += 'changed';"); //直接eval更改局部變量
    return x;//返回修改后的局部變量
}
function g() {
    var y = "local";
    geval("y += 'changed';"); //間接調(diào)用改變?nèi)肿兞?    return y;//返回未修改的局部變量
}
console.log(f(), x);//打印 "localchanged global"
console.log(g(), y);//打印 "local globalchanged"

嚴(yán)格eval()

use strict

嚴(yán)格模式將eval列為保留字,不允許使用別名覆蓋eval()函數(shù)亲怠。并且變量名所计、函數(shù)名、函數(shù)參數(shù)或者異常捕獲的參數(shù)都不能取名為eval团秽。

其他運(yùn)算符

?: 條件運(yùn)算符

?:是JavaScript中唯一的一個(gè)三元運(yùn)算符主胧。

條件操作符的操作數(shù)可以是任意類型。第一個(gè)操作數(shù)當(dāng)成布爾值习勤,如果真則計(jì)算第二個(gè)操作數(shù)并返回計(jì)算結(jié)果踪栋,如果假計(jì)算第三個(gè)操作數(shù)并返回計(jì)算結(jié)果。第二個(gè)和第三個(gè)操作數(shù)總是會(huì)計(jì)算其中之一图毕,不可能二者同時(shí)執(zhí)行夷都。(使用if語(yǔ)句也會(huì)帶來(lái)同樣效果)

greeting="hello"+(username?username:"there");
//上下二者等價(jià)
greeting="hello"
if(username)
    greeting+=username;
else
    greeting+="there";

typeof 運(yùn)算符

一元運(yùn)算符,放在其單個(gè)操作數(shù)的前面吴旋,操作數(shù)可以是任意類型损肛。返回操作數(shù)類型的一個(gè)字符串。

typeof x
typeof (x)
x typeof x
undefined "undefined"
null "object"
true/false "boolean"
任意數(shù)字或NaN "number"
任意字符串 "string"
任意函數(shù) "function"
任意內(nèi)置對(duì)象(非函數(shù)) "object"
任意宿主對(duì)象 由編譯器各自實(shí)現(xiàn)的字符串荣瑟。但是不是"undefined" "boolean" "number" "string"

delete 運(yùn)算符

一元運(yùn)算符治拿,刪除對(duì)象屬性或者數(shù)組元素。

var o={x:1;y:2};
delete o.x;
"x" in o;//false笆焰,這個(gè)屬性不再存在
var a=[1,2,3,4];
delete a[2];//刪除倒數(shù)第二個(gè)元素
2 in a;//false劫谅,這個(gè)元素不再存在
a[2];//undefined
a;// [1,2,,4]
a.length;// 4。刪除操作嚷掠,沒(méi)有修改數(shù)組長(zhǎng)度

delete希望他的操作數(shù)是一個(gè)左值捏检,如果不是左值,delete將不進(jìn)行任何操作并返回true不皆。否則贯城,delete駛?cè)雱h除這個(gè)指定的左值,如果刪除成功霹娄,返回true能犯,否則返回false。內(nèi)置核心和客戶端屬性是不能刪除的犬耻,用var語(yǔ)句生命的變量不能刪除踩晶,通過(guò)function語(yǔ)句定義的函數(shù)和函數(shù)參數(shù)也不能刪除。

> fff=function(){}
[Function: fff]
> typeof fff
'function'
> delete fff
true
> fff
ReferenceError: fff is not defined

> function ff(){}
undefined
> delete ff
false
> ff
[Function: ff]

ES5嚴(yán)格模式下枕磁,有操作數(shù)是一個(gè)屬性訪問(wèn)表達(dá)式才會(huì)正常工作渡蜻,否則將會(huì)拋出語(yǔ)法錯(cuò)誤。

void 運(yùn)算符

一元運(yùn)算符,它出現(xiàn)在操作數(shù)之前茸苇,操作數(shù)可以是任意類型排苍。操作數(shù)會(huì)照常計(jì)算,但忽略結(jié)果并返回undefined税弃。

最常用在客戶端的URL中纪岁。

<a href="javascript:void window.open();">打開(kāi)一個(gè)新窗口</a>

, 逗號(hào)運(yùn)算符

二元運(yùn)算符,操作數(shù)任意類型则果,先計(jì)算左操作數(shù)幔翰,再計(jì)算右操作數(shù),最后返回右操作數(shù)的值西壮。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末遗增,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子款青,更是在濱河造成了極大的恐慌做修,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,470評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件抡草,死亡現(xiàn)場(chǎng)離奇詭異饰及,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)康震,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門燎含,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人腿短,你說(shuō)我怎么就攤上這事屏箍。” “怎么了橘忱?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,577評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵赴魁,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我钝诚,道長(zhǎng)颖御,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,176評(píng)論 1 292
  • 正文 為了忘掉前任凝颇,我火速辦了婚禮郎嫁,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘祈噪。我一直安慰自己,他們只是感情好尚辑,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,189評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布辑鲤。 她就那樣靜靜地躺著,像睡著了一般杠茬。 火紅的嫁衣襯著肌膚如雪月褥。 梳的紋絲不亂的頭發(fā)上弛随,一...
    開(kāi)封第一講書(shū)人閱讀 51,155評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音宁赤,去河邊找鬼舀透。 笑死,一個(gè)胖子當(dāng)著我的面吹牛决左,可吹牛的內(nèi)容都是我干的愕够。 我是一名探鬼主播,決...
    沈念sama閱讀 40,041評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼佛猛,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼惑芭!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起继找,我...
    開(kāi)封第一講書(shū)人閱讀 38,903評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤遂跟,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后婴渡,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體幻锁,經(jīng)...
    沈念sama閱讀 45,319評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,539評(píng)論 2 332
  • 正文 我和宋清朗相戀三年边臼,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了哄尔。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,703評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡硼瓣,死狀恐怖究飞,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情堂鲤,我是刑警寧澤亿傅,帶...
    沈念sama閱讀 35,417評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站瘟栖,受9級(jí)特大地震影響葵擎,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜半哟,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,013評(píng)論 3 325
  • 文/蒙蒙 一酬滤、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧寓涨,春花似錦盯串、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,664評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春几缭,著一層夾襖步出監(jiān)牢的瞬間河泳,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,818評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工年栓, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留拆挥,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,711評(píng)論 2 368
  • 正文 我出身青樓某抓,卻偏偏與公主長(zhǎng)得像纸兔,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子搪缨,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,601評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容