接著之前的知識點席怪,繼續(xù)學(xué)習(xí)js.還是一如既往的在簡書上求個贊~
表達式呢畜普,它是JavaScript的一個短語奇昙,js會將表達式計算出一個結(jié)果护侮。最簡單的表達式是常量。變量名也是一種簡單的表達式储耐,他的值就是賦值給變量的值羊初。賦值的表達式有簡單表達式組成,而如何去組就依靠運算符什湘。
一长赞、表達式
原始表達式
原始表達式是最簡單的表達式了,主要包含常量闽撤,直接量得哆、變量和關(guān)鍵字
3.14 //數(shù)字直接量
“hello” //字符串直接量
/pattern/ //則表達式直接量
true //真
false //假
null //空
this //返回”當(dāng)前“對象
var i; //返回變量i的值
var sum; //返回變量sum的值
undefined //全局變量
這里的this是一個關(guān)鍵字,經(jīng)常在面向?qū)ο缶幊讨谐霈F(xiàn)哟旗,在后面我們會詳細進行研究~贩据。
對象表達式
對象表達式和數(shù)組表達式實際上是一個新創(chuàng)建的對象和數(shù)組。也可以叫做“對象直接量”和“數(shù)組直接量”热幔。對象直接量是有兩個花括號組成{}乐设,初始化一個對象
var obj={} //初始化一個obj對象
var foo={x:1,y:2} //初始化一個foo對象,并賦予屬性和值
對象表達式里面也可以嵌套
var obj={
a{x:1},
b{y:2}
}
數(shù)組表達式
數(shù)組表達式和對象表達式類似绎巨,只是花括號變成了中括號[]
var arr=[]
var arr2=[1,1,2,2,,3,3]
[]初始化一個數(shù)組近尚,并且可以給數(shù)組元素賦值,數(shù)組各元素間用逗號隔開场勤,當(dāng)逗號隔開是沒有值戈锻,則表示所在的數(shù)組元素值為undefined歼跟。
var arr=[1,,];
console.log(arr.length);
console.log(arr[1]);
數(shù)組表達式
函數(shù)表達式也可以稱作“函數(shù)直接量”,表示初始化一個函數(shù)格遭,function functionName(arguments){},function后面跟著函數(shù)名稱再假小括號里面是傳遞給函數(shù)的形式參數(shù)哈街,再用花括號包含函數(shù)體。當(dāng)然function后面也可不要函數(shù)名拒迅,或這沒有參數(shù)骚秦,
btn.onclick=function(){
//dosomething
}
這種叫匿名函數(shù)。
屬性訪問表達式
屬性訪問表達式是為了等到一個對象屬性或者數(shù)組屬性的值璧微,有兩種語法
一是點語法 對象.屬性
而是[]發(fā) 對象[屬性]或者數(shù)組[屬性]
var obj={x:1,y:2}
var arr=[1,2,3]
console.log(obj.x) //得到x的值
console.log(obj.y) //得到y(tǒng)的值
或者
obj["x"];
obj["y"]
console,log(arr[0]); //得到數(shù)組第一項元素
console.log(arr[1]); //得到數(shù)組第二項元素
這兩種方式都是沒問題的作箍,但是再屬性是標(biāo)識符(變量)或者不確定的值的時候優(yōu)先使用[].
調(diào)用表達式
調(diào)用是函數(shù)或者方法的特有,有一個小括號組成()
function sayHi(){ //定義函數(shù)
console.log("Hi")
}
var a{
sort:function(){
//dosomething
}
}
sayHi() //調(diào)用函數(shù)
Math.max(x,y,z) //Math.max是一個內(nèi)置函數(shù)前硫,x,y,z是參數(shù)
a.sort() //調(diào)用對象a的sort函數(shù)
對象創(chuàng)建表達式
對象創(chuàng)建表達式創(chuàng)建一個對象并調(diào)用一個函數(shù)(這個函數(shù)叫做構(gòu)造函數(shù))初始化對象的屬性胞得,對象創(chuàng)建表達式前面有個 new 關(guān)鍵字
new Object();
new Point(1,2);
new Array()
如果構(gòu)造函數(shù)里面不需要參數(shù),可以省略小括號()
new Objec();
new Function();
new Array();
關(guān)于構(gòu)造函數(shù)和new的用法屹电,我們接下去會詳細來探討阶剑,這里簡單知道下,它是可以在設(shè)計模式中行作用的危号。
二牧愁、運算符
js的運算操作等依賴于運算符,運算符有算數(shù)運算符葱色、比較運算符递宅、邏輯運算符娘香、復(fù)制運算符等苍狰,我們通過一個圖表來做一個參考。
圖表中烘绽,運算符是根據(jù)運算符的優(yōu)先級排序的淋昭。前面的運算符優(yōu)先級要高于后面的運算符優(yōu)先級。
標(biāo)題為A的列表表示運算符的結(jié)合性L (從左到右)或R(從右到左),所謂的結(jié)合性就是指定了在多個具有同樣優(yōu)先級的運算符表達式中的運算順序安接。從左到右是指運算符的執(zhí)行順序是按照由左到右的順序進行翔忽。例如減法運算符具有從左到右的結(jié)合性
a=x-y-z;等價與a=((x-y)-z)
*lval是left-value的簡寫,意思是"左值".他是一個術(shù)語盏檐。指的市表達式只能出現(xiàn)再賦值運算符(=)的左側(cè)歇式。在js中,變量胡野、對象屬性和數(shù)組元素均是左值材失。
運算符的副作用
有一些表達式具有副作用,就是說前后表達式的運算會相互的影響硫豆。比如賦值表達式(=)龙巨,給一個變量賦值笼呆,那么使用這個變量或?qū)傩缘谋磉_式的值都會發(fā)生改變,此外還有++和--遞增遞減運算符。delete運算符同樣也是旨别,刪除一個屬性就像(不一定一樣)給這個屬性賦值undefined
var a=1;
console.log(a);
var a=2;
console.log(a);
...
運算符的優(yōu)先級
上圖中運算符是按照優(yōu)先級從高到低排序的诗赌,每個水平線分割的一組運算符具有相同的優(yōu)先級。運算符優(yōu)先級控制這運算符的執(zhí)行順序秸弛。優(yōu)先級高的運算符的執(zhí)行總是先與優(yōu)先級低的運算符铭若。
注意的是=賦值運算符具有最低的優(yōu)先級,因此賦值操作是再右側(cè)的表達式計算出結(jié)果后進行的递览。
運算符也可以像數(shù)學(xué)那樣奥喻,使用圓括號()來指定那個運算符的順序。接下來就來了解下常見的運算符非迹,其他的運算符大家可以去書上看更加詳細的介紹~
算術(shù)表達式
算術(shù)運算符加(+)減(-)乘(*)除(/)模(%)也叫余环鲤。
首先,我們拋開前面復(fù)雜的概念憎兽,單純來理解這些運算符冷离。要知道的是,運算符具有隱式轉(zhuǎn)換的作用。這些算術(shù)運算符都希望自己左右兩側(cè)操作數(shù)是數(shù)值纯命,所有會對非數(shù)值的操作是轉(zhuǎn)換為數(shù)組西剥,轉(zhuǎn)換的規(guī)則可以參考我之前寫的文章。所有無法轉(zhuǎn)換為數(shù)字的操作數(shù)都會轉(zhuǎn)換成NaN值亿汞。如果操作數(shù)是NaN的話瞭空,那么算術(shù)運算符的結(jié)果也為NaN.
+運算符既可以對兩個數(shù)字做加法運算,也可以做字符串連接
1+1 //2
“a”+1 //"a1"
注意疗我,當(dāng)+左右兩側(cè)操作符有一個是字符串的時候咆畏,那么他們就會做字符串連接了。還有()可以改變運算符的運算順序吴裤,例如
1+1+“a” //"2a"
1+(1+"a") //11a
其他的運算也是類似旧找,這里我們重點強調(diào)下%求余運算符,直接上代碼
3%3 //0
4%3 //1
5%3 //2
6%3 //0
就是求余的操作麦牺。
一元算術(shù)運算符
算術(shù)運算符還有個可以操作與單獨的操作數(shù)钮蛛,并產(chǎn)生一個新值,這就是一元運算符剖膳。常見有++(遞增) 魏颓、--(遞減)、+(加)吱晒、(-)減法甸饱,其中加+和-即使一元運算符也是二元運算符。+可以對操作數(shù)轉(zhuǎn)換為數(shù)字枕荞,并返回這個數(shù)字柜候,-可以對操作數(shù)轉(zhuǎn)換為數(shù)字搞动,并返回這個數(shù)字的同時改變運算結(jié)果的符號。下面我們重點關(guān)照++和--渣刷。
++
遞增運算符的操作數(shù)可以再操作符的左側(cè)也可以再右側(cè)鹦肿。以此根據(jù)分別稱之為前增量和后增量。
下面我們來看一個直觀的例子來這兩個
var i=1;
var j=++i
console.log(i+" "+j); //2 2
var a=1;
var b=a++;
console.log(a+" "+b); //2 1
區(qū)別:前增量對操作數(shù)進行增量計算辅柴,并且返回計算后的值箩溃。后增量對操作數(shù)進行增量計算,但返回為增量計算的值碌嘀。
同理--(遞減也是同樣道理)
var x=2;
var y=--x;
console.log(x+" "+y);
var c=2;
var d=c++;
console.log(c+" "+d);
關(guān)系表達式
關(guān)系運算符呢用于測試兩個值的關(guān)系涣旨,他們間的關(guān)系有相等、小于股冗、屬性從屬關(guān)系等等霹陡,關(guān)系運算符會根據(jù)兩個值的關(guān)系是否存在而返回true或者false。他們總是會返回一個布爾值
==(相等)和===(全等運算符)運算符用于比較兩個值是否相等止状。他們允許任意類型的操作數(shù)烹棉,如果操作數(shù)相等則返回true,否則返回false.===全等是嚴格相等的運算符怯疤,它操作兩個數(shù)是否嚴格相等浆洗,當(dāng)然啦,相等和嚴格相等也是有個依據(jù)的集峦,我們來仔細理解下伏社。首先,我們把=(等于)放進來一起塔淤,他們都有區(qū)別的
=是賦值(等于)摘昌,==是相等,===是嚴格相等(全等)凯沪;
!=和!==是==和===運算符的求反第焰。
現(xiàn)在我們來理清下什么情況下==和什么情況下===
首先买优,我們先來對全等運算符進行討論妨马,我們在上一篇文章知道,js對象比較就是引用的比較杀赢,而不是值的比較烘跺,對象只和他們本身是相等的,和他們?nèi)魏螌ο蠖疾幌嗟取?/p>
===嚴格運算符首先會計算操作數(shù)的值脂崔,然后比較兩個值滤淳,特別注意的是:全等比較過程中沒有任何的類型轉(zhuǎn)換
也就是說類型不同,值相等或者值相等類型不同都是不全等的
console.log(1==="1");
console.log(undefined===null)
console.log(NaN===NaN)
console.log("true"===true)
console.log(0===-0)
var a={}
var c=a;
console.log(a===c);
var x={"a":1};
var y={"a":1};
console.log(x===y);
大家可以動手嘗試一下砌左,從上面可以測試得出
類型不同脖咐,值相等或者值相等類型不同都是不全等的
NaN和任何數(shù)字都不全等铺敌,即使是它本身
如果兩個數(shù)字,一個為0,一個為-0,那么他們是全等的(我認為是特殊的屁擅,值和類型相等偿凭,但是運算符號不同)
如果兩個應(yīng)用指向同一個對象,那么他們?nèi)扰筛瑁绻赶虿欢畬ο笸淠遥词惯@兩個對象具有同樣的屬性,那么他們也是不全等的胶果。
==相等操作符就沒有全等那樣嚴格了匾嘱,同樣,我們理解下==的操做規(guī)則
如果兩個操作數(shù)是全等的早抠,那么他們一定是相等的霎烙,這個沒有疑問
值相等當(dāng)時類型不同也是相等的,不同類型比較需要先轉(zhuǎn)換為同類型在來比較值
下面我們上代碼蕊连,看看掌握了沒
console.log(1==2);
console.log(1=="1");
console.log(true==1);
console.log(0==false);
console.log(undefined==null)
console.log("true"=="false");
比較運算符
比較運算符用來檢測兩個操作數(shù)的大小關(guān)系(數(shù)組大小或者字母表順序)吼过,也就是說只能對數(shù)值和字符串進行操作,如果操作數(shù)不是數(shù)值或者字符串咪奖,那么他們會像轉(zhuǎn)換成數(shù)值或者字符串進行比較盗忱,具體轉(zhuǎn)換規(guī)則可以參考上幾篇文章。
<小于
如果第一個操作數(shù)小于第二個操作數(shù)則返回true羊赵,否則為false
大于
如果第一個操作數(shù)大于第二個操作數(shù)則返回true趟佃,否則為false
同樣還有小于等于<=和大于等于>=
注意比較字符串的時候,字符串是區(qū)分大小寫的昧捷,所有大寫字符都小于小寫字母闲昭。
console.log(1<2);
console.log(“11”>2);
console.log("one"<3);
這里再次提醒下,NaN和任何數(shù)進行操作返回的結(jié)果都是false.
in運算符
in運算符希望它左邊的操作數(shù)是一個字符串或者可以轉(zhuǎn)換為字符串靡挥,希望他的右側(cè)操作數(shù)是一個對象序矩。如果右側(cè)的對象有一個左側(cè)操作數(shù)值的屬性名,記得是屬性名跋破,那么表達式返回true
var obj={
x:1,
y:2
}
console.log("x" in obj)
console.log("z" in obj);
console.log("toString" in obj)
var arr=[1,2,3]
console.log(“0” in arr);
console.log("1" in arr);
console.log("3" in arr);
要注意是屬性名而不是值簸淀。還有就是toString()是所有對象都擁有的方法,因為他是從object繼承過來的毒返,以后我們會更加仔細來學(xué)習(xí)
instanceof運算符
instanceof運算符用來判斷一個構(gòu)造函數(shù)的prototype屬性所指向的對象是否存在另外一個要檢測對象的原型鏈上租幕,這樣說有點暈,很多剛開始學(xué)習(xí)的人可能很疑惑拧簸,我們先簡單說下劲绪,js在es6之前是沒有真正意義上的類的,什么為類了,我理解是一個抽象的總稱贾富,而由這些抽象的類具象出來的就叫做對象歉眷。好比如:人類(類)和我(對象),動物(類)和貓(具體的個體颤枪,具象化的類姥芥,也就是對象)。
instanceof的左操作數(shù)就是對象汇鞭,右操作數(shù)就是類了凉唐,如果對象是類的實例(具象化的獨立個體),則instanceof返回true,否則為false.有關(guān)與原型霍骄,構(gòu)造函數(shù)台囱,類,繼承等等读整,后續(xù)我會專門整理出來簿训,按照我的理解盡量讓讀者看懂,學(xué)到東西哈哈米间。
var obj={};
console.log(obj instanceof Object)
var arr=[];
console.log(arr instanceof Array)
js里用構(gòu)造函數(shù)來模擬類强品。這里我們不深入探討,只要知道instanceof的用法就可以了屈糊,我在準(zhǔn)備些時間的榛,在接下來的專題會更加仔細來學(xué)習(xí)。
關(guān)系表達式就差不錯了逻锐,接下來來一起探究邏輯表達式~求贊夫晌,求收藏
邏輯表達式
邏輯運算符有&&(邏輯與)、||(邏輯非)昧诱、和O怼(邏輯非),他們是對操作數(shù)進行布爾值算術(shù)運算盏档,怎么說了凶掰,因為他們會對“真值”和“假值”進行布爾值轉(zhuǎn)換,從而返回布爾值蜈亩,他們也經(jīng)常和關(guān)系運算符一起配合使用懦窘,組合成更加復(fù)雜的表達式。
邏輯與&&
&&邏輯與有左右兩個的操作數(shù)勺拣,首先奶赠,他會對第一個操作數(shù)進行布爾值運算,“真值”就轉(zhuǎn)換為true,“假值”就轉(zhuǎn)換為false药有。左邊的操作數(shù)為false的時候,&&操作符就不會對右邊的操作數(shù)進行布爾運算,從而直接返回false,如果左邊操作數(shù)為true的話愤惰,那么就會對&&右邊的操作數(shù)進行布爾運算了苇经,如果右邊返回true,則&&操作符,返回true,否則為false.可以理解為“一假必假”宦言。
console.log(true&&false);
console.log(true&&true);
console.log(false&&false);
console.log(false&&true);
js在對&&左邊操作數(shù)進行運算時扇单,如果左邊返回false,那么js就會“偷懶”,不會去判斷右邊的操作數(shù)奠旺。
邏輯非||
邏輯非和邏輯與有點類似蜘澜,||對左右兩個操作數(shù)進行布爾運算,當(dāng)左邊操作數(shù)為true的話就會返回true,也會“偷懶”不去計算右邊操作數(shù)响疚,而當(dāng)左邊為false的話鄙信,哪||就會對右邊進行計算,如果右邊為true則返回true,否則為false.只有||前后都是false的時候才返回false忿晕,否則返回true装诡。可以理解為“一真必真”践盼。
console.log(true||false);
console.log(true||true);
console.log(false||false);
console.log(false||true);
console.log(''||1);
console.log(1||2);
這種特性可以做幾個操作
var a='';
...
var b=a||1;
當(dāng)我們不知道a是否改變了鸦采,我們可以用這種技巧,這個和if/else語句類似咕幻,只不過寫的代碼少了渔伯。更加精簡。
邏輯非肄程!
邏輯非咱旱!就是放在操作數(shù)之前并對他的操作數(shù)轉(zhuǎn)換的布爾值進行求反, 比如!A绷耍,如果A是真值吐限,則返回false,如果A是假值,則返回true.并且邏輯非的優(yōu)先級很高褂始,和操作數(shù)緊密綁定在一起诸典。隨便說一下,以下崎苗,對于pq的取值狐粱,等式永遠成立,(來自《JavaScript權(quán)威指南》)
!(p && q)===!p || q;
!(p || q)===!p && !q
賦值表達式
js使用=運算符來給標(biāo)識符(變量或者屬性等)賦值胆数。
var a=1;
a=2;
var b=a;
=具有非常低的優(yōu)先級肌蜻,通常在最后才計算,同時還要注意區(qū)分==和===必尼,在之前我們了解過蒋搜,這里就不說啦篡撵。此外,=運算符還可以和其他運算符進行組合操作豆挽,組合攻擊波有沒有~~~
例如
var a=1;
var b;
b+=a;
console.log(b);
這種和其他運算符組合一起的育谬,都有一個規(guī)律就是
A+=B 等價與 A=A+B
換成其他符號也是如此的,還有-=帮哈、*=膛檀、/=、%=等等娘侍。
條件運算符?:(三元運算符)
不多說咖刃,我直接上個用法,讀者就知道啦~
計算結(jié)果是否為true ? true的時候取這個值(如果為true) : false的時候去這個值(如果為false)憾筏;
var a=1;
var b=(a > 0 ? 3 : 0); //b=3
條件運算符的操作數(shù)有三個嚎杨,其中?前面的會進行布爾運算踩叭,如果為ture的話就返回 磕潮?后 :前的那個操作數(shù),這個例子時3容贝,因為a是大于0的自脯,如果前面的操作數(shù)返回false,那么結(jié)果就是最后一個操作數(shù)了斤富。
如果用if/else語句來解釋的話就好比
var a=1;
var b;
if(a >0 ){
b=3
}else{
b=0
}
同樣的意思膏潮,只不過?:更加精簡了,而且他是一個三元運算符满力,也是目前js中唯一一個三元運算符(以我知識面來說)焕参。
typeof運算符
typeof是一元運算符,放在單個操作數(shù)前面油额,操作數(shù)可以是任意類型叠纷,返回值有如下
[table id=15 /]
typeof也可以加()像函數(shù)一樣用也是可以的,只是要注意的是潦嘶,typeof是運算符涩嚣,不是函數(shù),
typeof(null)
關(guān)于typeof更加深層次的用法掂僵,后續(xù)有設(shè)計~
delete運算符
delete是一元操作符航厚,他是用來刪除對象屬性活著數(shù)組元素的,要記住他是用來做刪除操作的锰蓬,不是用來返回一個值的
var obj={x:1}
delete obj.x;
console.log(obj.x) //false 這個屬性在對象中不再存在
var arr=[1,2.3];
delete arr[2];
console.log(arr) //最后已經(jīng)被刪除了
注意幔睬,用delete刪除數(shù)組的某一項,數(shù)組的長度并沒有改變,芹扭,當(dāng)讀取一個不存在的屬性將返回undefined麻顶,還有delete不能刪除以var 聲明的標(biāo)識符赦抖,和以function函數(shù)什么表達式的函數(shù)。
void運算符
void是一元運算符澈蚌,他會忽略計算寄過并返回undefined,由于void會忽略操作數(shù)的值摹芙,因此再操作數(shù)具有副作用的時候使用void來讓程序更加語義化
最常用的就是
<a href="javascrit:void(0)">超鏈接</a>
讓用戶點擊的時候不必顯示這個表達式的結(jié)果灼狰,當(dāng)然啦宛瞄,具體怎么用還是具體看實際需求啦。
還有不常用的表達式和運算符沒有提到交胚,大家可以去查資料份汗,當(dāng)然有很多術(shù)語,對剛剛接觸的開發(fā)者有點繞蝴簇,但是沒事的杯活,熟能生巧,滴水穿石熬词,只要堅持下去旁钧,什么都不是問題,先打好堅固的基礎(chǔ)哈互拾,現(xiàn)在這篇文章就到這兒結(jié)束啦歪今,又代表新的篇章要開始啦,歡迎交流颜矿,
本文的全部內(nèi)容就到這了寄猩,歡迎大家留言補充。
原創(chuàng)文章骑疆,轉(zhuǎn)載請注明出處田篇,謝謝歡迎一起討論交流
歡迎訪問我的個人網(wǎng)站zhengyepan