流程控制(二)
JavaScript的歷史:
在95年以前,就有很多上網的使用者了,當時的頻寬只有28.8kb/s,使用者要進行表單的驗證時,點選提交按鈕,直接就將資料傳送到伺服器了,受限於頻寬的關係,瀏覽器和伺服器的通訊很慢,大概一次通訊需要30s的時間。
這樣,問題就出現了,我們平常註冊一個使用者,需要填寫很多資訊,當我們將所有資訊填寫好,點選提交按鈕後,等待30s以後,提示我們使用者名稱被佔用了,修改,提交,等待30s,提示使用者名稱不符合規範,修改,提交,等待30s,密碼不符合規範,修改,等待。。。這樣的使用者體驗感很差,給網民造成很大的煩惱。隨著上網的使用者越來越多,問題越來越嚴重。
這時候,網景公司(Netscape ,這是一家瀏覽器公司)下定決心要解決這個問題,並將這個問題交給布蘭登·艾奇(Brendan Eich,1964年~,當時在網景公司工作的一個程式設計師)來解決,他用了10個工作日的時間,設計了一個門語言,叫做LiveScript,專門用來解決客戶端上的問題。網景公司和Sun公司合作,在釋出的時候,改名為Javascript,目的是為了利用 Java 這個因特網時髦詞彙。JavaScript 從此變成了因特網的必備元件。
因為 JavaScript 1.0 如此成功,微軟推出了JScript指令碼語言,後來陸續有好幾家公司都建立了自己的客戶端指令碼語言。
此時,JavaScript 並沒有一個標準來統一其語法或特性,隨著網際網路的發展,分久必合的趨勢越來越有必要,最終,1997年,ECMA(歐洲計算機制造商協會)邀請了Netscape、Sun、微軟、Borland等公司的一些程式設計師組成了TC39,定義了標準,名為ECMAScript。
ECMAScript是一個標準,而javascript是語言。
js概念
概念:支援面向物件的跨平臺指令碼語言
理解:
-
- 指令碼語言:依賴別的語言才能執行 html必須在瀏覽器中才能執行,js巢狀在html中才能執行
- 跨平臺:可以在不同的平臺上執行 windows、linux、安卓 ......
- 支援面向物件 使用面向物件的思想程式設計
應用場景:
- 表單驗證:規範使用者輸入資料,和後臺資料進行互動
- 網頁特效:給頁面內容加行為,讓頁面動起來
- 遊戲開發:飛機大戰、打磚塊
- 物聯網: https://zhuanlan.zhihu.com/p/45509947
JS和H5的關係
- H5 = 大前端,主要技術包含:html+css+html5+css3+javascript+前端框架(vue+react+angular)+app+小程式+......
- html5是html的下一個版本,就目前而言,h5只是一些標籤,並不能完美的展示出他的強大之處,有很多高階功能需要使用js來啟用,例如:多媒體標籤自定義控制多媒體的各種場景;canvas標籤用js來繪製圖形等。
- 隨著h5應用越來越多,js的使用方式和各種框架及外掛也越來越多,甚至已經從前端語言可以實現後臺伺服器的功能。
- js的發展已經成為一種潮流。
js的組成
ECMAScript: 語法標準
BOM: 操作瀏覽器的標準
DOM: 操作html文件的標準
JS在html中
js 的書寫位置:
- js不能獨立執行,需要依賴 html,html 是由標籤組成的,js 程式碼寫在一個script 雙標籤。
- script 雙標籤可放在 html 文件的任意位置,但不同的位置,對於程式碼的執行有一定的影響,初期學習建議放在body結束之後。
- 當瀏覽器在執行 html 程式碼的時候,就會解析其中的script標籤,並執行 js 程式碼。
js 的註釋:
註釋程式碼不會被執行,僅起到一個提示的作用。註釋可以對複雜的程式碼進行解釋,方便後期的維護和開發。
單行註釋: // js的單行註釋是雙斜槓
多行註釋: /*
js的多行註釋:
開頭是斜槓星號
結尾是星號斜槓
*/
js的輸出:
輸出:就是將內容顯示在網頁中,和html不同,js程式碼不會主動顯示在網頁中,要顯示指定的內容,需要特殊方法指定才能顯示在網頁中,這個指定顯示的過程就叫做輸出。
- 以彈窗的形式顯示 alert( 123 );
應用:通常適用於給使用者做提示,例如:登入成功;刪除失敗;使用者名稱被佔用等......
- 以文字的形式顯示 document.write(123);
應用:通常用於動態改變或增加body標籤中的內容,有些網頁,我們在檢視原始碼的時候發現body中是沒有程式碼的,但是在網頁中會顯示出很多內容,其實就是用 js 顯示上的。這個中輸出方式,顯示的內容會自動新增到body標籤中。
- 可輸入內容的彈窗 prompt( 1+1=? " );
應用:通常在專案使用較少,專案中要提示使用者輸入內容的時候通常都會使用表單。
- 問使用者是否確認操作的彈窗 confirm("確定要提交嗎?");
應用:通常在專案中使用者進行某些敏感操作時,提示使用者是否繼續進行下去,例如:使用者點選了刪除按鈕之後,使用者點選了退出按鈕之後,需要讓使用者確認是否繼續操作,可以取消。
- 瀏覽器控制檯輸出 console.log(123);
應用:在開發過程中很常用,通常用於除錯程式碼時,在瀏覽器的控制檯檢視除錯結果,不會影響到整體專案的邏輯和效果。
注意:在js程式碼中,每行結束可以加分號,也可以不加分號,但是建議加上,字串要加引號包含起來
變數 : 計算機內部用來儲存資料的容器
在實際專案中,很多情況下,需要在一個初始資料的基礎上進行多次累加操作,例如:
// 第一次輸出數字1
console.log( 1 )
// 第二次需要在第一次的結果基礎上新增2
console.log( 1+2 )
// 第三次需要在第二次的結果基礎上新增3
console.log( 1+2+3 )
// 如果有100次累加,我們就需要在後面寫100個加,可想而知其中的繁瑣
解決方案:
- 將初始資料放在一個容器中,第二次累加時,將第二個資料放在容器中,輸出容器中的內容,第三次累加時,將第三個資料繼續放在容器中,繼續輸出容器中的內容,......這樣,我們只需 每次將資料放在容器中,容器中的資料隨著每次放入,會逐漸增多。
- 當這個容器不會自動出現在記憶體中,需要手動進行建立,也就是變數,不會自動產生,需要定義。
定義變數
語法: var 變數名;
var是一個關鍵字,也就是 js 內部指定有特殊作用的單詞。
變數名的規則
1. 變數名由字母、數字、下劃線、美元符號組成,不能用數字開頭
m √ m2 √ mp3 √ 3m user_id √ _start √ 2_m
2. 不能使用關鍵字作為變數名,關鍵字指的就是js內部有特殊作用所使用的單詞,如
3. 儘量不要使用 name , start 等單詞作為變數名。
變數定義的過程
定義變數的過程,就是在記憶體開闢了一個空間,名字是變數名,如下圖:
定義多個變數的時候,可以使用一個簡短的表示式,一次性定義多個變數: var 變數1 , 變數2 ;
賦值 給變數中放資料的過程
定義變數就是在記憶體開闢好了空間,是一個空的空間,賦值就是給空間加入資料。
賦值需要用到一個符號叫賦值符:=
這個符號在程式設計中,不代表相等的意思,他有自己的使用特點:
-
- 賦值符 左邊 的一定是一個變數,準備接收資料
- 賦值符 右邊 的一定是一個值或者能得到值的一個表示式
- 賦值符的唯一作用就是 將右邊得到的值放在左邊的變數容器中
例子: var a; var b; var c;
a=10; b=20; c=a+b;
定義變數,給變數賦值的兩行程式碼,可以合併為一行:
var a=10; var b=20; var c=a+b;
定義多個變數,也可以在定義的時候賦值,每個變數之間使用逗號隔開:
var a=10,b=20; var a,b=20; var a=10,b;
資料型別
型別 |
示例 |
備註 |
數字型(number) |
1 -2 3.14 300 |
包括整數、小數、負數 |
字串型(string) |
"你好嗎?" '今天嫁給我' |
用引號引起來的任意多任意字元,單引號和雙引號都行 |
布林型(boolean) |
true false |
代表事物的兩面性,真和假 |
未定義型(undefined) |
var a |
代表定義過未賦值的變數 |
物件(object) |
null [1,2,3] {name:張三} |
代表一個集合 |
例子:
// 在頁面上顯示:你的頭髮還好嗎 document.write( 你的頭髮還好嗎 )
此時瀏覽器會報錯:原因:將“你的頭髮還好嗎”識別為了一個變數,但是這個變數沒有定義過。
即:變數的名字還可以使用中文(實際中儘量不用中文命名):
var 我=123;
console.log( 我 ); //控制檯輸出123
輸出數字不需要加引號,但是輸出一段話就需要加引號,因為資料型別不一樣
console.log("你的頭髮還好嗎");
檢測資料型別 typeof(被檢測的內容)
- console.log ( typeof(-123456) ); // 數字型
- console.log ( typeof("明天會更好") ); // 字串型
- console.log ( typeof (true) ); // 布林型
- console.log ( typeof (x) ); // 布林型
- console.log ( typeof ( [1,2,3] ) ); // 物件
- console.log ( typeof( {name:"張三",age:12} ) ); // 物件
- console.log ( typeof (null) ); // 物件
結果如下圖:
拓展: typeof(x) 可以寫成 typeof x 。使用小括號和空格都可以。
數字型別 使用number來代表數字型別。
不同進位制的數字
一般使用的數字是十進位制,在js中還可以使用八進位制和十六進位制。
科學計數法
數值範圍
記憶體大和小區別:儲存的資料多和少的區別。
計算機儲存資料有限制,即:計算機能表達的數字有極限值:
最小值:Number.MIN_VALUE,這個值為: 5e-324
最大值:Number.MAX_VALUE,這個值為: 1.7976931348623157e+308
無窮大:Infinity 1/0
無窮小:-Infinity
需要掌握的內容
NaN
NaN: not a number, 表示一個非數字
在js中,NaN用來表示一個非數字的特殊值,當發現無法進行運算時,js不會報錯,而是會返回一個NaN
NaN的注意事項:
-
- NaN 的型別是 number型別 的,表示一個非數字
- NaN 不等於任何值,包括 NaN 本身
- 通過 isNaN() 可以判斷是否是一個數字,返回 false 的時候,表示是一個數字。
小數 (小數運算時 小數點精度不準確)
//在進行浮點數運算的時候,可能會出現精度丟失的問題
0.1 + 0.2 = 0.30000000000000004;
0.2 + 0.2 = 0.4;
原因:計算機內部所能識別的資料只有二進位制,當我們進行10進位制數字運算的時候,在計算機內部需要先將資料轉為2進位制,然後運算,再將結果轉為10進位制給出來。
10進位制的小數進行2進位制轉換的時候,根據轉換規則,有些小數會進行無限死迴圈,最終在後面數字太多的時候只能四捨五入,所以其實最終並沒有很精確的轉為2進位制,所以只能給出一個大概的值。
有時候會有兩個大概的值相加,在轉換10進位制的時候正好能轉換了,也會計算的比較精準。
也不絕對,如果小數是2的n次方分支m的話,計算機內部儲存的就比較準確。
解決辦法:
// 1.根據小數點後面的位數量 乘以 對應的整數 0.1 + 0.2 ==> (0.1*10+0.2*10) / 10 = 0.3
// 2.使用 toFixed 工具強制保留小數點後位數
var a = 0.1 + 0.2
console.log(a.toFixed(3)) // 0.300
字串型別
字串所使用的引號,在js中,單引號和雙引號是沒有區別的,使用哪個都一樣。
字串中的字元是任意字元,即只要在鍵盤上能輸入的字元都是可以的。
單引號和雙引號也是字串的字元:
var str=' " '// 一個雙引號字元的字串
var str1=" ' "// 一個單引號字元的字串
引號問題
1、雙引號中不能包含雙引號,單引號中不能包含雙引號:
說明:引號對於字串是給字串做邊界,雙引號定義的字串,在字串中碰到第一個雙引號時,將前面的雙引號結束了,單引號同理。
2、雙引號就需要巢狀雙引號,單引號就需要巢狀單引號:
報錯原因:中間的漢字和兩邊的字串之間並沒有拼接,不符合js的語法,所以報錯。
關鍵的原因就是單引號字串中碰到了第一個單引號,將前面的單引號結束了,因為引號對於字串是有特殊含義的。
解決方案:
給字串中的引號轉義(給引號前加反引號\),即:將引號對於字串的特殊含義去掉,就剩下普通字元的含義。
js輸出標籤 (在輸出標籤的時候一定要將標籤當做字串輸出)
一個標籤可以分多次輸出,結果和輸出一次是一樣
字串的拼接 (字串和字串之間的 + 是可以將兩個字串連線在一起組成大字串)
物件型別 (在js中有3種表現形式)
- null
- 用[ ]定義的資料
- 用{ }定義的資料
undefined型別
定義變數後但沒有賦值,即沒有給這個容器中放入資料,這個變數的預設值就是undefined,型別也是undefined。
運算子
算術運算
求餘運算:用於判斷一個數字是奇數或偶數。奇數對2求餘的結果都是1,偶數對2求餘的結果都是0。
關係運算(比較運算)
關係運算最後的結果只有兩種(真 / 假),即布林型的 true 和 false
等於 和 全等於
引號只能代表資料的型別不同,字串在記憶體中儲存時不會將引號存進去,所以字串在記憶體中的真實儲存並不帶引號,所以a變數和b變數在記憶體中存的內容一樣,所以是相等的,但型別不一樣,所以不全等。
賦值運算
例:
邏輯運算 (用於判斷多個關係運算,得出最後結果)
邏輯運算最後得出的結果也是布林型
例題:模特的要求:年齡在18歲以上,30歲以下。小紅今年20歲,看看小紅是否滿足條件。
雙重否定等於肯定:
自增自減運算
符號:++ 表示讓一個數字遞增1
當遞增運算碰到賦值或者輸出時,放前面則:先進行遞增運算, 後進行輸出或賦值
放後面則:最後進行遞增運算,先進行輸出或者賦值
符號:-- 表示讓一個數字遞減1
使用方法和注意事項與遞增一樣。遞增遞減運算需要使用變數,不能使用具體數字
型別轉換
強制轉換
1、轉換為布林型 Boolean (arg)
-
- 0 ==>false,非 0 數字 ==>true
- 空字串 ==>false,非空字串 ==>true
- undefined ==>false
- null ==>false
2、轉換為字串 String (arg)
-
- true ==>true,false ==>false
- null ==>null
- undefined ==>undefined
3、轉換為數字 Number (str)
-
- NaN代表不是數字,但是他是數字型別(沒有意義的數字)
- 非數字字串 ==>都是NaN(NaN是一個不是數字的數字型別)
- true ==>1,false ==>0
- undefined ==>NaN
- null ==>0
4、使用函式強制轉換為數字
parseInt(arg) # 強制轉換為整數
parseFloat(arg) # 強制轉換為小數
-
- 小數 轉換為 整數 只取整數,向下取整
- 首位非數字的字串強轉為整數為NaN,首位是數字的字串強轉為 整數是首位的數字
- 布林型 強轉為數字為NaN
- undefined 強轉為數字為NaN
- null 強轉為數字為NaN
5、使用toString()方法強制轉換為字串,轉換結果和String()函式一樣
注意:這個方法不能給 undefined 和 null 使用
隱形轉換
數學運算時轉換為數字型,例:
比較運算時發生隱形轉換,例:
-
- 如果 兩個值 都是 字串,則進行比較編碼值
- 如果有一個值為數字或布林型,則轉換為數字進行比較
- 字串進行比較的時候首字元進行比較,相等再進行後面的字元比較。參照阿斯克碼錶。
拼接運算時發生字串轉換,例:
擴充套件
進位制介紹
平常使用的數字是十進位制,由0~9這10個數字組成,沒有一個單獨的數字代表10,要表示10,需要向前進一位,所以是10進位制。
計算機內部還會使用二進位制、八進位制和十六進位制。
二進位制由0和1兩個數字組成,沒有一個數字表示2,要表示2,需要向前進一位。
同理八進位制由0~7這8個數字組成。表示8的時候要向前進一位。
十六進位制由0~9和a~f這16個數字組成,使用f來表示15,表示1要向前進一位。
進位制轉換:
轉成10進位制:以進製為底,冪從右往左依次為0次方,1次方,2次方…,乘以當前當前數字在10進制中的結果,所有乘積相加
1.16進位制的FF轉為10進位制:
2.2進位制的11011轉為10進位制
3.10進位制的11轉2進位制-----反向取餘數
總結: