★04.表達式和運算符

表達式

原始表達式

  • 原始表達式通常指直接由直接量表示的表達式嘶居。
1.23
"hello"
/pattern/

true
false
null
this

i
sum
undefined

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

  • 對象和數(shù)組初始化表達式 實際上是一個新創(chuàng)建的對象和數(shù)組但狭,這些 初始化表達式 有時稱做 對象直接量數(shù)組直接量 旬渠。
{}
{ topic: "JavaScript", fat: true }

[]
[1 + 2, 3 + 4]

函數(shù)定義表達式

  • 函數(shù)定義表達式 可稱為 函數(shù)直接量
function plus1(x) { return x + 1; }

屬性訪問表達式

  • 屬性訪問表達式 運算得到一個對象屬性或一個數(shù)組元素的值闲延。
var o = {x: 1, y: {z: 3}};
var a = [o, 4, [5, 6]];
o.x
o.y.z
o["x"]
a[1]
a[2]["1"]
a[0].x

調(diào)用表達式

  • 調(diào)用表達式函數(shù)調(diào)用方法調(diào)用 兩種痊剖, 函數(shù)調(diào)用 中的this指的是全局對象,而 方法調(diào)用this則代表著 方法 的對象垒玲。在 ES 5 中邢笙,通過嚴(yán)格模式定義的函數(shù)調(diào)用中,this的值為undefined侍匙。
f(0)
Math.max(x, y, z)
a.sort()

對象創(chuàng)建表達式

  • 對象創(chuàng)建表達式 創(chuàng)建一個對象并調(diào)用一個函數(shù)初始化新對象的屬性。
new Object()
new Point(2, 3)

// 不需要傳入任何參數(shù)給構(gòu)造函數(shù)時叮雳,可以省略括號
new Object
new Date

運算符

  • 大多數(shù)運算符都是符號想暗,少數(shù)非符號的運算符有:deletetypeof帘不,void说莫,instanceofin寞焙。
  • JavaScript 總是嚴(yán)格按照從左至右的順序來計算表達式储狭。

算術(shù)運算符

  • 位運算符有

基本算術(shù)運算符

  • 基本的算術(shù)運算符有:+互婿、-*辽狈、/慈参、%

加法算術(shù)運算符 —— +

  • 加法既可以做數(shù)字運算刮萌,也可以做字符串連接操作驮配。
  • 加法計算規(guī)則:
    • 兩個都是數(shù)字:加法運算。
    • 兩個都是字符串:字符串連接操作着茸。
    • 一個是數(shù)字壮锻,一個是字符串:數(shù)字轉(zhuǎn)化為字符串,字符串連接操作
    • 一個是對象涮阔,另一個是字符串或數(shù)字猜绣,轉(zhuǎn)換規(guī)則如下:
      1. Date類對象會使用toString()轉(zhuǎn)換為字符串。
      2. Date類以外的其他對象會使用以下規(guī)則:
        1. 使用valueOf()轉(zhuǎn)換為數(shù)字敬特。
        2. 若沒有valueOf()掰邢,則使用toString()轉(zhuǎn)換為字符串。
        3. 若沒有既沒有valueOf()也沒有toString()擅羞,【Todo】尸变。
      3. 完成上述轉(zhuǎn)換后,會有三種情況:
        1. 兩個操作數(shù)都是字符串:字符串連接操作减俏。
        2. 兩個操作數(shù)都是數(shù)字:加法運算召烂。
        3. 一個數(shù)字,一個字符串:數(shù)字轉(zhuǎn)換為字符串娃承,進行字符串連接操作奏夫。
    • 兩個操作數(shù)都轉(zhuǎn)換為數(shù)字或者NaN,然后進行加法操作历筝。
  • 加法需要考慮結(jié)合性對運算順序的影響:
1 + 2 + "blind mice"    // => "3 blind mice"

其他算術(shù)運算符 —— -酗昼、*/梳猪、%

  • 操作數(shù)嘗試轉(zhuǎn)換為數(shù)字麻削,若無法轉(zhuǎn)化為數(shù)字就轉(zhuǎn)化為NaN值。
  • 如果操作數(shù)或轉(zhuǎn)換結(jié)果是NaN值春弥,運算結(jié)果也為NaN值呛哟。
  • JavaScript 的除法是浮點型的。
  • 除數(shù)為0-0時匿沛,運算結(jié)果為Infinity-Infinity扫责。
  • 0/0的結(jié)果是NaN
  • %的操作數(shù)通常都是整數(shù)逃呼,但也適用于浮點數(shù)鳖孤。
  • %運算結(jié)果的符號與第一個操作數(shù)相同者娱。

一元算術(shù)運算符 —— +-苏揣、++黄鳍、--

  • 一元算術(shù)運算符有很高的優(yōu)先級,且都是右結(jié)合性的腿准,

位算術(shù)運算符 —— &际起、|^吐葱、~街望、<<>>弟跑、>>>

  • >>右移補零時灾前,由操作數(shù)的符號相關(guān)。
  • >>>右移補零時孟辑,總是補0哎甲。

關(guān)系運算符

  • 關(guān)系運算符根據(jù)關(guān)系是否存在返回truefalse
  • 關(guān)系運算符包括:饲嗽、炭玫、貌虾、吞加、尽狠、衔憨、x

相等與不等運算符 —— ==袄膏、===践图、!=!==

  • ==是相等運算符沉馆。
  • ===是嚴(yán)格相等運算符码党,也稱恒等運算符。
  • !=稱做不相等斥黑,!==稱做不嚴(yán)格相等闽瓢。
  • !=!==運算符的檢測規(guī)則是==!==的運算符的求反。
  • JavaScript 對象比較的是引用心赶,而不是值。
  • ===的比較過程沒有任何類型轉(zhuǎn)換缺猛,有以下重要的比較情況:
    • null === undefined返回false缨叫。
    • NaN === x或者NaN === NaN椭符,返回false。(若x !== x返回true耻姥,則可以判斷xNaN
    • 0 === -0返回true销钝。
    • 如果兩個字符串對應(yīng)為上的16位數(shù)完全相等,則=====返回true琐簇,若兩個字符串顯示出來的字符完全一樣蒸健,但是內(nèi)部編碼的16位數(shù)不一樣,則=====返回false婉商。
    • 如果兩個引用指向同一個對象似忧、數(shù)組或函數(shù),則===返回true丈秩,如果指向不同的對象盯捌、數(shù)組或函數(shù),則===返回false蘑秽,盡管兩個對象饺著、數(shù)組或函數(shù)具有完全一樣的屬性、元素或函數(shù)體肠牲。
  • =====類似幼衰,但是==不嚴(yán)格,有以下重要的比較情況:
    • 兩個操作數(shù)的類型相同缀雳,則返回結(jié)果與===一致渡嚣。
    • 如果兩個操作數(shù)類型不同:
      • null == undefined返回true
      • 如果是布爾值俏险,則先轉(zhuǎn)換為數(shù)字再進行比較严拒。true轉(zhuǎn)換為1flase轉(zhuǎn)換為0竖独。
      • 一個數(shù)字裤唠,一個字符串:字符串轉(zhuǎn)換為數(shù)字,比較數(shù)字莹痢。
      • 如果一個是對象种蘸,另一個是數(shù)字或字符串,則使用以下轉(zhuǎn)換規(guī)則:
        1. Date類對象會使用toString()轉(zhuǎn)換為字符串竞膳。
        2. Date類以外的其他對象會使用以下規(guī)則:
          1. 使用valueOf()轉(zhuǎn)換為數(shù)字航瞭。
          2. 若沒有valueOf(),則使用toString()轉(zhuǎn)換為字符串坦辟。
          3. 若沒有既沒有valueOf()也沒有toString()刊侯,【Todo】。
        3. 完成上述轉(zhuǎn)換后锉走,會有三種情況:
          1. 兩個操作數(shù)都是字符串:比較字符串滨彻。
          2. 兩個操作數(shù)都是數(shù)字:比較數(shù)字藕届。
          3. 一個數(shù)字,一個字符串:字符串轉(zhuǎn)換為數(shù)字亭饵,比較數(shù)字休偶。
      • 對于其他不同類型的操作數(shù),==返回false辜羊。

比較運算符 —— <踏兜、><=八秃、>=

  • 比較操作符的操作數(shù)可能是任意類型碱妆,但是只有數(shù)字和字符串才能真正執(zhí)行比較操作。
  • <=>的取反喜德,>=<的取反山橄,只有一個例外,操作數(shù)有NaN時舍悯,返回值為false航棱。
  • 比較規(guī)則:
    • 兩個都是數(shù)字:
      • 0-0是相等的。
      • Infinity比任何值(除了自身)以外都大萌衬。
      • -Infinity比任何值(除了自身)以外都小饮醇。
      • 其中一個是NaN的話,返回false秕豫。
    • 兩個都是字符串:比較兩個由16位值組成的序列朴艰。注意Unicode定義的字符編碼中文不是按照拼音順序的,英文則是所有大寫字母小于小寫字母混移§羰可以采用String.localCompare()解決問題。
    • 一個是數(shù)字歌径,一個是字符串:字符串轉(zhuǎn)換為數(shù)字毁嗦,比較數(shù)字。
    • 轉(zhuǎn)換規(guī)則如下:
      • 如果操作數(shù)是對象回铛,則按照如下轉(zhuǎn)換規(guī)則:
        1. Date類對象會使用toString()轉(zhuǎn)換為字符串狗准。
        2. Date類以外的其他對象會使用以下規(guī)則:
          1. 使用valueOf()轉(zhuǎn)換為數(shù)字。
          2. 若沒有valueOf()茵肃,則使用toString()轉(zhuǎn)換為字符串腔长。
          3. 若沒有既沒有valueOf()也沒有toString(),【Todo】验残。
        3. 完成上述轉(zhuǎn)換后捞附,會有三種情況:
          1. 兩個操作數(shù)都是字符串:比較字符串。
          2. 兩個操作數(shù)都是數(shù)字:比較數(shù)字。
          3. 一個數(shù)字鸟召,一個字符串:字符串轉(zhuǎn)換為數(shù)字想鹰,比較數(shù)字。

in運算符

  • 左操作數(shù)是一個字符串或可以轉(zhuǎn)換為字符串药版,右操作數(shù)是一個對象。
  • 如果右操作數(shù)對象有一個名為左操作數(shù)的屬性名喻犁,表達式返回true槽片。
var point = {x : 1, y : 1};

"x" in point            // true
"z" in point            // false
"toString" in point     // true

var data = [7, 8, 9];
"0" in data             // true
1 in data               // true
3 in data               // false

instanceof運算符

  • 左操作數(shù)是對象,右操作數(shù)是標(biāo)識類的函數(shù)肢础。
  • 如果左操作數(shù)不是對象还栓,返回false,如果右操作數(shù)不是函數(shù)传轰,拋出一個 類型錯誤異常 剩盒。
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

邏輯運算符 —— &&||慨蛙、!

  • C語言 的短路規(guī)則辽聊。

賦值運算符 —— =+=期贫、-=

  • 帶操作的賦值運算符有:+=跟匆、-=*=通砍、/=玛臂、%=<<=封孙、>>=迹冤、>>>=&=虎忌、|=泡徙、^=

表達式計算 —— eval()

  • eval()只有一個參數(shù)呐籽,如果傳入的參數(shù)不是字符串锋勺,它直接返回這個參數(shù)。
  • eval()如果參數(shù)是字符串狡蝶,它會把字符串當(dāng)作 JavaScript 代碼編譯庶橱,如果編譯失敗則拋出一個 語法錯誤異常 。如果編譯成功贪惹,則開始執(zhí)行這段代碼苏章。
  • eval()的返回值為這個字符串最后一個表達式或語句的值,如果最后一個表達式或語句沒有值,則最終返回undefined枫绅。
  • 如果執(zhí)行的字符串拋出異常泉孩,這個異常會傳遞給eval()
  • eval()使用了調(diào)用它的變量作用域環(huán)境并淋,如下代碼示例:
x = 1;
eval("x = 2")       // 改變局部變量x的值
  • 如果在再最頂層代碼中調(diào)用eval()寓搬,當(dāng)然它會作用于全局變量和全局函數(shù)。
  • 以下代碼是錯誤的:
var foo = function(a) {
    eval(a);
};
foo("return; ");    // eval()的上下文環(huán)境就是函數(shù)調(diào)用的環(huán)境县耽,即全局環(huán)境句喷,在全局上下文中使用return會報錯
  • 直接eval :直接調(diào)用eval()
  • 間接eval :通過別名來間接調(diào)用eval()兔毙。
  • ES3
    • 直接eval :在調(diào)用它的上下文作用域中執(zhí)行唾琼,也叫 局部eval()
    • 間接eval :禁止使用 間接eval 澎剥,若使用會拋出一個 EvalError異常 锡溯。
  • ES5
    • 直接eval :在調(diào)用它的上下文作用域中執(zhí)行,也叫 局部eval() 哑姚。
    • 間接eval :使用全局對象作為其上下文作用域祭饭,并且無法讀、寫蜻懦、定義局部變量和函數(shù)甜癞,也叫 全局eval()
  • ES5 嚴(yán)格模式:
    • 直接eval :可以查詢和更改局部變量宛乃,但是不能定義新的變量或函數(shù)悠咱。
    • 間接eval : 禁止使用 間接eval ,若使用會拋出一個 EvalError異常 征炼。
var geval = eval;
var x = "global", y = "global";
function f() {
    var x = "local";
    eval("x += 'change';");     // 此x是局部x
    return x;
}

function g() {
    var y = "local";
    geval("y += 'changed';");   // 此y是全局y
    return y;
}

console.log(f(), x);
console.log(g(), y);
  • 通常不用eval()析既,如果真的要用,更可能是用 全局eval() 而不是 局部eval() 谆奥。

其他運算符

typeof()運算符

  • 接受一個任意類型的操作數(shù)眼坏,返回一個表示操作數(shù)類型的字符串。
  • switch語句中非常有用酸些。
x typeof(x)
undefined "undefined"
null "object"
true或false "boolean"
任意數(shù)字或NaN "number"
任意字符串 "string"
任意函數(shù) "function"
任意內(nèi)置對象(非函數(shù)) "object"
任意宿主對象 由編譯器各自實現(xiàn)的字符串

delete運算符

  • delete用來刪除對象的屬性或者數(shù)組元素宰译。
  • C++ 中的delete完全不同。
  • delete刪除數(shù)組元素后魄懂,數(shù)組長度依舊不變沿侈。
  • delete返回值:
    • 若操作數(shù)不是左值,不進行任何操作并返回true市栗。
    • 若操作數(shù)是左值缀拭,如果刪除成功返回true咳短,刪除失敗返回false
  • 不能使用delete刪除的有:
    • 內(nèi)置核心和客戶端屬性蛛淋。
    • 使用var聲明的變量咙好。
    • 函數(shù)。
    • 函數(shù)參數(shù)褐荷。
  • ES5 嚴(yán)格模式:非法的delete會報錯勾效。
var o = {x : 1, y : 2};
delete o.x;
o.y = undefined
"x" in o                    // false
"y" in o                    // true

var a = [1, 2, 3];
delete a[2];
2 in a;                     // false
a.length                    // 3:依舊是3

void運算符

  • 忽略表達式的計算結(jié)果并返回undefined
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末叛甫,一起剝皮案震驚了整個濱河市葵第,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌合溺,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,548評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件缀台,死亡現(xiàn)場離奇詭異棠赛,居然都是意外死亡,警方通過查閱死者的電腦和手機膛腐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,497評論 3 399
  • 文/潘曉璐 我一進店門睛约,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人哲身,你說我怎么就攤上這事辩涝。” “怎么了勘天?”我有些...
    開封第一講書人閱讀 167,990評論 0 360
  • 文/不壞的土叔 我叫張陵怔揩,是天一觀的道長。 經(jīng)常有香客問我脯丝,道長商膊,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,618評論 1 296
  • 正文 為了忘掉前任宠进,我火速辦了婚禮晕拆,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘材蹬。我一直安慰自己实幕,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 68,618評論 6 397
  • 文/花漫 我一把揭開白布堤器。 她就那樣靜靜地躺著昆庇,像睡著了一般。 火紅的嫁衣襯著肌膚如雪吼旧。 梳的紋絲不亂的頭發(fā)上凰锡,一...
    開封第一講書人閱讀 52,246評論 1 308
  • 那天,我揣著相機與錄音,去河邊找鬼掂为。 笑死裕膀,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的勇哗。 我是一名探鬼主播昼扛,決...
    沈念sama閱讀 40,819評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼欲诺!你這毒婦竟也來了抄谐?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,725評論 0 276
  • 序言:老撾萬榮一對情侶失蹤扰法,失蹤者是張志新(化名)和其女友劉穎蛹含,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體塞颁,經(jīng)...
    沈念sama閱讀 46,268評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡浦箱,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,356評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了祠锣。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片酷窥。...
    茶點故事閱讀 40,488評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖伴网,靈堂內(nèi)的尸體忽然破棺而出蓬推,到底是詐尸還是另有隱情,我是刑警寧澤澡腾,帶...
    沈念sama閱讀 36,181評論 5 350
  • 正文 年R本政府宣布沸伏,位于F島的核電站,受9級特大地震影響动分,放射性物質(zhì)發(fā)生泄漏馋评。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,862評論 3 333
  • 文/蒙蒙 一刺啦、第九天 我趴在偏房一處隱蔽的房頂上張望留特。 院中可真熱鬧,春花似錦玛瘸、人聲如沸蜕青。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,331評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽右核。三九已至,卻和暖如春渺绒,著一層夾襖步出監(jiān)牢的瞬間贺喝,已是汗流浹背菱鸥。 一陣腳步聲響...
    開封第一講書人閱讀 33,445評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留躏鱼,地道東北人氮采。 一個月前我還...
    沈念sama閱讀 48,897評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像染苛,于是被迫代替她去往敵國和親鹊漠。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,500評論 2 359

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