表達式
原始表達式
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ù)非符號的運算符有:
delete
,typeof
帘不,void
说莫,instanceof
,in
寞焙。
-
JavaScript 總是嚴(yán)格按照從左至右的順序來計算表達式储狭。
算術(shù)運算符
基本算術(shù)運算符
- 基本的算術(shù)運算符有:
+
互婿、-
、*
辽狈、/
慈参、%
。
加法算術(shù)運算符 —— +
- 加法既可以做數(shù)字運算刮萌,也可以做字符串連接操作驮配。
- 加法計算規(guī)則:
- 兩個都是數(shù)字:加法運算。
- 兩個都是字符串:字符串連接操作着茸。
- 一個是數(shù)字壮锻,一個是字符串:數(shù)字轉(zhuǎn)化為字符串,字符串連接操作
- 一個是對象涮阔,另一個是字符串或數(shù)字猜绣,轉(zhuǎn)換規(guī)則如下:
-
Date
類對象會使用toString()
轉(zhuǎn)換為字符串。
- 除
Date
類以外的其他對象會使用以下規(guī)則:
- 使用
valueOf()
轉(zhuǎn)換為數(shù)字敬特。
- 若沒有
valueOf()
掰邢,則使用toString()
轉(zhuǎn)換為字符串。
- 若沒有既沒有
valueOf()
也沒有toString()
擅羞,【Todo】尸变。
- 完成上述轉(zhuǎn)換后,會有三種情況:
- 兩個操作數(shù)都是字符串:字符串連接操作减俏。
- 兩個操作數(shù)都是數(shù)字:加法運算召烂。
- 一個數(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)系是否存在返回
true
或false
。
- 關(guān)系運算符包括:
饲嗽、
炭玫、、
貌虾、吞加、
、尽狠、
衔憨、x
。
相等與不等運算符 —— ==
袄膏、===
践图、!=
、!==
-
==
是相等運算符沉馆。
-
===
是嚴(yán)格相等運算符码党,也稱恒等運算符。
-
!=
稱做不相等斥黑,!==
稱做不嚴(yán)格相等闽瓢。
-
!=
和!==
運算符的檢測規(guī)則是==
和!==
的運算符的求反。
-
JavaScript 對象比較的是引用心赶,而不是值。
-
===
的比較過程沒有任何類型轉(zhuǎn)換缺猛,有以下重要的比較情況:
-
null === undefined
返回false
缨叫。
-
NaN === x
或者NaN === NaN
椭符,返回false
。(若x !== x
返回true
耻姥,則可以判斷x
為NaN
)
-
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)換為1
,flase
轉(zhuǎn)換為0
竖独。
- 一個數(shù)字裤唠,一個字符串:字符串轉(zhuǎn)換為數(shù)字,比較數(shù)字莹痢。
- 如果一個是對象种蘸,另一個是數(shù)字或字符串,則使用以下轉(zhuǎn)換規(guī)則:
-
Date
類對象會使用toString()
轉(zhuǎn)換為字符串竞膳。
- 除
Date
類以外的其他對象會使用以下規(guī)則:
- 使用
valueOf()
轉(zhuǎn)換為數(shù)字航瞭。
- 若沒有
valueOf()
,則使用toString()
轉(zhuǎn)換為字符串坦辟。
- 若沒有既沒有
valueOf()
也沒有toString()
刊侯,【Todo】。
- 完成上述轉(zhuǎn)換后锉走,會有三種情況:
- 兩個操作數(shù)都是字符串:比較字符串滨彻。
- 兩個操作數(shù)都是數(shù)字:比較數(shù)字藕届。
- 一個數(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ī)則:
-
Date
類對象會使用toString()
轉(zhuǎn)換為字符串狗准。
- 除
Date
類以外的其他對象會使用以下規(guī)則:
- 使用
valueOf()
轉(zhuǎn)換為數(shù)字。
- 若沒有
valueOf()
茵肃,則使用toString()
轉(zhuǎn)換為字符串腔长。
- 若沒有既沒有
valueOf()
也沒有toString()
,【Todo】验残。
- 完成上述轉(zhuǎn)換后捞附,會有三種情況:
- 兩個操作數(shù)都是字符串:比較字符串。
- 兩個操作數(shù)都是數(shù)字:比較數(shù)字。
- 一個數(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
邏輯運算符 —— &&
、||
慨蛙、!
賦值運算符 —— =
、+=
期贫、-=
等
- 帶操作的賦值運算符有:
+=
跟匆、-=
、*=
通砍、/=
玛臂、%=
、<<=
封孙、>>=
迹冤、>>>=
、&=
虎忌、|=
泡徙、^=
。
表達式計算 —— 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
。