一、JS概述
關于JavaScript的歷史,語言特點,略。
二、JavaScript的組成
JavaScript是ECMAScript、文檔對象模型(document object model:DOM)、瀏覽器對象模型(brower object model:BOM)由三部分構(gòu)成,其核心是ECMAScript,它描述了該語言的語法和基本對象;DOM 描述了處理網(wǎng)頁內(nèi)容的方法和接口,通過 DOM,可以訪問所有的 HTML 元素,連同它們所包含的文本和屬性,可以對其中的內(nèi)容進行修改和刪除,同時也可以創(chuàng)建新的元素;BOM 描述了與瀏覽器進行交互的方法和接口,BOM提供了獨立于內(nèi)容而與瀏覽器窗口進行交互的對象,例如可以移動,調(diào)整瀏覽器大小的window對象,可以用于導航的location對象與history對象,可以獲取瀏覽器,操作系統(tǒng)與用戶屏幕信息的navigator與screen對象,可以使用document作為訪問HTML文檔的入口,管理框架的frames對象等。

三、JavaScript的引入方式
3.1外部引入
在<script></script>標簽里面src=“ ”;中添加鏈接
<script type="text/javascript" src="yuanmi.js">
// 如果鏈接了外部JS文件,script標簽里面的JS代碼就不執(zhí)行了
// 此處不能加JS代碼
</script>
3.2內(nèi)部引入
在script標簽內(nèi)添加
<script type="text/javascript">
<!-- script標簽可以有多個,按順序執(zhí)行 -->
console.log("你好!")
</script>
四、基本概念
1、ECMAscript中的一切(變量、函數(shù)名,操作符)都區(qū)分大小寫
2、標志符(標識符(identifier)指的是用來識別各種值的合法名稱。最常見的標識符就是變量名,以及后面要提到的函數(shù)名):第一個字符必須是一個字母,下劃線、美元符號。其他字符可以是字符、下劃線。美元符號、或者是數(shù)字
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。
3、注釋
- 單行注釋://
- 多行注釋:/* */
4、變量:ECMAscript的變量是松散型的,所謂松散型就是可以用來保存任何類型的數(shù)據(jù)、定義時要用var操作符,如果在函數(shù)中使用var定義一個變量,那么這個變量在函數(shù)退出 后就會被銷毀,如果省略var,那么這個變量就成為全局變量,可以在函數(shù)外的任何一個地方被訪問到,但是,不推薦這么使用。
- 變量是對值的具名引用,變量就是為“值”起名,然后引用這個名字,就等同于引用這個值
- 如果只是聲明變量而沒有賦值,則該變量的值是undefined
- 變量的類型沒有限制,變量可以隨時更改類型。
- 第二次聲明的時候還進行了賦值,則會覆蓋掉前面的值。
- 變量提升:JavaScript 引擎的工作方式是,先解析代碼,獲取所有被聲明的變量,然后再一行一行地運行。這造成的結(jié)果,就是所有的變量的聲明語句,都會被提升到代碼的頭部,這就叫做變量提升。表示變量已聲明,但還未賦值
五、數(shù)據(jù)類型
JavaScript 語言的每一個值,都屬于某一種數(shù)據(jù)類型。JavaScript 的數(shù)據(jù)類型,共有六種。(ES6 又新增了第七種 Symbol 類型的值,本文不涉及。)
- 數(shù)值(number):整數(shù)和小數(shù)(比如1和3.14)
- 字符串(string):文本(比如Hello World)。
- 布爾值(boolean):表示真?zhèn)蔚膬蓚€特殊值,即true(真)和false(假)
- undefined:表示“未定義”或不存在,即由于目前沒有定義,所以此處暫時沒有任何值
- null:表示空值,即此處的值為空。
- 對象(object):各種值組成的集合。
通常,數(shù)值、字符串、布爾值這三種類型,合稱為原始類型(primitive type)的值,即它們是最基本的數(shù)據(jù)類型,不能再細分了。對象則稱為合成類型(complex type)的值,因為一個對象往往是多個原始類型的值的合成,可以看作是一個存放各種值的容器。至于undefined和null,一般將它們看成兩個特殊值。
5.1 undefined
- 1、定義一個變量,但是沒有初始化,會得到undefined
- 2、變量未定義,會得到undefined
- 3、函數(shù)中return不帶任何返回值時,函數(shù)停止執(zhí)行會返回undefined
- 4、函數(shù)參數(shù)arguments,沒有傳遞值的命名參數(shù)將自動被賦予undefined
- 5、對象沒有賦值的屬性
var o = new Object(); o.p // undefined
5.2 Null
- null是只有一個值得數(shù)據(jù)類型,這個特殊值是null
- null值表示一個空對象指針,如果保存對象的變量還沒有真正的保存對象,就應該明確的讓該變量保存null值
特殊情況: - alert(null == undefined)//true
- alert(null === undefined)//false
5.3 Boolean
該類型有2個字面量值true和false,經(jīng)常用在流程控制語句和選擇判斷語句,
常見false值,除了false值都基本都是true
- 1.數(shù)字0、
- 2.NaN、
- 3.“ ”,空字符串
- 4.false
- 5.undefined
- 6.null
下列運算符會返回布爾值: - 前置邏輯運算符: ! (Not)
- 相等運算符:===,!==,==,!=
- 比較運算符:>,>=,<,<=
5.4 Number
1、浮點數(shù):所謂浮點數(shù),就是該數(shù)值中必須包含一個小數(shù)點,且小數(shù)點后面至少有一位數(shù)字,由于保存浮點數(shù)的內(nèi)存空間是保存整數(shù)的2倍,因此,如果小數(shù)點后面沒有任何數(shù)字,或者本身就是一個整數(shù)(1.0),那么該值會被轉(zhuǎn)化成整數(shù),但是浮點數(shù)計算會產(chǎn)生四舍五入誤差的問題。
2、數(shù)值范圍:由于內(nèi)存的限制,ECMAScript 并不能保存世界上所有的數(shù)值。ECMAScript 能夠表示的最小數(shù)值保 存在 Number.MIN_VALUE 中——在大多數(shù)瀏覽器中,這個值是 5e-324;能夠表示的最大數(shù)值保存在 Number.MAX_VALUE 中——在大多數(shù)瀏覽器中,這個值是 1.7976931348623157e+308。如果某次計算的 結(jié)果得到了一個超出 JavaScript 數(shù)值范圍的值,那么這個數(shù)值將被自動轉(zhuǎn)換成特殊的 Infinity 值。具 體來說,如果這個數(shù)值是負數(shù),則會被轉(zhuǎn)換成-Infinity(負無窮),如果這個數(shù)值是正數(shù),則會被轉(zhuǎn) 換成 Infinity(正無窮)。
isFinite():這個函數(shù)在參數(shù)位于最小和最大值之間會返回true
3、NaN
這個數(shù)值表示一個本來要返回數(shù)值的操作數(shù)未返回的情況(這樣不會拋出錯誤)
任何設計NAN的操作都會返回NaN,其次,NaN與任何值都不相等,包括NaN本身
isNaN():任何不能被轉(zhuǎn)化成數(shù)值的值都會導致這個函數(shù)返回true
- 數(shù)值轉(zhuǎn)化
Number():可以轉(zhuǎn)化任何類型數(shù)據(jù)
parseInt():專門用于把字符串轉(zhuǎn)化成整數(shù)
parseFloat():專門用于把字符串轉(zhuǎn)化成浮點數(shù)
5.5 String
多個字符的有序序列,雙引號和單引號引起來的都是字符串
轉(zhuǎn)化成字符串
toString(),String()
兩者區(qū)別:
1、除了null和undefined值,任何值都有toString()
2、toSring()接受一個參數(shù),表示進制
3、String()能夠?qū)⑷魏晤愋偷闹刀嫁D(zhuǎn)換成字符串toString()規(guī)則:值如果有toString,則調(diào)用該方法,如果值是null,則返回“null”,如果值是undefined,返回‘undefined’
六、檢測數(shù)值類型
typeof()
typeof()是用來檢測給定變量的數(shù)據(jù)類型,對一種值使用typeof操作符可能返回下列某個字符串
‘undefined’:這個值未定義
‘boolean’:這個值是布爾類型
‘string’:這個值是字符串
‘number’:這個值是數(shù)值
‘object’:這個值是對象或者null
‘function’:這個值是函數(shù)
typeof操作符用來區(qū)分函數(shù)和其他對象是有必要的
instanceof運算符
Object.prototype.toString方法
七、語句
7.1 條件語句
if語句
// if結(jié)構(gòu)先判斷一個表達式的布爾值,然后根據(jù)布爾值的真?zhèn)?,?zhí)行不同的語句
if (布爾值){
語句;
}
// 或者
if (布爾值) 語句;
if else語句
if (布爾值) {
// 滿足條件時,執(zhí)行的語句
} else {
// 不滿足條件時,執(zhí)行的語句
}
if ...else 語句
if (m === 0) {
// ...
} else if (m === 1) {
// ...
} else if (m === 2) {
// ...
} else {
// ...
}
switch語句
// 選擇執(zhí)行相應的case。如果所有case都不符合,則執(zhí)行最后的default部分
// switch語句內(nèi)部采用的是“嚴格相等運算符”
switch (x) {
case 1:
console.log('x 等于1');
break;
case 2:
console.log('x 等于2');
break;
default:
console.log('x 等于其他值');
}
三元運算符 ?:
// 如果“條件”為true,則返回“表達式1”的值,否則返回“表達式2”的值。
(條件) ? 表達式1 : 表達式2
't' ? 'hello' : 'world' // "hello"
0 ? 'hello' : 'world' // "world"
7.2 循環(huán)語句
while循環(huán)
// While語句包括一個循環(huán)條件和一段代碼塊,只要條件為真,就不斷循環(huán)執(zhí)行代碼塊。
while (條件) {
語句;
}
// 或者
while (條件) 語句;
for 循環(huán)
// 初始化表達式(initialize):確定循環(huán)變量的初始值,只在循環(huán)開始時執(zhí)行一次。
// 條件表達式(test):每輪循環(huán)開始時,都要執(zhí)行這個條件表達式,只有值為真,才繼續(xù)進行循環(huán)。
// 遞增表達式(increment):每輪循環(huán)的最后一個操作,通常用來遞增循環(huán)變量。
for (初始化表達式; 條件; 遞增表達式) {
語句
}
for語句的三個部分(initialize、test、increment),可以省略任何一個,也可以全部省略。
for ( ; ; ){
console.log('Hello World');
}
上面代碼省略了for語句表達式的三個部分,結(jié)果就導致了一個無限循環(huán)。
do while語句:至少執(zhí)行一次
// do...while循環(huán)與while循環(huán)類似,唯一的區(qū)別就是先運行一次循環(huán)體,然后判斷循環(huán)條件。
// 不管條件是否為真,do...while循環(huán)至少運行一次,這是這種結(jié)構(gòu)最大的特點。另外,while語句后面的分號注意不要省略。
do
語句
while (條件);
// 或者
do {
語句
} while (條件);
break 語句和 continue 語句
break語句用于跳出代碼塊或循環(huán)。
continue語句用于立即終止本輪循環(huán),返回循環(huán)結(jié)構(gòu)的頭部,開始下一輪循環(huán)
for (var i = 0; i < 5; i++) {
console.log(i);
if (i === 3)
break;
}
// 0
// 1
// 2
// 3
// 上面代碼執(zhí)行到i等于3,就會跳出循環(huán)
var i = 0;
while (i < 100){
i++;
if (i % 2 === 0) continue;
console.log('i 當前為:' + i);
}
// 上面代碼只有在i為奇數(shù)時,才會輸出i的值。如果i為偶數(shù),則直接進入下一輪循環(huán)
標簽(label)
JavaScript 語言允許,語句的前面有標簽(label),相當于定位符,用于跳轉(zhuǎn)到程序的任意位置.
標簽可以是任意的標識符,但不能是保留字,語句部分可以是任意語句。
標簽通常與break語句和continue語句配合使用,跳出特定的循環(huán)。
top:
for (var i = 0; i < 3; i++){
for (var j = 0; j < 3; j++){
if (i === 1 && j === 1) break top;
console.log('i=' + i + ', j=' + j);
}
}
// i=0, j=0
// i=0, j=1
// i=0, j=2
// i=1, j=0
// break命令后面加上了top標簽(注意,top不用加引號),滿足條件時,直接跳出雙層循環(huán)。如果break語句后面不使用標簽,則只能跳出內(nèi)層循環(huán),進入下一次的外層循環(huán)。
top:
for (var i = 0; i < 3; i++){
for (var j = 0; j < 3; j++){
if (i === 1 && j === 1) continue top;
console.log('i=' + i + ', j=' + j);
}
}
// i=0, j=0
// i=0, j=1
// i=0, j=2
// i=1, j=0
// i=2, j=0
// i=2, j=1
// i=2, j=2
// continue命令后面有一個標簽名,滿足條件時,會跳過當前循環(huán),直接進入下一輪外層循環(huán)。如果continue語句后面不使用標簽,則只能進入下一輪的內(nèi)層循環(huán)。
八、操作符
++ : 自增
++
// 運算子首先轉(zhuǎn)為數(shù)值,然后加上1或者減去1。它們會修改原始變量
// 自增和自減運算符是僅有的兩個具有副作用的運算符,其他運算符都不會改變變量的值
var x = 1;
++x // 2
x // 2
-- : 自減
var x = 2;
--x // 1
x // 1
// 自增和自減運算符有一個需要注意的地方,
// 就是放在變量之后,會先返回變量操作前的值,再進行自增/自減操作;
// 放在變量之前,會先進行自增/自減操作,再返回變量操作后的值
var x = 1;
var y = 1;
// x是先返回當前值,然后自增,所以得到1
x++ // 1
++y // 2
// y是先自增,然后返回新的值,所以得到2
+ :加號操作符
// 1. 用來求兩個數(shù)值的和
// 2. 兩個字符串相加,這時加法運算符會變成連接運算符,返回一個新的字符串,將兩個原字符串連接在一起
// 3. 一個運算子是字符串,另一個運算子是非字符串,這時非字符串會轉(zhuǎn)成字符串,再連接在一起
'3' + 4 + 5 // "345"
3 + 4 + '5' // "75"
// 4. 重載:加法運算符是在運行時決定,到底是執(zhí)行相加,還是執(zhí)行連接。也就是說,運算子的不同,導致了不同的語法行為,這種現(xiàn)象稱為“重載”(overload)
// 5. 對象的相加
// 如果運算子是對象,必須先轉(zhuǎn)成原始類型的值,然后再相加
// 對象轉(zhuǎn)成原始類型的值,首先,自動調(diào)用對象的valueOf方法,一般來說,
// 對象的valueOf方法總是返回對象自身,這時再自動調(diào)用對象的toString方法,將其轉(zhuǎn)為字符串,知道了這個就可以自己定義valueOf方法或toString方法,得到想要的結(jié)果
var obj = { p: 1 };
obj.valueOf().toString() // "[object Object]"
var obj = {
valueOf: function () {
return 1;
}
};
obj + 2 // 3
// 如果運算子是一個Date對象的實例,那么會優(yōu)先執(zhí)行toString方法
var obj = new Date();
obj.valueOf = function () { return 1 };
obj.toString = function () { return 'hello' };
obj + 2 // "hello2"
-:主要用來表示負數(shù)
// 具有將一個值轉(zhuǎn)為數(shù)值的功能,只不過得到的值正負相反
var x = 1;
-x // -1
-(-x) // 1
** : 指數(shù)運算符
// 指數(shù)運算符(**)完成指數(shù)運算,前一個運算子是底數(shù),后一個運算子是指數(shù)。
2 ** 4 // 16
// 指數(shù)運算符是右結(jié)合,而不是左結(jié)合。即多個指數(shù)運算符連用時,先進行最右邊的計算
2 ** 3 ** 2
// 512
乘性操作符
乘法:*
除法: /
求模:%
// 余數(shù)運算符(%)返回前一個運算子被后一個運算子除,所得的余數(shù)
// 運算結(jié)果的正負號由第一個運算子的正負號決定。
// 為了得到負數(shù)的正確余數(shù)值,可以先使用絕對值函數(shù)
-1 % 2 // -1
1 % -2 // 1
// 錯誤的寫法
function isOdd(n) {
return n % 2 === 1;
}
isOdd(-5) // false
isOdd(-4) // false
// 正確的寫法
function isOdd(n) {
return Math.abs(n % 2) === 1;
}
isOdd(-5) // true
isOdd(-4) // false
===: 全等
// 如果兩個值的類型不同,直接返回false
1 === "1" // false
// 同一類型的原始類型的值(數(shù)值、字符串、布爾值)比較時,值相同就返回true,值不同就返回false
1 === 0x1 // true
//NaN與任何值都不相等(包括自身)。另外,正0等于負0
NaN === NaN // false
+0 === -0 // true
// 復合類型值: 兩個復合類型(對象、數(shù)組、函數(shù))的數(shù)據(jù)比較時,不是比較它們的值是否相等,而是比較它們是否指向同一個地址
{} === {} // false
[] === [] // false
(function () {} === function () {}) // false
// 如果兩個變量引用同一個對象,則它們相等。
var v1 = {};
var v2 = v1;
v1 === v2 // true
//對于兩個對象的比較,嚴格相等運算符比較的是地址,而大于或小于運算符比較的是值。
//undefined和null與自身嚴格相等
undefined === undefined // true
null === null // true
var v1;
var v2;
v1 === v2 // true
!==:不全等
// 先求嚴格相等運算符的結(jié)果,然后返回相反值
1 !== '1' // true
// 等同于
!(1 === '1')
==:相等
// 1、原始類型的值會轉(zhuǎn)換成數(shù)值再進行比較
'1' == true // true
// 等同于 Number('1') === Number(true)
// 等同于 1 ===
'true' == true // false
// 等同于 Number('true') === Number(true)
// 等同于 NaN === 1
// 2、對象(這里指廣義的對象,包括數(shù)組和函數(shù))與原始類型的值比較時,對象轉(zhuǎn)換成原始類型的值,再進行比較。
// 對象與數(shù)值比較時,對象轉(zhuǎn)為數(shù)值
[1] == 1 // true
// 等同于 Number([1]) == 1
// 對象與字符串比較時,對象轉(zhuǎn)為字符串
[1] == '1' // true
// 等同于 String([1]) == '1'
[1, 2] == '1,2' // true
// 等同于 String([1, 2]) == '1,2'
// 對象與布爾值比較時,兩邊都轉(zhuǎn)為數(shù)值
[1] == true // true
// 等同于 Number([1]) == Number(true)
[2] == true // false
// 等同于 Number([2]) == Number(true)
// 3、undefined和null與其他類型的值比較時,結(jié)果都為false,它們互相比較時結(jié)果為true
false == null // false
false == undefined // false
0 == null // false
0 == undefined // false
undefined == null // true
// 4、相等運算符的缺點
// 相等運算符隱藏的類型轉(zhuǎn)換,會帶來一些違反直覺的結(jié)果
0 == '' // true
0 == '0' // true
2 == true // false
2 == false // false
false == 'false' // false
false == '0' // true
false == undefined // false
false == null // false
null == undefined // true
' \t\r\n ' == 0 // true
!=: 不等運算符
// 它的算法就是先求相等運算符的結(jié)果,然后返回相反值
1 != '1' // false
// 等同于
!(1 == '1')
>: 大于
//1、是否都是字符串,如果是的,就按照字典順序比較(實際上是比較 Unicode 碼點)
'cat' > 'catalog' // false
//2、如果不是字符串,就會將兩個運算子都轉(zhuǎn)成數(shù)值,再比較數(shù)值的大小
5 > '4' // true
// 等同于 5 > Number('4')
// 即 5 > 4
true > false // true
// 等同于 Number(true) > Number(false)
// 即 1 > 0
2 > true // true
// 等同于 2 > Number(true)
// 即 2 > 1
// 3、這里需要注意與NaN的比較。任何值(包括NaN本身)與NaN比較,返回的都是false。
1 > NaN // false
1 <= NaN // false
'1' > NaN // false
'1' <= NaN // false
NaN > NaN // false
NaN <= NaN // false
// 4、如果運算子是對象,會轉(zhuǎn)為原始類型的值,再進行比較。
[2] > [1] // true
// 等同于 [2].valueOf().toString() > [1].valueOf().toString()
// 即 '2' > '1'
[2] > [11] // true
// 等同于 [2].valueOf().toString() > [11].valueOf().toString()
// 即 '2' > '11'
{ x: 2 } >= { x: 1 } // true
// 等同于 { x: 2 }.valueOf().toString() >= { x: 1 }.valueOf().toString()
// 即 '[object Object]' >= '[object Object]'
小于:<
大于等于:>=
小于等于:<=
= : 賦值操作符
// 將 1 賦值給變量 x
var x = 1;
// 將變量 y 的值賦值給變量 x
var x = y;
// 賦值運算符還可以與其他運算符結(jié)合,形成變體
// 等同于 x = x + y
x += y
// 等同于 x = x - y
x -= y
// 等同于 x = x * y
x *= y
// 等同于 x = x / y
x /= y
// 等同于 x = x % y
x %= y
// 等同于 x = x ** y
x **= y
布爾操作符
! :邏輯非
// 取反運算符是一個感嘆號,用于將布爾值變?yōu)橄喾粗?,即true變成false,false變成true
!true // false
!false // true
!undefined // true
!null // true
!0 // true
!NaN // true
!"" // true
!54 // false
!'hello' // false
![] // false
!{} // false
&&:且運算符
// 如果第一個運算子的布爾值為true,則返回第二個運算子的值(注意是值,不是布爾值);
// 如果第一個運算子的布爾值為false,則直接返回第一個運算子的值,且不再對第二個運算子求值。
't' && 'f' // "f"
't' && (1 + 2) // 3
'' && 'f' // ""
'' && '' // ""
var x = 1;
(1 - 1) && ( x += 1) // 0
x // 1
// 且運算符可以多個連用,這時返回第一個布爾值為false的表達式的值。如果所有表達式的布爾值都為true,則返回最后一個表達式的值
true && 'foo' && '' && 4 && 'foo' && true
// ''
1 && 2 && 3
// 3
||: 或運算符
// 如果第一個運算子的布爾值為true,則返回第一個運算子的值,且不再對第二個運算子求值;
// 如果第一個運算子的布爾值為false,則返回第二個運算子的值
't' || '' // "t"
't' || 'f' // "t"
// 或運算符可以多個連用,這時返回第一個布爾值為true的表達式的值。如果所有表達式都為false,則返回最后一個表達式的值
false || 0 || '' || 4 || 'foo' || true
// 4
false || 0 || ''
// ''
function saveText(text) {
text = text || '';
// ...
}
// 或者寫成
saveText(this.text || '')
本文參考:JavaScript 教程