JavaScript入門 - 01
准備工作
在正式的學習JavaScript
之前,我們先來學習一些小工具
,幫助我們更好的學習和理解后面的內容。
js代碼位置
首先是如何編寫JavaScript
代碼,說到這,我們首先要來說明一個需要新人們關注的點,因為我們的js
是一門跨平台
的語言,所以說,我們的代碼可以運行在不同的平台
之上。這也就導致了可能相同的代碼放在不同的平台運行就會有所出入。
這里面說的平台其實被稱之為
宿主環境
。
同時,代碼在不同的平台上的運行方式也有所不同。
如果運行在服務端
,那么更多的時候我們需要通過命令行的形式去運行,而如果是代碼運行在客戶端
,則需要通過啟動瀏覽器
來運行代碼。
我們在學習的初期建議是在瀏覽器
中運行代碼,減少學習成本。
首先,我們的js
代碼可以寫在script
標簽內部並且將script
標簽放在網頁的任何位置。
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title></title>
<script>
// js code ...
</script>
</head>
<body>
<script>
// js code ...
</script>
</body>
<script>
// js code ...
</script>
</html>
在上面的代碼中,我們把包含有js
代碼的script
標簽放在了head
標簽、body
標簽、和body
標簽之后的位置。從語法的層面來說,上面的這幾種寫法都是正確的。但是在本教程中較為推薦的寫法是將scirpt
標簽放在body
標簽的閉合標簽的后面。
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title></title>
</head>
<body>
</body>
<script>
// js code ...
</script>
</html>
推薦的原因,是因為
js
代碼經常需要操作html
標簽,而放在后面可以等到html
標簽加載完畢之后再來執行js
代碼。避免因為html
標簽未加載而導致的報錯。
而另外一種寫法是將js
代碼完全的寫在一個后綴名為.js
的文件中。在需要的html
文件中通過script
標簽引入。
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title></title>
</head>
<body>
</body>
// 通過src屬性與script標簽配合引入外部的js文件
<script src="01.js"></script>
</html>
js語句
js
當中的語句表示js
向宿主環境發送的命令。
例如下面的語句是向頁面中輸出計算10 + 2
的結果。
document.write(10+2);
在每一條語句的后面都帶有一個分號,表示語句結束。
當然js
允許我們將分號省略掉,但是無論是從代碼的維護成本還是其他因素考慮,都不建議將每條語句后面的分號省略掉。
需要注意的是,如果分號前面的語句為空,則沒有意義。
; ; ;
類似上面的語句代碼是沒有意義的。
注釋
注釋
是任何編程語言當中必不可少的一環。通過注釋,可以讓我們開發過的代碼具有更好的可讀性,也能變相的提升后期代碼的維護和升級速度。
一般情況下,注釋的內容可以包含很多,例如參數信息
,代碼功能
、使用方式
等等。
在js
中,注釋
分為兩種,一種是單行注釋
,一種是多行注釋
。
單行注釋
通過//
表示,一般寫在語句的后面或者語句的上方。
// 這里是代碼注釋
多行注釋
通過/**/
的形式來創建,一般寫在代碼的上方。
/*
這里是多行注釋...
*/
無論你是一個js
新人,還是一個成熟的老程序員
,合理的應用注釋
都是一個非常好的習慣。
直接量
在js
中,直接使用的量,我們稱之為叫做直接量
。
例如,在代碼中,我們要使用10
,那么這個10
就是一個直接量
。
表達式
一般情況下,表達式
需要得到一個結果。
例如10+2
就是一個表達式,我們在創建這個表達式的時候,就希望得到10+2
的結果。
document.write(10+2);// 通過document.write()方法將10+2這個表達式的結果輸出到網頁當中
輸出方式
我們在編寫js
代碼的時候,經常需要得到計算的值,用以判斷得到的值與我們預期的值是否相符,所以我們需要了解下面的基本的輸出方式。
// console.log() 將內容輸出到瀏覽器的控制台
console.log(10+2);
// document.write() 將內容輸出到網頁當中
document.write(10+2);
通常情況下我們通過
console.log()
這種形式輸出代碼我們稱之為代碼打印
。
彈窗
在js
中,如果你的代碼運行環境是在瀏覽器
當中,那么就可以使用瀏覽器
給我們提供的彈窗。
alert(10+2);
confirm(10+2);
prompt(10+2);
上述的三個彈窗只能夠在運行環境為瀏覽器的情況下使用。
變量
我們上面說到了表達式
,通過表達式
能夠得到計算的結果,但是如果我們計算的邏輯較為復雜,那么如果單純的依賴表達式將會變得不那么方便。
這個時候,就可以使用變量
。
什么是變量
呢?
我們可以把變量
理解為是一個代名詞
或者說叫做臨時的容器
。
我們可以把一個具體的值存入到變量中。那么此時這個變量就代表着我們這個具體的值。我們如果想要重新的使用這個值,不再需要重新的計算或者其他操作,直接使用變量就可以得到之前存儲的這個值。
而想要創建一個變量(也可以說是聲明
一個變量),需要通過var
關鍵字(es6
中通過let
聲明)。
var val = 10 + 2;
在上面的代碼中,我們創建了一個變量val
,並且使用這個變量val
存儲了表達式10+2
的計算結果。那么如果想要第二次使用10+2
的結果,可以直接使用變量val
即可。
console.log(val);// 通過console.log() 輸出val,此時就可以在控制台看到10+2的結果
在我們使用變量
的時候,還有一點需要理解,變量
之所以叫變量,是因為變量
隨時可以根據我們的需要更改其中存儲的值。
var a = 10;
a = 20; // 當我們重新的向變量中存儲數據的時候,不需要再加var
console.log(a); // 此時再打印a結果就為20
需要注意的是,上面我們將變量a
內存儲的數據由10
變成了20
,在重新存儲的過程中,我們並沒有使用var
,那么上面的代碼就相當於我們將20
的值存儲到之前創建的變量a
中。
而如果在重新的存儲的過程中使用了var
,如同下面的案例:
var a = 10; // 第一次聲明變量a
var a = 20; // 再一次通過var聲明變量a,並且使用了var
consoloe.log(a);
需要注意的是,雖然最后的結果和上面的打印結果相同,但是變量a
本質上已經發生了變化。
如果在重新存儲數據的過程中,沒有在變量名前面加var,那么相當於是更改變量a中存儲的值,而如果前面加了var,則相當於重新的創建了一個變量a,並且存儲了20這個數據。
如果采用下面的這種寫法,那么重新創建的變量將會無效:
var x = 1;
var x;
x // 1
變量提升:
JavaScript
引擎的工作方式是,先解析代碼,獲取所有被聲明的變量,然后再一行一行地運行。這造成的結果,就是所有的變量的聲明語句,都會被提升到代碼的頭部
,這就叫做變量提升(hoisting)。
console.log(a);
var a = 1;
上面代碼首先使用console.log
方法,在控制台(console)顯示變量a
的值。這時變量a
還沒有聲明和賦值,所以這是一種錯誤的做法,但是實際上不會報錯。因為存在變量提升,真正運行的是下面的代碼。
var a;
console.log(a);
a = 1;
最后的結果是顯示undefined
,表示變量a
已聲明,但還未賦值。
標識符
標識符(identifier)指的是用來識別各種值的合法名稱。最常見的標識符就是變量名,以及后面要提到的函數名。JavaScript 語言的標識符對大小寫敏感,所以a
和A
是兩個不同的標識符。
標識符有一套命名規則,不符合規則的就是非法標識符。JavaScript 引擎遇到非法標識符,就會報錯。
簡單說,標識符命名規則如下。
- 第一個字符,可以是任意 Unicode 字母(包括英文字母和其他語言的字母),以及美元符號(
$
)和下划線(_
)。 - 第二個字符及后面的字符,除了 Unicode 字母、美元符號和下划線,還可以用數字
0-9
。
下面這些都是合法的標識符。
arg0
_tmp
$elem
π
下面則是一些不合法的標識符:
1a // 第一個字符不能是數字
23 // 同上
*** // 標識符不能包含星號
a+b // 標識符不能包含加號
-d // 標識符不能包含減號或連詞線
需要注意的是,在js
當中,中文也是合法的標識符,但是並不推薦使用。
JavaScript 有一些保留字,不能用作標識符:arguments、break、case、catch、class、const、continue、debugger、default、delete、do、else、enum、eval、export、extends、false、finally、for、function、if、implements、import、in、instanceof、interface、let、new、null、package、private、protected、public、return、static、super、switch、this、throw、true、try、typeof、var、void、while、with、yield。
數據類型
變量
用來臨時存儲數據(如果想要永久的存儲數據,需要通過數據庫)。而在任何一門編程語言當中,數據都是分為不同類型的。就如同人類也分為男人和女人一樣。
下面就來說一下在JavaScript
中數據的不同類型。
在js
當中數據類型分為兩類,一類是原始類型
,一類是引用數據類型
。原始類型
又稱之為基礎數據類型
,引用類型
也稱之為對象類型
。
原始類型
的數據包含有下面幾個:
- Boolean
- Null
- Undefined
- Number
- String
- Symbol(ES6中新增加的內容)
引用類型
的數據包含有下面幾個:
- Object
- Array
- Function
在
js
當中,引用類型
也包括Date
、Math
和RegExp
等內容。
需要注意的是,
JS
當中的原始值並不能夠更改,也就意味着一旦一個原始值創建成功。那么將不能夠進行第二次的值得修改,除非重新創建一個數據。
Boolean
In computer science, a Boolean is a logical data type that can have only the values
true
orfalse
. For example, in JavaScript, Boolean conditionals are often used to decide which sections of code to execute (such as in if statements) or repeat (such as in for loops).
在MDN
中,對於JavaScript
中的布爾值(Boolean)
有上面一段描述,翻譯過來的意思大致如下:
在計算機科學中,布爾值是一種邏輯數據類型,其值只能為真或假。例如,在JavaScript中,布爾條件
常用於決定執行哪一部分代碼(例如在if語句中)或重復(例如在For循環中)。
布爾值
包含有兩個值true
和false
。其中true
表示真
,false
表示假
。
例如我們判斷一個條件,如果這個條件滿足,那么對應着布爾值true
,如果這個條件不滿足,那么就對應着布爾值false
。
下列運算符會返回布爾值:
- 前置邏輯運算符:
!
(Not) - 相等運算符:
===
,!==
,==
,!=
- 比較運算符:
>
,>=
,<
,<=
如果 JavaScript 預期某個位置應該是布爾值,會將該位置上現有的值自動轉為布爾值。轉換規則是除了下面六個值被轉為false
,其他值都視為true
。
undefined
null
false
0
NaN
""
或''
(空字符串)
Null
In computer science, a null value represents a reference that points, generally intentionally, to a nonexistent or invalid object or address. The meaning of a null reference varies among language implementations.
In JavaScript, null is one of the primitive values.
譯文:
在計算機科學中,空值表示一個引用,該引用通常有意指向不存在或無效的對象或地址。空引用的含義因語言實現而異。
在JavaScript中,null是一個基本值(原始數據)。
Null
類型里面只有一個值,就是null
。
關於null
,你可以把它理解為無
,它表示一個空值。
var a = null;
例如上面的代碼當中,你可以理解為此事的變量a表示的值為空。
當我們在一些需要傳遞值的地方,如果我們沒有值進行傳遞,那么就可以傳遞一個
null
,表示傳遞的值為空。
undefined
Undefined
類型當中只有一個值就是undefined
。
在代碼的編寫過程中,一個沒有被賦值的變量的類型就是undefined
。
var a;
console.log(a); // 會在瀏覽器的控制台中輸出undefined
如果一個變量聲明但是沒有被賦值,我們就可以使用typeof
運算符來檢查一下結果.
var a;
console.log(typeof a);// 輸出undefined類型
Number
Number
類型即為數字類型
。
在MDN
中關於Number
類型的描述如下:
根據 ECMAScript 標准,JavaScript 中只有一種數字類型:基於 IEEE 754 標准的雙精度 64 位二進制格式的值(-(263 -1) 到 263 -1)。它並沒有為整數給出一種特定的類型。除了能夠表示浮點數外,還有一些帶符號的值:
+Infinity
,-Infinity
和NaN
(非數值,Not-a-Number)。
JavaScript 內部,所有數字都是以64位浮點數
形式儲存,即使整數也是如此。所以,1
與1.0
是相同的,是同一個數。
1 === 1.0 // true
這就是說,JavaScript 語言的底層根本沒有整數,所有數字都是小數(64位浮點數)。容易造成混淆的是,某些運算只有整數才能完成,此時 JavaScript 會自動把64位浮點數,轉成32位整數,然后再進行運算。
由於浮點數
不是精確的值,所以涉及小數的比較和運算要特別小心。
0.1 + 0.2 === 0.3
// false
0.3 / 0.1
// 2.9999999999999996
(0.3 - 0.2) === (0.2 - 0.1)
// false
數值范圍:
根據標准,64位浮點數的指數部分的長度是11個二進制位,意味着指數部分的最大值是2047(2的11次方減1)。也就是說,64位浮點數的指數部分的值最大為2047,分出一半表示負數,則 JavaScript 能夠表示的數值范圍為21024到2-1023(開區間),超出這個范圍的數無法表示。
如果一個數大於等於2的1024次方,那么就會發生“正向溢出”,即 JavaScript 無法表示這么大的數,這時就會返回Infinity
。
如果一個數小於等於2的-1075次方(指數部分最小值-1023,再加上小數部分的52位),那么就會發生為“負向溢出”,即 JavaScript 無法表示這么小的數,這時會直接返回0。
Math.pow(2, -1075) // 0
下面是一個實際的例子。
var x = 0.5;
for(var i = 0; i < 25; i++) {
x = x * x;
}
x // 0
上面代碼中,對0.5
連續做25次平方,由於最后結果太接近0,超出了可表示的范圍,JavaScript 就直接將其轉為0。
而如果在js
小於-1.7976931348623157E+103088 的時候,就會表示為-Infinity
.
Number當中的特殊值:
1、正零和負零
JavaScript 的64位浮點數之中,有一個二進制位是符號位。這意味着,任何一個數都有一個對應的負值,就連0
也不例外。
JavaScript 內部實際上存在2個0
:一個是+0
,一個是-0
,區別就是64位浮點數表示法的符號位不同。它們是等價的。
-0 === +0 // true
0 === -0 // true
0 === +0 // true
幾乎所有場合,正零和負零都會被當作正常的0
。
+0 // 0
-0 // 0
(-0).toString() // '0'
(+0).toString() // '0'
但是當0
和-0
被充當分母的時候,返回的值是不相等的。
(1 / +0) === (1 / -0) // false
上面的代碼之所以出現這樣結果,是因為除以正零得到+Infinity
,除以負零得到-Infinity
,這兩者是不相等的。
2、NaN
NaN
是 JavaScript 的特殊值,表示“非數字”(Not a Number),主要出現在將字符串解析成數字出錯的場合。
console.log(5 - 'x'); //NaN
需要注意的是,NaN
不是獨立的數據類型,而是一個特殊數值,它的數據類型依然屬於Number
,使用typeof
運算符可以看得很清楚。
需要注意,
NaN
是一個非常狠
的角色,它連自己都不認,也就是說,如果你判斷NaN
是否等於NaN
,答案是否定的,也就是false
,二者根本不想等。
3、Infinity
Infinity
表示為無窮大
。在js
中,如果數值的內容超過了js
所能表示的范圍,就會輸出Infinity
或者-Infinity
。
Number當中的全局方法:
1、parseInt()
parseInt
方法用於將字符串轉為整數。
parseInt('123') // 123
如果字符串頭部有空格,空格會被自動去除。
parseInt(' 81') // 81
如果parseInt
的參數不是字符串,則會先轉為字符串再轉換。
parseInt(1.23) // 1
// 等同於
parseInt('1.23') // 1
字符串轉為整數的時候,是一個個字符依次轉換,如果遇到不能轉為數字的字符,就不再進行下去,返回已經轉好的部分。
parseInt('8a') // 8
parseInt('12**') // 12
parseInt('12.34') // 12
parseInt('15e2') // 15
parseInt('15px') // 15
上面代碼中,parseInt
的參數都是字符串,結果只返回字符串頭部可以轉為數字的部分。
如果字符串的第一個字符不能轉化為數字(后面跟着數字的正負號除外),返回NaN
。
parseInt('abc') // NaN
parseInt('.3') // NaN
parseInt('') // NaN
parseInt('+') // NaN
parseInt('+1') // 1
所以,parseInt
的返回值只有兩種可能,要么是一個十進制整數,要么是NaN
。
2、parseFloat()
parseFloat
方法用於將一個字符串轉為浮點數。
parseFloat('3.14') // 3.14
如果字符串符合科學計數法,則會進行相應的轉換。
parseFloat('314e-2') // 3.14
parseFloat('0.0314E+2') // 3.14
如果字符串包含不能轉為浮點數的字符,則不再進行往后轉換,返回已經轉好的部分。
parseFloat('3.14more non-digit characters') // 3.14
parseFloat
方法會自動過濾字符串前導的空格。
parseFloat('\t\v\r12.34\n ') // 12.34
如果參數不是字符串,或者字符串的第一個字符不能轉化為浮點數,則返回NaN
。
parseFloat([]) // NaN
parseFloat('FF2') // NaN
parseFloat('') // NaN
parseFloat('1avc') // 1
parseFloat('a1') // NaN
上面代碼中,尤其值得注意,parseFloat
會將空字符串轉為NaN
。
這些特點使得parseFloat
的轉換結果不同於Number
函數。
parseFloat(true) // NaN
Number(true) // 1
parseFloat(null) // NaN
Number(null) // 0
parseFloat('') // NaN
Number('') // 0
parseFloat('123.45#') // 123.45
Number('123.45#') // NaN
3、isNaN()
isNaN
方法可以用來判斷一個值是否為NaN
。
isNaN(NaN) // true
isNaN(123) // false
但是,isNaN
只對數值有效,如果傳入其他值,會被先轉成數值。比如,傳入字符串的時候,字符串會被先轉成NaN
,所以最后返回true
,這一點要特別引起注意。也就是說,isNaN
為true
的值,有可能不是NaN
,而是一個字符串。
isNaN('Hello') // true
// 相當於
isNaN(Number('Hello')) // true
4、isFinite()
isFinite
方法返回一個布爾值,表示某個值是否為正常的數值。
isFinite(Infinity) // false
isFinite(-Infinity) // false
isFinite(NaN) // false
isFinite(undefined) // false
isFinite(null) // true
isFinite(-1) // true
除了Infinity
、-Infinity
、NaN
和undefined
這幾個值會返回false
,isFinite
對於其他的數值都會返回true
。
String
將0
個或者任意多
個字符排列起來放在單引號
或者雙引號
當中,就是一個字符串(String)
。
var a = "hello,world!";
var b = 'hello,JavaScript!';
上面的變量a
和b
當中存儲的數據就是字符串
,其中一個使用了單引號,一個使用了雙引號,兩者都是合法的。
單引號字符串的內部,可以使用雙引號。雙引號字符串的內部,可以使用單引號。
'key = "value"'
"It's a long journey"
如果要在單引號字符串的內部,使用單引號,就必須在內部的單引號前面加上反斜杠,用來轉義。雙引號字符串內部使用雙引號,也是如此。
'Did she say \'Hello\'?'
// "Did she say 'Hello'?"
"Did she say \"Hello\"?"
// "Did she say "Hello"?"
由於 HTML 語言的屬性值使用雙引號
,所以很多項目約定JavaScript
語言的字符串只使用單引號
,在這套系列教程中會遵守這個約定。當然,只使用雙引號也完全可以。重要的是堅持使用一種風格,不要一會使用單引號表示字符串,一會又使用雙引號表示。
字符串默認只能寫在一行內,分成多行將會報錯。
'a
b
c'
// SyntaxError: Unexpected token ILLEGAL
上面代碼將一個字符串分成三行,JavaScript 就會報錯。
如果長字符串必須分成多行,可以在每一行的尾部使用反斜杠。
var longString = 'Long \
long \
long \
string';
longString
// "Long long long string"
上面代碼表示,加了反斜杠以后,原來寫在一行的字符串,可以分成多行書寫。但是,輸出的時候還是單行,效果與寫在同一行完全一樣。注意,反斜杠的后面必須是換行符,而不能有其他字符(比如空格),否則會報錯。
連接運算符(+
)可以連接多個單行字符串,將長字符串拆成多行書寫,輸出的時候也是單行。
var longString = 'Long '
+ 'long '
+ 'long '
+ 'string';
轉義字符:
反斜杠(\)在字符串內有特殊含義,用來表示一些特殊字符,所以又稱為轉義符。
需要用反斜杠轉義的特殊字符,主要有下面這些。
\0
:null(\u0000
)\b
:后退鍵(\u0008
)\f
:換頁符(\u000C
)\n
:換行符(\u000A
)\r
:回車鍵(\u000D
)\t
:制表符(\u0009
)\v
:垂直制表符(\u000B
)\'
:單引號(\u0027
)\"
:雙引號(\u0022
)\\
:反斜杠(\u005C
)
如果在一個正常的字符前面加了\
,是沒有效果的。
console.log("\a"); //輸出a
運算符
在編程語言當中,運算符是處理數據的基本方法,能夠根據現有的值得到新的值。
在JavaScript
當中,存在下列的運算符。
- 賦值運算符
- 比較運算符
- 算數運算符
- 位運算符
- 邏輯運算符
- 字符串運算符
- 條件(三元)運算符
- 逗號運算符
- 一元運算符
- 關系運算符
下面我們將逐一的來講解不同的運算符。
這一部分很枯燥,請做好心理准備!
賦值運算符
賦值運算符(assignment operator)基於右值(right operand)的值,給左值(left operand)賦值。
在之前的內容中,我們通過下面的寫法來創建變量。
var a = 10;
上面我們通過=
來將右邊的10
存儲到左邊的變量a身上。而這種操作,我們在編程當中稱之為賦值
。
而=
也就是賦值運算符
。也可以使用鏈式賦值。
var a = b = c = 15;
console.log(a,b,c);//15,15,15
順序是從右向左的進行賦值操作。
下面的列表中包含全部的賦值運算符
。
- 賦值
x = y
- 加賦值
x += y
- 減賦值
x -= y
- 乘賦值
x *= y
- 除賦值
x /= y
- 模賦值
x %= y
- 指數賦值
x **= y
- 左移賦值
x <<= y
- 右移賦值
x >>= y
- 無符號右移賦值
x >>>= y
- 按位與賦值
x &= y
- 按位異或賦值
x ^= y
- 按位或賦值
x |= y
賦值
簡單的賦值運算符,把一個值賦給一個變量。為了把一個值賦給多個變量,可以以鏈式使用賦值運算符。
加賦值
加賦值運算符把一個右值與一個變量
相加,然后把相加的結果賦給該變量。兩個操作數的類型決定了加賦值運算符的行為。算術相加或字符串連接都有可能。
例如:
var x = 10;
var y = 20;
x += y;
console.log(x);
// 相當於
x = x + y;
減賦值
減賦值運算符使一個變量減去右值,然后把結果賦給該變量。
例如:
var x = 10;
var y = 20;
x -= y;
console.log(x); // -10
// 相當於
x = x - y;
乘賦值
乘賦值運算符使一個變量乘以右值,然后把相成的結果賦給該變量。
例如:
var x = 10;
var y = 20;
x *= y;
console.log(x); // 200
// 相當於
x = x * y;
除賦值
除賦值運算符使一個變量除以右值,然后把結果賦給該變量。
例如:
var a = 10;
var b = 20;
a /= b;
console.log(a);
// 相當於
a = a / b;
模賦值
模賦值運算符使一個變量除以右值,然后把余數交給該變量。
var x = 10;
var y = 20;
a %= b;
console.log(a);
//等同於
a = a % b;
指數賦值
指數賦值運算符使一個變量為底數、以右值為指數的指數運算(乘方)結果賦給該變量。
例如:
var x = 2;
var y = 3;
x **= y;
console.log(x); // 8
// 相當於
x = x ** y
剩下的放在后面說到進制的時候再來說。
比較運算符
比較運算符包括下列內容:
- 等於
==
如果兩邊操作數相等時返回true。 - 不等於
!=
如果兩邊操作數不相等時返回true - 全等
===
兩邊操作數相等且類型相同時返回true。 - 不全等
!==
兩邊操作數不相等或類型不同時返回true。 - 大於
>
左邊的操作數大於右邊的操作數返回true - 大於等於
>=
左邊的操作數大於或等於右邊的操作數返回true - 小於
<
左邊的操作數小於右邊的操作數返回true - 小於等於
<=
左邊的操作數小於或等於右邊的操作數返回true
=>
並不是一個運算符,而是箭頭函數。
/*
下面是比較運算符的示例:
*/
// == 相等運算符
console.log(10 == 10); // true
console.log(20 == "20"); // true
// != 不等運算符
console.log(3 != 2); // true
console.log(2 != "hello"); // true
// === 全等
console.log(3 === 3); // true
console.log(3 === "3"); // false 值雖然相等,但是類型不相等。
// !== 不全等
console.log(3 !== "3"); // true
console.log(3 !== 2); // true
// > 大於
console.log(3 > 2); // true
console.log("3" > "4"); // false
// < 小於
console.log(2 < 1); // false
console.log(3 < 4); // true
// >= 大於等於
// <= 小於等於
console.log(2 >= 1); // true
console.log(2 >= 2); // true
console.log(3 <= 3); // true
console.log(3 <= 4); // true
算數運算符
在js
當中,除了提供基礎的+
,-
,*
,/
以外,還提供了一些其他的運算符,下面是所有的算術運算符:
+
加法運算-
減法運算*
乘法運算/
除法運算%
求余運算(求模運算)++
自增運算--
自減運算+
一元正值符-
一元負值符**
指數運算符
例子:
/*
下面是一些算數運算符的案例:
*/
var a,b;
a = 10;
b = 3;
console.log(a + b); // 13
console.log(a - b); // 7
console.log(a * b); // 30
console.log(a / b); // 3.3333333333333335
console.log(a % b); // 1
console.log(++a); // 11 自增|自減符號在前,則先運算,在使用值
console.log(a++); // 11 自增|自減符號在后,則先使用值,在運算
console.log(a); // 12 // 上面a++后a由11變成了12
// 一元正值符,如果操作數不是Number,則嘗試着將操作數轉換為Number
var c = "3";
console.log(+c,typeof +c); // 3 number
// 一元負值負,將一個值變為負數
var d = 3;
console.log(-d); // -3
var e = '3';
console.log(-e,typeof -e); //-3 number 也起到了轉換的效果
console.log(-3 === -e); // true
// 指數運算符
var f = 2;
var x = 3;
console.log(f ** x); // 8 相當於2 的 3 次冪
邏輯運算符
邏輯運算符常用於布爾(邏輯)值之間; 當操作數都是布爾值時,返回值也是布爾值。 不過實際上&&
和||
返回的是一個特定的操作數的值,所以當它用於非布爾值的時候,返回值就可能是非布爾值。
下面是邏輯運算符:
- 邏輯與
(&&)
- 邏輯或
(||)
- 邏輯非
(!)
邏輯與:
邏輯與&&
運算符又稱為且運算符
,往往用於多個表達式之間的求值。
它的運算規則是:如果第一個運算子的布爾值為true
,則返回第二個運算子的值(注意是值,不是布爾值);如果第一個運算子的布爾值為false
,則直接返回第一個運算子的值,且不再對第二個運算子求值。
語法:
exrp1 && exrp2;
邏輯或:
邏輯或||
運算符又稱為或運算符
,同樣用於在多個表達式之間求值。
它的運算規則是:如果第一個運算子的布爾值為true
,則返回第一個運算子的值,且不再對第二個運算子求值;如果第一個運算子的布爾值為false
,則返回第二個運算子的值。
語法:
exrp1 || exrp2
例如:
// 邏輯與
// 當運算符的前后都為條件語句的時候,當條件同時為true,則返回true,否則返回false
var a = 1;
var b = 2;
console.log(a > 0 && b > a); //true 第一個條件判斷為true,第二個條件判斷為true,那么整體返回true
console.log(a > b && b > 1); // false 第一個條件判斷為false,第二個條件判斷為true,整體返回false
console.log(a > 0 && b > 2); // false 第一個條件為true,第二個條件為false,整體返回false
//
console.log("dog" && "cat"); // cat 當運算符的前后是一個直接量的時候,如果運算符前后都為true,則返回第二個直接量
// 邏輯或
console.log(a > b || b > a); //true 其中只要有一個條件成立,那么就會返回true
console.log(a > 2 || b > 2); // false 兩個條件都不成立,所以返回fasle
// 第一個條件如果成立,那么就不會去讀取后面的條件
console.log(a > 0 || b > 2); // true
在上面的兩個邏輯運算符的使用過程中,容易造成短路效果
。
false
&& anything // 被短路求值為falsetrue
|| anything // 被短路求值為true
在上面的短路代碼中,anything部分不會被求值,也就意味着不會對代碼產生任何的影響。
邏輯與運算符和邏輯或的連用:
邏輯與運算符可以多個連用,這時返回第一個布爾值為false
的表達式的值。如果所有表達式的布爾值都為true
,則返回最后一個表達式的值。
true && 'foo' && '' && 4 && 'foo' && true
// ''
1 && 2 && 3
// 3
上面代碼中,例一里面,第一個布爾值為false
的表達式為第三個表達式,所以得到一個空字符串。例二里面,所有表達式的布爾值都是true
,所有返回最后一個表達式的值3
。
運算符可以多個連用,這時返回第一個布爾值為true
的表達式的值。如果所有表達式都為false
,則返回最后一個表達式的值。
false || 0 || '' || 4 || 'foo' || true
// 4
false || 0 || ''
// ''
上面代碼中,例一里面,第一個布爾值為true
的表達式是第四個表達式,所以得到數值4。例二里面,所有表達式的布爾值都為false
,所以返回最后一個表達式的值。
邏輯或運算符
通常情況下用於給一個變量設置默認值。
var a = username || "zhangsan";
邏輯非:
邏輯非(!)
運算符又叫取反運算符
,就是取一個值的反值。主要用於將一個布爾值變為相反值。即true
變為false
,false
變為true
。
如果使用取反運算符的值不是一個布爾值,那么取反運算符就會將其變為一個布爾值,然后再取反。
下面的六個值使用取反運算符取反后都為true
,其他都為false
。
undefined
null
false
0
NaN
- 空字符串
('')
!undefined // true
!null // true
!0 // true
!NaN // true
!"" // true
!54 // false
!'hello' // false
![] // false
!{} // false
不管什么類型的值,經過取反運算后都會變成布爾值。
如果對一個值連續做兩次的取反運算,等於將其轉換為對應的布爾值,與
Boolean
函數的作用相同。這是一種較為常見的類型轉換的方法。例如:
var a = "hello"; console.log(!!a); // true
字符串運算符
字符串運算符
指的是+
,通過加號,我們可以對兩個字符串進行拼接從而返回一個新的字符串。
var a = "hello,";
var b = "world!";
console.log(a + b); // hello,world!
也可以采用簡寫的形式來拼接字符串。
var str = "hello,";
var str += "world!";
console.log(str); // hello,world!
我們也可以在使用的過程中進行數據的拼接。
var sayHello = "hello,my name is ";
console.log(sayHello + "zhangsan");// hello,my name is zhangsan
條件運算符
條件運算符
也稱之為三元運算符
。
條件運算符是JavaScript中唯一需要三個操作數的運算符。運算的結果根據給定條件在兩個值中取其一。語法為:
條件 ? 值1 : 值2
如果條件
為真,則結果取值1
。否則為值2
。你能夠在任何允許使用標准運算符的地方使用條件運算符。
var status = (age >= 18) ? "adult" : "minor";
當 age
大於等於18的時候,將“adult”賦值給 status
;否則將“minor”賦值給 status
。
逗號運算符
逗號操作符(,)對兩個操作數進行求值並返回最終操作數的值。它常常用在 for 循環中,在每次循環時對多個變量進行更新。
當然,我們在console.log()
的過程中,如果輸出多個值,也會用到逗號運算符。
console.log("hello","world");
一元操作符
一元操作符僅對應一個操作數。
常用的一元操作符有如下幾個:
- delete
- typeof
- void
delete
主要用於刪除對象當中的某個元素。
void
主要用於表明一個運算沒有返回值。
例如:
var trees = new Array("redwood", "bay", "cedar", "oak", "maple");
delete trees[3]; // 刪除數組當中的一個元素
<a href="javascript:void(0)">Click here to do nothing</a> // 用戶點擊這個鏈接不會有任何效果
上面的demo中的兩個運算符,我們暫時還沒有用到,所以可以先放在這,后面再來理解。
至於typeof
運算符,主要用來查看數據的類型,將獲取的數據類型以一個字符串的形式展示出來。
var a = "hello,world!";
console.log(typeof a); // "string"
var b = 13;
console.log(typeof (b)); // "number"
在上面的demo中,我們發現typeof
有兩種使用方式。運算符后面的括號可以選擇省略或者不省略。
案例:
console.log(typeof "hello,world"); // "string"
console.log(typeof 10); // "number"
console.log(typeof true); // "boolean"
console.log(typeof false); // "boolean"
console.log(typeof null); // "object"
console.log(typeof undefined); // "undefined"
// 查看typeof返回的數據的類型
console.log(typeof typeof(10)); // "string"
關系操作符
關系操作符對操作數進行比較,根據比較結果真或假,返回相應的布爾值。
下面是關系操作符
的具體內容:
-
in
-
instanceof
運算符優先級
運算符的優先級,用於確定一個表達式的計算順序。在你不能確定優先級時,可以通過使用括號顯式聲明運算符的優先級。
下表列出了描述符的優先級,從最高到最低。
Operator type | Individual operators |
---|---|
member | . [] |
call / create instance | () new |
negation/increment | ! ~ - + ++ -- typeof void delete |
multiply/divide | * / % |
addition/subtraction | + - |
bitwise shift | << >> >>> |
relational | < <= > >= in instanceof |
equality | == != === !== |
bitwise-and | & |
bitwise-xor | ^ |
bitwise-or | | |
logical-and | && |
logical-or | || |
conditional | ?: |
assignment | = += -= *= /= %= <<= >>= >>>= &= ^= |= |
comma | , |
數據類型轉換
JavaScript 是一種動態類型語言,變量沒有類型限制,可以隨時賦予任意值。
例如:
var a = 10; // 創建一個變量a,並且賦值為10
a = "hello,world!"; // 將"hello,world"重新賦值給變量a,這樣a就由number變為string
再來看下面這個案例:
var x = y ? 1 : 'a';
上面代碼中,變量x
到底是數值還是字符串,取決於另一個變量y
的值。y
為true
時,x
是一個數值;y
為false
時,x
是一個字符串。這意味着,x
的類型沒法在編譯階段就知道,必須等到運行時才能知道。
雖然變量的數據類型是不確定的,但是各種運算符對數據類型是有要求的。如果運算符發現,運算子的類型與預期不符,就會自動轉換類型。比如,減法運算符預期左右兩側的運算子應該是數值,如果不是,就會自動將它們轉為數值。
'4' - '3' // 1
上面代碼中,雖然是兩個字符串相減,但是依然會得到結果數值1
,原因就在於 JavaScript 將運算子自動轉為了數值。
在章節,我們將會先來講解手動強制類型轉換數據類型
,接着會說到數據類型的自動轉換規則
。
強制類型轉換
強制轉換主要指使用Number()
、String()
和Boolean()
三個函數,手動將各種類型的值,分別轉換成數字、字符串或者布爾值。
Number()
使用Number
函數,可以將任意類型的值轉化成數值。
下面分成兩種情況討論,一種是參數是原始類型的值,另一種是參數是對象。
原始類型值:
下面通過案例來演示一下原始類型值轉換為Number類型的規則:
// 數值:轉換后還是原來的值
Number(324) // 324
// 字符串:如果可以被解析為數值,則轉換為相應的數值
Number('324') // 324
// 字符串:如果不可以被解析為數值,返回 NaN
Number('324abc') // NaN
// 空字符串轉為0
Number('') // 0
// 布爾值:true 轉成 1,false 轉成 0
Number(true) // 1
Number(false) // 0
// undefined:轉成 NaN
Number(undefined) // NaN
// null:轉成0
Number(null) // 0
Number函數會自動過濾一個字符串前導和后綴的空格。
對象:
簡單的規則是,Number方法的參數是對象時,將返回NaN,除非是包含單個數值的數組。
Number({a: 1}) // NaN
Number([1, 2, 3]) // NaN
Number([5]) // 5
String()
String
函數可以將任意類型的值轉化成字符串,轉換規則如下。
(1)原始類型值
- 數值:轉為相應的字符串。
- 字符串:轉換后還是原來的值。
- 布爾值:true轉為字符串"true",false轉為字符串"false"。
- undefined:轉為字符串"undefined"。
- null:轉為字符串"null"。
String(123) // "123"
String('abc') // "abc"
String(true) // "true"
String(undefined) // "undefined"
String(null) // "null"
(2)對象:
String
方法的參數如果是對象,返回一個類型字符串;如果是數組,返回該數組的字符串形式。
String({a: 1}) // "[object Object]"
String([1, 2, 3]) // "1,2,3"
Boolean()
Boolean()
函數可以將任意類型的值轉為布爾值。
它的轉換規則相對簡單:除了以下五個值的轉換結果為false
,其他的值全部為true
。
undefined
null
0
(包含-0
和+0
)NaN
''
(空字符串)
Boolean(undefined) // false
Boolean(null) // false
Boolean(0) // false
Boolean(NaN) // false
Boolean('') // false
當然,true
和false
這兩個布爾值不會發生變化。
Boolean(true) // true
Boolean(false) // false
注意,所有對象(包括空對象)的轉換結果都是true
,甚至連false
對應的布爾對象new Boolean(false)
也是true
Boolean({}) // true
Boolean([]) // true
Boolean(new Boolean(false)) // true
所有對象的布爾值都是true
,這是因為 JavaScript 語言設計的時候,出於性能的考慮,如果對象需要計算才能得到布爾值,對於obj1 && obj2
這樣的場景,可能會需要較多的計算。為了保證性能,就統一規定,對象的布爾值為true
。
自動類型轉換
上面說完了強制類型轉換,再來說下自動類型轉換,它是以強制類型轉換為基礎的。
遇到以下三種情況時,JavaScript 會自動轉換數據類型,即轉換是自動完成的,用戶不可見。
第一種情況,不同類型的數據互相運算。
123 + 'abc' // "123abc"
第二種情況,對非布爾值類型的數據求布爾值。
if ('abc') {
console.log('hello')
}
第三種情況,對非數值類型的值使用一元運算符(即+
和-
)。
var a = "10";
console.log(+ a,typeof +a); // 10 "number"
+ {foo: 'bar'} // NaN
- [1, 2, 3] // NaN
自動轉換的規則是這樣的:預期什么類型的值,就調用該類型的轉換函數。比如,某個位置預期為字符串,就調用String
函數進行轉換。如果該位置即可以是字符串,也可能是數值,那么默認轉為數值。
由於自動轉換具有不確定性,而且不易除錯,建議在預期為布爾值、數值、字符串的地方,全部使用Boolean
、Number
和String
函數進行顯式轉換。
自動轉換為布爾值
JavaScript 遇到預期為布爾值的地方(比如if
語句的條件部分),就會將非布爾值的參數自動轉換為布爾值。系統內部會自動調用Boolean
函數。
因此除了以下五個值,其他都是自動轉為true
。
undefined
null
+0
或-0
NaN
''
(空字符串)
下面這個例子中,條件部分的每個值都相當於false
,使用否定運算符后,就變成了true
。
if ( !undefined
&& !null
&& !0
&& !NaN
&& !''
) {
console.log('true');
} // true
下面兩種寫法,有時也用於將一個表達式轉為布爾值。它們內部調用的也是Boolean
函數。
// 寫法一
expression ? true : false
// 寫法二
!! expression
自動轉換為字符串
JavaScript 遇到預期為字符串的地方,就會將非字符串的值自動轉為字符串。具體規則是,先將復合類型的值轉為原始類型的值,再將原始類型的值轉為字符串。
字符串的自動轉換,主要發生在字符串的加法運算時。當一個值為字符串,另一個值為非字符串,則后者轉為字符串。
'5' + 1 // '51'
'5' + true // "5true"
'5' + false // "5false"
'5' + {} // "5[object Object]"
'5' + [] // "5"
'5' + function (){} // "5function (){}"
'5' + undefined // "5undefined"
'5' + null // "5null"
這種自動轉換很容易出錯。
var obj = {
width: '100'
};
obj.width + 20 // "10020"
上面代碼中,開發者可能期望返回120
,但是由於自動轉換,實際上返回了一個字符10020
。
自動轉換為數值
JavaScript 遇到預期為數值的地方,就會將參數值自動轉換為數值。系統內部會自動調用Number
函數。
除了加法運算符(+
)有可能把運算子轉為字符串,其他運算符都會把運算子自動轉成數值。
'5' - '2' // 3
'5' * '2' // 10
true - 1 // 0
false - 1 // -1
'1' - 1 // 0
'5' * [] // 0
false / '5' // 0
'abc' - 1 // NaN
null + 1 // 1
undefined + 1 // NaN
上面代碼中,運算符兩側的運算子,都被轉成了數值。
注意:
null
轉為數值時為0
,而undefined
轉為數值時為NaN
。
一元運算符也會把運算子轉成數值。
+'abc' // NaN
-'abc' // NaN
+true // 1
-false // 0
小練習:
1、為抵抗洪水,戰士連續作戰89小時,編程計算共多少天零多少小時?
var sum_hour = 89;
var day = parseInt(89 / 24);
var hour = 89 % 24 ;
console.log("共計用了" + day + "天" + hour + "小時");
2、小明要到美國旅游,可是那里的溫度是以華氏度為單位記錄的。
它需要一個程序將華氏溫度(80度)轉換為攝氏度,並以華氏度和攝氏度為單位分別顯示該溫度。
提示:攝氏度與羋氏度的轉換公式為:攝氏度 = 5/9.0*(華氏度-32)保留3位小數
var a_temperature = 80;
var local_c = ( 5 / 9.0 * ( a_temperature - 32) ) .toFixed(3);
console.log("當前的溫度是:"+local_c+"攝氏度");
3、計算兩個文本框內數字的和
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>兩個文本框內的和</title>
</head>
<body>
<input type="text" name="v1" placeholder="請輸入第一個數值" id="v1"> +
<input type="text" name="v2" placeholder="請輸入第二個數值" id="v2"> =
<input type="text" name="add_v" value="當前的數值之和是:" id="add_v">
<button onclick="add()">點擊計算</button>
</body>
<script>
function add(){
// 獲取三個輸入框元素
var v1,v2,v3;
v1 = document.getElementById("v1");
v2 = document.getElementById("v2");
v3 = document.getElementById("add_v");
var add = Number(v1.value) + Number(v2.value);
v3.value = "當前的數值之和是:" + add;
}
</script>
</html>
3、計算 var k=0; console.log(k++ + ++k +k +k++);
結果是6
。
4、計算兩個文本框的加減乘除
要求:1) 使用parseInt方法類型轉換
2) 計算結果使用Math.round方法四舍五入