學習信息 學習形式:網路教學視頻 學習地址:https://www.bilibili.com/video/BV1Sy4y1C7ha/?spm_id_from=333.337.search-card.all.click 學習開始時間:2022年11月18日 01 初識 JavaScript 瀏覽器執行 ...
目錄
學習信息
學習形式:網路教學視頻
學習地址:https://www.bilibili.com/video/BV1Sy4y1C7ha/?spm_id_from=333.337.search-card.all.click
學習開始時間:2022年11月18日
01 初識 JavaScript
瀏覽器執行JS過程
瀏覽器分成兩部分:渲染引擎和JS引擎
-
渲染引擎︰用來解析HTML與CSS,俗稱內核,比如chrome瀏覽器的 blink,老版本的 webkit
-
JS引擎:也稱為JS解釋器。用來讀取網頁中的JavaScript代碼,對其處理後運行,比如chrome瀏覽器的V8
瀏覽器本身並不會執行JS代碼,而是通過內置JavaScript引擎(解釋器)來執行JS代碼。JS引擎執行代碼時逐行解釋每一句源碼(轉換為機器語言),然後由電腦去執行,所以JavaScript語言歸為腳本語言,會逐行解釋執行。
JS的組成
1)ECMAScript
ECMAScript 是由ECMA國際(原歐洲電腦製造商協會)進行標準化的一門編程語言,這種語言在萬維網上應用廣泛,它往往被稱為JavaScript或JScript,但實際上後兩者是ECMAScript語言的實現和擴展。
ECMAScript : ECMAScript規定了JS的編程語法和基礎核心知識,是所有瀏覽器廠商共同遵守的一套JS語法工業標準。
2)DOM——文檔對象模型
文檔對象模型(Document Object Model,簡稱DOM),是W3C組織推薦的處理可擴展標記語言的標準編程介面。通過DOM提供的介面可以對頁面上的各種元素進行操作(大小、位置、顏色等)。
3)BOM——瀏覽器對象模型
BOM(Browser Object Model,簡稱BOM)是指瀏覽器對象模型,它提供了獨立於內容的可以與瀏覽器視窗進行互動的對象結構。通過BOM可以操作瀏覽器視窗,比如彈出框、控制瀏覽器跳轉、獲取解析度等。
JS初體驗
JS有3種書寫位置,分別為行內、內嵌和外部。
1)行內式JS
<input type="button" value="點我式試" onclick="alert('Hello world')"/>
- 可以將單行或少量JS代碼寫在HTML標簽的事件屬性中(以on開頭的屬性),如:onclick
- 註意單雙引號的使用:在HTML中我們推薦使用雙引號,JS中我們推薦使用單引號
- 可讀性差,在html中編寫JS大量代碼時,不方便閱讀;
- 引號易錯,引號多層嵌套匹配時,非常容易弄混﹔
- 特殊情況下使用
2)內嵌JS
<script>
alert("醉後不知天在水")
</script>
-
可以將多行JS代碼寫到
<script>
標簽中 -
內嵌JS是學習時常用的方式
3)外部 JS 文件
<script src="example.js"></script>
-
利於HTML頁面代碼結構化,把大段JS代碼獨立到HTML頁面之外,既美觀,也方便文件級別的復用
-
引用外部JS文件的script標簽中間不可以寫代碼
-
適合於JS代碼量比較大的情況
JS 的註釋
-
單行註釋使用雙斜線 //
-
多行註釋使用
/* 要註釋的代碼 */
02 JavaScript輸入輸出語句
方法 | 說明 | 歸屬 |
---|---|---|
alert(msg) | 瀏覽器彈出警示框 | 瀏覽器 |
console.log(msg) | 瀏覽器控制台列印輸出信息 | 瀏覽器 |
prompt(info) | 瀏覽器彈出輸入框,用戶可以輸入 | 瀏覽器 |
註:從prompt獲取的值的數據類型是字元串類型。
03 變數
變數概述
什麼是變數
白話∶變數就是一個裝東西的盒子。
通俗︰變數是用於存放數據的容器。我們通過變數名獲取數據,甚至數據可以修改。
變數在記憶體中的存儲
本質:變數是程式在記憶體中申請的一塊用來存放數據的空間。類似我們酒店的房間,一個房間就可以看做是一個變數。
變數的使用
變數在使用時分為兩步:
1.聲明變數
2.賦值
1.聲明變數
// 聲明變數
var age; // 聲明一個名稱為 age 的變數
- var 是一個JS關鍵字,用來聲明變數( variable變數的意思)。使用該關鍵字聲明變數後,電腦會自動為變數分配記憶體空間,不需要程式員管
- age是程式員定義的變數名,我們要通過變數名來訪問記憶體中分配的空間
案例∶變數的使用
1.彈出一個輸入框,提示用戶輸入姓名。
2.彈出一個對話框,輸出用戶剛纔輸入的姓名。
<script>
var name= prompt("請輸入您的名字:");
alert(name);
</script>
變數的語法擴展
更新變數
一個變數被重新復賦值後,它原有的值就會被覆蓋,變數值將以最後一次賦的值為準。
<script>
var name = "迪麗熱巴";
console.log(name);
name = "古力娜扎";
console.log(name); // 輸出古力娜扎
</script>
同時聲明多個變數
同時聲明多個變數時,只需要寫一個var,多個變數名之間使用英文逗號隔開。
var name="張三", age=18, address="China";
聲明變數的特殊情況
情況 | 說明 | 結果 |
---|---|---|
var age; console.log(age) | 只聲明,不賦值 | undefined |
console.log(name) | 不聲明,不賦值,直接使用 | 報錯 |
age=10; console.log(age) | 不聲明,只賦值 | 10 |
變數的命名規範
- 由字母(A-Za-z)、數字(O-9)、下劃線(
_
)、美元符號($ )組成,如: usrAge, num01,_name - 嚴格區分大小寫。var app;和var App;是兩個變數
- 不能以數字開頭。18age是錯誤的
- 不能是關鍵字、保留字。例如: var、for、while
- 變數名必須有意義。MMD BBD nl →age
- 遵守駝峰命名法。首字母小寫,後面單詞的首字母需要大寫。myFirstName
04 數據類型
4.1 數據類型簡介
變數的數據類型
變數是用來存儲值的所在處,它們有名字和數據類型。變數的數據類型決定瞭如何將代表這些值的位存儲到電腦的記憶體中。JavaScript是一種弱類型或者說動態語言。這意味著不用提前聲明變數的類型,在程式運行過程中,類型會被自動確定。
var age=10; // 這是一個數字型
var name="李白"; // 這是一個字元串
在代碼運行時,變數的數據類型是由JS引擎根據=右邊變數值的數據類型來判斷的,運行完畢之後,變數就確定了數據類型。
JavaScript擁有動態類型,同時也意味著相同的變數可用作不同的類型∶
var x=6;
var x="Jack";
數據類型的分類
JS把數據類型分為兩類:
- 簡單數據類型(Number,String,Boolean,Undefined,Null)
- 複雜數據類型(object)
4.2 簡單數據類型(基本數據類型)
JavaScript中的簡單數據類型及其說明如下︰
簡單數據類型 | 說明 | 預設值 |
---|---|---|
Number | 數字型,包含整型值和浮點型值,如21、0.21 | 0 |
Boolean | 布爾值類型,如true 、false,等價於1和0 | false |
String | 字元串類型,如"張三”註意咱們 js 裡面,字元串都帶引號 | "" |
Undefined | var a; 聲明瞭變數a但是沒有給值,此時a = undefined | undefined |
Null | var a = null; 聲明瞭變數a為空值 | null |
數字型 Number
JavaScript數字類型既可以用來保存整數值,也可以保存小數(浮點數)。
var age = 18; // 整數
var distance = 19.1; // 小數
數字型範圍
JavaScript中數值的最大和最小值
alert(Number.MAX_VALUE);
alert(Number.MIN_VALUE);
數字型三個特殊值
alert(Infinity);
alert(-Infinity);
alert(NaA);
-
Infinity ,代表無窮大,大於任何數值
-
-Infinity ,代表無窮小,小於任何數值
-
NaN,Not a number,代表一個非數值
isNaN()
用來判斷一個變數是否為非數字的類型,返回 true 或者 false
isNaN(x):
- x是數字,返回 false
- x不是數字,返回true
字元串型 String
-
字元串型可以是引號中的任意文本,其語法為雙引號""和單引號"
-
因為HTML標簽裡面的屬性使用的是雙引號,JS這裡我們更推薦使用單引號。
-
JS可以用單引號嵌套雙引號,或者用雙引號嵌套單引號(外雙內單,外單內雙)
var str="He's name is Jakc";
字元串轉義符
類似HTML裡面的特殊字元,字元串中也有特殊字元,我們稱之為轉義符。轉義符都是\開頭的,常用的轉義符及其說明如下:
轉義符 | 解釋說明 |
---|---|
\n |
換行符 |
\\ |
斜杠\ |
\' |
' 單引號 |
\" |
" 雙引號 |
\t |
tab 縮進 |
\b |
空格 |
字元串長度
字元串是由若幹字元組成的,這些字元的數量就是字元串的長度。通過字元串的 length 屬性可以獲取整個字元串的長度。
var msg = "Hello World!"
alert(msg.length) // 顯示12
字元串拼接
多個字元串之間可以使用+進行拼接,其拼接方式為 字元串+任何類型 = 拼接之後的新字元串
console.log("jack" + "ma"); // jackma
console.log("jack" + 01); // jack1
console.log("jack" + true); // jacktrue
console.log(12 + 12); // 24
console.log('12' + 12); // 1212
記憶口訣:數值相加,字元相連
布爾型 Boolean
布爾類型有兩個值: true和false ,其中true表示真(對),而false表示假(錯)。
Undefined 和 Null
一個聲明後沒有被賦值的變數會有一個預設值undefined(如果進行相連或者相加時,註意結果)。
undefined 和數字相加的結果是 NaN。
null 和數字相加的結果是數字。
4.3 獲取變數數據類型
typeof 可用來獲取檢測變數的數據類型。
var num=10;
console.log(typeof num) // num
var username='Jack';
console.log(typeof username) // string
var flag=true;
console.log(typeof flag); // boolean
var timer=null;
console.log(typeof timer); // object
var value2=undefined;
console.log(typeof value2); // undefined
字面量
字面量是在源代碼中一個固定值的表示法,通俗來說,就是字面量表示如何表達這個值。
-
數字字面量:8,9,10
-
字元串字面量:'黑馬程式員',"大前端"
-
布爾字面量:true , false
4.4 數據類型轉換
什麼是數據類型轉換
使用表單、prompt獲取過來的數據預設是字元串類型的,此時就不能直接簡單的進行加法運算,而需要轉換變數的數據類型。通俗來說,就是把一種數據類型的變數轉換成另外一種數據類型。
我們通常會實現3種方式的轉換∶
- 轉換為字元串類型
- 轉換為數字型
- 轉換為布爾型
轉換為字元串
方式 | 說明 | 案例 |
---|---|---|
toString() | 轉成字元串 | var num= 1; alert(num.toString()); |
String()強制轉換 | 轉成字將串 | var num = 1; alert(String(num)); |
加號拼接字元串 | 和字元串拼接的結果都是字元串 | var num = 1; alert(num+ "我是字元串"); |
- toString(和String()使用方式不一樣。
- 三種轉換方式,我們更喜歡用第三種加號拼接字元串轉換方式,這一種方式也稱之為隱式轉換。
轉換為數字型(重點)
方式 | 說明 | 案例 |
---|---|---|
parselnt(string)函數 | 將string類型轉成整數數值型 | parseInt('78') |
parseFloat(string)函數 | 將string類型轉成浮點數數值型 | parseFloat('78.21') |
Number()強制轉換函數 | 將string類型轉換為數值型 | Number("12') |
js 隱式轉換( - * / ) | 利用算術運算隱式轉換為數值型 | '12'-0 |
註意:
- parseInt('3.14') 的值是3、parseInt(3.99)的值是3、parseInt(250px)的值是250
- parseInt('name66') 的值是 NaN
- parseFloat('aa11') 的值是 NaN
總結:
- 當加號的任意一邊有字元串類型時,結果會隱式轉換為字元串
- 當字元串和數字之間的運算符是 減/乘/除 時,結果會隱式轉換為數字
轉換為布爾型
方式 | 說明 | 案例 |
---|---|---|
Boolean() 函數 | 其他類型轉換成布爾值 | Boolean('true'); |
-
代表空、否定的值會被轉換為false ,如 ""、0、NaN、null、undefined
-
其餘值都會被轉換為true
05 運算符
比較運算符
運算符名稱 | 說明 | 案例 | 結果 |
---|---|---|---|
== | 判等號(會轉型),判斷兩邊的值是否相等 | 37 == '37' | true |
=== !== | 全等 要求值和數據類型一直 | 37 === '37' | false |
邏輯運算符
邏輯運算符 | 說明 | 案例 |
---|---|---|
&& | "邏輯與",簡稱 "與" and | true && true |
|| | "邏輯或",簡稱 "或" or | true || false |
! | "邏輯非",簡稱 "非" not | !true |
- 邏輯與,兩邊都為 true 才返回 true,否則返回 false
- 邏輯或,只要一邊是 true 就返回 true,否則返回 false
- 邏輯非,只要是 true 就返回 false
短路運算(邏輯中斷)
短路運算的原理∶當有多個表達式(值)時,左邊的表達式值可以確定結果時,就不再繼續運算右邊的表達式的值;
1)邏輯與
- 語法:表達式1 && 表達式2
- 如果第一個表達式的值為真,則返回表達式2
- 如果第一個表達式的值為假,則返回表達式1
2)邏輯或
- 語法:表達式1 || 表達式2
- 如果第一個表達式的值為真,則返回表達式1
- 如果第一個表達式的值為假,則返回表達式2
運算符的優先順序
優先順序 | 運算符 | 順序 |
---|---|---|
1 | 小括弧 | () |
2 | 一元運算符 | ++ -- ! |
3 | 算數運算符 | 先 * / % 後 + - |
4 | 關係運算符 | > >= < <= |
5 | 相等運算符 | == != === !== |
6 | 邏輯運算符 | 先 && 後 || |
7 | 賦值運算符 | = |
8 | 逗號運算符 | , |
- 一元運算符裡面的 邏輯非 優先順序很高
- 邏輯與比邏輯或的優先順序高
06 流程式控制制分支
流程式控制制主要有三種結構,分別是順序結構、分支結構和迴圈結構,這三種結構代表三種代碼執行的順序。
三元表達式
語法結構
條件表達式 ? 表達式1:表達式2
age>18?alert("已成年"):alert("未成年")
執行思路
-
如果條件表達式結果為真則返回表達式1的值
-
如果條件表達式結果為假則返回表達式2的值
分支流程式控制制 switch 語句
語法結構
switch語句也是多分支語句,它用於基於不同的條件來執行不同的代碼。當要針對變數設置一系列的特定值的選項時,就可以使用switch。
心。
switch(表達式){
case value1:
執行語句1;
break;
case value2:
執行語句2;
break;
case value3:
執行語句3;
break;
...
default:
執行語句最後語句;
}
執行思路
利用我們的表達式的值和 case後面的選項值相匹配如果匹配上,就執行該裡面的語句如果都沒有匹配上,那麼執行default裡面的語句。
案例:
<script>
var level = prompt("請輸入您的年齡:");
level = parseInt(level);
switch(level){
case 1:
alert("您的等級是1級!");
break;
case 2:
alert("您的等級是2級!");
break;
case 3:
alert("您的等級是3級!");
break;
default:
alert("您的等級未知!");
}
</script>
註意:
- level 的值和case裡面的值相匹配的時候是全等,必須數據類型和值一致才可以
- 如果當前的 case 裡面沒有 break,則不會退出 switch且繼續執行下一個 case
switch 語句和 if else if 語句的區別
- 一般情況下,它們兩個語句可以相互替換
- switch..case語句通常處理case為比較確定值的情況,而i...else...語句更加靈活,常用於範圍判斷(大於、等於某個範圍)
- switch語句進行條件判斷後直接執行到程式的條件語句,效率更高。而if...else語句有幾種條件,就得判斷多少次。
- 當分支比較少時,if...else語句的執行效率比switch語句高。
- 當分支比較多時,switch語句的執行效率比較高,而且結構更清晰。
JS中的迴圈
- for 迴圈
- while 迴圈
- do...while 迴圈
for 迴圈
在程式中,一組被重覆執行的語句被稱之為迴圈體,能否繼續重覆執行,取決於迴圈的終止條件。由迴圈體及迴圈的終止條件組成的語句,被稱之為迴圈語句
語法結構
for迴圈主要用於把某些代碼迴圈若幹次,通常跟計數有關係。其語法結構如下:
for(初始化變數;條件表達式;操作表達式){
// 迴圈體;
}
案例:在瀏覽器控制台輸出100句"JS天下第一!"
<script>
for (var i=0; i<100;i++){
console.log("JS天下第一!")
}
</script>
斷點調試
斷點調試是指自己在程式的某一行設置一個斷點,調試時,程式運行到這一行就會停住,然後你可以一步一步往下調試,調試過程中可以看各個變數當前的值,出錯的話,調試到出錯的代碼行即顯示錯誤,停下。
斷點調試可以幫我們觀察程式的運行過程
瀏覽器中按F12--> sources -->找到需要調試的文件-->在程式的某一行設置斷點Watch:監視,通過watch可以監視變數的值的變化,非常的常用。
F11:程式單步執行,讓程式一行一行的執行,這個時候,觀察watch中變數的值的變化。
代碼調試的能力非常重要,只有學會了代碼調試,才能學會自己解決bug的能力。初學者不要覺得調試代碼麻煩就不去調試,知識點花點功夫肯定學的會,但是代碼調試這個東西,自己不去練,永遠都學不會。
while 迴圈
while語句可以在條件表達式為真的前提下,迴圈執行指定的一段代碼,直到表達式不為真時結束迴圈while語句的語法結構如下:
while (條件表達式){
// 迴圈體
}
執行思路:
- 先執行條件表達式,如果結果為true,則執行迴圈體代碼;如果為false,則退出迴圈,執行後面代碼
- 執行迴圈體代碼
- 迴圈體代碼執行完畢後,程式會繼續判斷執行條件表達式,如條件仍為true,則會繼續執行迴圈體,直到迴圈條件為false時,整個迴圈過程才會結束
do while 迴圈
do... while 語句其實是while語句的一個變體。該迴圈會先執行一次代碼塊,然後對條件表達式進行判斷,如果條件為真,就會重覆執行迴圈體,否則退出迴圈。
do {
迴圈體
} while (條件表達式)
continue 關鍵字
continue關鍵字用於立即跳出本次迴圈,繼續下一次迴圈(本次迴圈體中continue之後的代碼就會少執行一次)。
break 關鍵字
break關鍵字用於立即跳出整個迴圈(迴圈結束)。
07 JavaScript 數組
7.1 數組的概念
數組是指一組數據的集合,其中的每個數據被稱作元素,在數組中可以存放任意類型的元素。數組是一種將一組數據存儲在單個變數名下的優雅方式。
// 普通變數一次只能存儲一個值
var num=10;
// 數組一次可以存儲多個值
var arr = [1, 2, 3, 4];
7.2 數組的創建方式
JS中創建數組有兩種方式:
- 利用new創建數組
- 利用數組字面量創建數組
// 利用new創建數組
var arr = new Array(); // 創建一個空數組
// 利用數組字面量創建數組
var arr = []; // 創建一個空數組
- 數組的字面量是方括弧[]
- 聲明數組並賦值稱為數組的初始化
- 字面量方式也是我們以後最多使用的方式
數組元素的類型
數組中可以存放任意類型的數據,例如字元串,數字,布爾值等。
var arr = [1, 'China', true, 66.66]
7.3 獲取數組元素
數組的索引
索引(下標)∶用來訪問數組元素的序號(數組下標從0開始)。
數組可以通過索引來訪問、設置、修改對應的數組元素,我們可以通過“數組名[索引]”的形式來獲取數組中的元素。
這裡的訪問就是獲取得到的意思
var arr = [1, 'China', true, 66.66];
// 獲取數組中的第二個元素
alert(arr[1]);
數組長度
獲取數組長度可以使用 數組名.length 方法獲取。
7.4 遍曆數組
可以使用 for 迴圈將數組中的元素遍歷出來。
案例:
<script>
var nameList = ['張三', '李四', '王五', '趙六', '陳琦'];
for (var i=0; i<nameList.length; i++){
console.log(nameList[i]);
}
</script>
案例:獲取數組中的最大值
<script>
var arr = [1, 2, 3, 4, 6, 5, 78, 34];
var max=arr[0];
for(var i=0; i<arr.length-1;i++){
if (arr[i+1] > max){
max = arr[i+1];
}
}
console.log(max);
</script>
7.5 數組中新增元素
通過修改length長度新增數組元素
- 可以通過修改length長度來實現數組擴容的目的
- 不能直接給數組名賦值,否則會覆蓋掉以前的數據
- length屬性是可讀寫的
var arr = [1, 2, 3];
arr.length=5;
console.log(arr);
console.log(arr[3]);
console.log(arr[4]);
其中索引號3、4的空間沒有給值,就是聲明變數未給值,預設值就是 undefined。
案例1:篩選數組中大於10的元素,並將它們放到一個新的數組中。
<script>
var arr = [1, 2, 3, 5, 88, 89, 99];
var newArr = [];
for(var i=0; i<arr.length; i++){
if (arr[i]>10){
// 註意這裡的寫法,很妙
newArr[newArr.length] = arr[i];
}
}
console.log(newArr);
</script>
案例2:翻轉數組
<script>
var arr = [1, 2, 3, 4, 6, 5, 7];
var newArr = [];
for (var i = arr.length-1; i>=0; i--){
newArr[newArr.length] = arr[i];
}
console.log("原數組:" + arr)
console.log("翻轉之後的數組:" + newArr);
</script>
08 函數
8.1 函數的概念
雖然 for迴圈語句也能實現一些簡單的重覆操作,但是比較具有局限性,此時我們就可以使用JS中的函數。
函數就是封裝了一段可以被重覆執行調用的代碼塊目的:就是讓大量代碼重覆使用
8.2 函數的使用
函數在使用時分為兩步:聲明函數和調用函數。
聲明函數
// 聲明函數
function 函數名(){
// 函數體代碼
}
-
function是聲明函數的關鍵字,必須小寫
-
由於函數一般是為了實現某個功能才定義的,所以通常我們將函數名命名為動詞,比如 getSum
-
function聲明函數的關鍵字全部小寫
調用函數
// 調用函數
函數名(); // 通過調用函數名來執行函數體的代碼
- 調用的時候千萬不要忘記添加小括弧
- 口訣:函數不調用,自己不執行
註意:聲明函數本身並不會執行代碼,只有調用函數時才會執行函數體代碼。
函數的封裝
函數的封裝是把一個或者多個功能通過函數的方式封裝起來,對外只提供一個簡單的函數介面。
案例:求1-100之間的累加和
<script>
function getSum(){
var sum=0;
for (var i=0; i<=100; i++){
sum += i;
}
console.log(sum)
}
getSum()
</script>
8.3 函數的參數
形參和實參
在聲明函數時,可以在函數名稱後面的小括弧中添加一些參數,這些參數被稱為形參,而在調用該函數時,同樣也需要傳遞相應的參數,這些參數被稱為實參。
參數 | 說明 |
---|---|
形參 | 形式上的參數函數定義的時候傳遞的參數當前並不知道是什麼 |
實參 | 實際上的參數函數調用的時候傳遞的參數實參是傳遞給形參的 |
參數的作用:在函數內部某些值不能固定,我們可以通過參數在調用函數時傳遞不同的值進去。
函數形參和實參個數不匹配的問題
參數個數 | 說明 |
---|---|
實參個數等於形參個數 | 輸出正確結果 |
實參個數多於形參個數 | 只取到形參個數 |
實參個數小於形參個數 | 多的形參定義為 undefined,結果為 NaN |
8.4 函數的返回值
return語句
有的時候,我們會希望函數將值返回給調用者,此時通過使用 return 語句就可以實現。
function 函數名(){
return 需要返回的結果;
}
-
我們函數只是實現某種功能,最終的結果需要返回給函數的調用者函數名()通過return 實現的
-
只要函數遇到return 就把後面的結果返回給函數的調用者﹐函數名() = return 後面的結果
-
return語句之後的代碼不被執行
-
return只能返回一個值。如果用逗號隔開多個值,以最後一個為準
-
函數沒有return返回undefined
案例:
<script>
var name = prompt("請輸入您的名字:");
function greeting(name){
msg = "Hello " + name;
return msg;
}
msg = greeting(name);
alert(msg);
</script>
break ,continue ,return的區別
-
break:結束當前的迴圈體(如for、while )
-
continue :跳出本次迴圈,繼續執行下次迴圈(如for、while )
-
return :不僅可以退出迴圈,還能夠返回 return 語句中的值,同時還可以結束當前的函數體內的代碼
8.5 arguments 的使用
當我們不確定有多少個參數傳遞的時候,可以用arguments來獲取。在JavaScript中,arguments實際上它是當前函數的一個內置對象。所有函數都內置了一個arguments對象,arguments對象中存儲了傳遞的所有實參。
<script>
function fn(){
console.log(arguments)
}
fn(1, 2, 3);
</script>
瀏覽器 console 輸出結果:
arguments展示形式是一個偽數組,因此可以進行遍歷。偽數組具有以下特點∶
- 具有length屬性
- 按索引方式儲存數據
- 不具有數組的push , pop等方法
- 只有函數才有 arguments 對象而且是每個函數都內置好了這個 arguments
8.6 函數可以調用另外一個函數
因為每個函數都是獨立的代碼塊,用於完成特殊任務,因此經常會用到函數相互調用的情況。
8.7 函數聲明的兩種方式
1、利用函數關鍵字自定義函數(命名函數)
function fn(){
}
fn();
2、函數表達式(匿名函數)
var 變數名 = function(){};
var fun = function(){
console.log('函數表達式')
}
fun()
- fun是變數名不是函數名
- 函數表達式聲明方式跟聲明變數差不多,只不過變數裡面存的是值而函數表達式裡面存的是函數
09 作用域
9.1 作用域
作用域概述
通常來說,一段程式代碼中所用到的名字並不總是有效和可用的,而限定這個名字的可用性的代碼範圍就是這個名字的作用域。作用域的使用提高程式邏輯的局部性,增強了程式的可靠性,減少了名字衝突。
全局作用域
整個script標簽或者是一個單獨的 js 文件。
局部作用域
在函數內部就是局部作用域這個代碼的名字只在函數內部起效果和作用
9.2 變數的作用域
變數作用域的分類
在JavaScript中,根據作用域的不同,變數可以分為兩種:
- 全局變數
- 局部變數
全局變數
在全局作用域下聲明的變數叫做全局變數(在函數外部定義的變數)。
- 全局變數在代碼的任何位置都可以使用
- 在全局作用域下var聲明的變數是全局變數
- 特殊情況下,在函數內不使用var聲明的變數也是全局變數(不建議使用)
局部變數
在局部作用域下聲明的變數叫做局部變數(在函數內部定義的變數)
- 局部變數只能在該函數內部使用
- 在函數內部var 聲明的變數是局部變數
- 函數的形參實際上就是局部變數
從執行效率來看全局變數和局部變數
(1全局變數只有瀏覽器關閉的時候才會銷毀,比較占記憶體資源
(2)局部變數當我們程式執行完畢就會銷毀,比較節約記憶體資源
9.3 作用域鏈
-
只要是代碼,就至少有一個作用域
-
寫在函數內部的局部作用域
-
如果函數中還有函數,那麼在這個作用域中就又可以誕生一個作用域
-
根據在內部函數可以訪問外部函數變數的這種機制,用鏈式查找決定哪些數據能被內部函數訪問,就稱作作用域鏈
- 作用域鏈採取的查找方式是就近原則
案例:結果是幾?
<script>
function f1(){
var num=123;
function f2(){
console.log(num); // 輸出123
}
f2();
}
var num=456;
f1();
</script>
10 預解析
10.1 預解析
JavaScript代碼是由瀏覽器中的JavaScript解析器來執行的。JavaScript解析器在運行JavaScript代碼的時候分為兩步:預解析和代碼執行。
- 預解析:js引擎會把js 裡面所有的 var還有 function 提升到當前作用域的最前面
- 代碼執行:按照代碼書寫的順序從上往下執行
10.2 變數預解析和函數預解析
預解析分為變數預解析(變數提升)和 函數預解析(函數提升)
1)變數提升就是把所有的變數聲明提升到當前的作用域最前面,不提升賦值操作
變數提升案例1
console.log(num); // 輸出:undefined
var num=10;
// 相當於執行了以下代碼:
var num;
console.log(num);
num = 10; // 變數提升不提升賦值操作
變數提升案例2
fun(); // 報錯:fun is not defined
var fun = function(){
console.log(11);
}
// 相當於執行了以下代碼:
var fun;
fun();
fun = function(){
console.log(11);
}
2)函數提升就是把所有的函數聲明提升到當前作用域的最前面,不調用函數
函數提升案例
fn(); // 輸出:11
function fn(){
console.log(11);
}
// 相當於執行了以下代碼:
function fn(){
console.log(11);
}
fn();
10.3 預解析案例
案例1:
var num=10;
fun();
function fun(){
console.log(num); // 輸出結果 undefined
var num=20;
}
// 相當於執行了以下操作
var num;
function fun(){
// 函數內部的變數也提升到了函數內的頂部
var num;
console.log(num); // 輸出結果 undefined
num=20; // 賦值操作不提升
}
num = 10; // 賦值操作不提升
fun();
案例2:
f1();
console.log(c);
console.log(b);
console.log(a);
function f1(){
var a=b=c=9;
console.log(a);
console.log(b);
console.log(c);
}
// 相當於執行了以下代碼
function f1(){
var a;
a=b=c=9;
console.log(a); // 9
console.log(b); // 9
console.log(c); // 9
}
f1();
console.log(c); // 9
console.log(b); // 9
console.log(a); // a is not defined
註意: var a=b=c=9;
相當於 var a=9; b=9; c=9;
,b和c 前面是沒有 var 的,相當於 b 和 c 是全局變數。如果想集體聲明,應該這樣聲明:var a=9,b=9,c=9;
11 對象
11.1 對象
什麼是對象?
現實生活中:萬物皆對象,對象是一個具體的事物,看得見摸得著的實物。例如,一本書、一輛汽車、一個人可以是“對象”,一個資料庫、一張網頁、一個與遠程伺服器的連接也可以是“對象”。
在JavaScript中,對象是一組無序的相關屬性和方法的集合,所有的事物都是對象,例如字元串、數值、數組、函數等。
對象是由屬性和方法組成的。
-
屬性:事物的特征,在對象中用屬性來表示(常用名詞)
-
方法:事物的行為,在對象中用方法來表示(常用動詞)
11.2 創建對象的三種方式
在JavaScript中,現階段我們可以採用三種方式創建對象( object ) :
- 利用字面量創建對象
- 利用 new Object 創建對象
- 利用構造函數創建對象
利用字面量創建對象
對象字面量:就是花括弧 {} 裡面包含了表達這個具體事物(對象)的屬性和方法。
-
裡面的屬性或者方法我們採取鍵值對的形式 鍵屬性名:值屬性值
-
多個屬性或者方法中間用逗號隔開的
-
方法冒號後面跟的是一個匿名函數
案例:
var obj ={
userName: '張三',
age: 18,
sex: '男',
sayHi: function(){
console.log('Hi~')
}
}
對象的使用
1)調用對象的屬性我們採取 對象名.屬性名。如
console.log(obj.name) // 輸出'張三'
2)也可以採用 對象名['屬性名'] 的方法,如:
console.log(obj['name']) // 輸出'張三'
3)調用對象的方法,使用 對象名.方法名,如:
console.log(obj.sayHi()) // 輸出'張三'
變數、屬性、函數、方法總結
-
變數:單獨聲明賦值,單獨存在
-
屬性:對象裡面的變數稱為屬性,不需要聲明,用來描述該對象的特征
-
函數︰單獨存在的,通過“函數名)”的方式就可以調用
-
方法:對象裡面的函數稱為方法,方法不需要聲明,使用“對象.方法名()”的方式就可以調用,方法用來描述該對象的行為和功能。
利用 new Object 創建對象
案例:
var obj = new Object(); // 創建一個空對象
obj.userName = '張三';
obj.age = 18;
obj.sex = '男';
obj.sayHi = function(){
console.log('Hi~');
}
利用構造函數創建對象
為什麼需要使用構造函數?
-
就是因我們前面兩種創建對象的方式一次只能創建一個對象。
-
因為我們一次創建一個對象,裡面很多的屬性和方法是大量相同的我們只能複製。
-
因此我們可以利用函數的方法重覆這些相同的代碼我們就把這個函數稱為構造函數。
-
又因為這個函數不一樣,裡面封裝的不是普通代碼,而是對象。
-
構造函數就是把我們對象裡面一些相同的屬性和方法抽象出來封裝到函數裡面。
構造函數:是一種特殊的函數,主要用來初始化對象,即為對象成員變數賦初始值,它總與new運算符一起使用。我們可以把對象中一些公共的屬性和方法抽取出來,然後封裝到這個函數裡面。
構造函數的語法格式
function 構造函數名(){
this.屬性 = 值;
this.方法 = function(){
}
}
//使用關鍵字 new 調用構造函數
new 構造函數名();
- 構造函數的名字首字母要大寫
- 構造函數不需要 return 就可以返回結果
- 調用構造函數,必須使用 new
- 屬性和方法前面必須添加 this
案例:利用構造函數創建4大天王
function Star(name, age, sex){
this.name = name;
this.age = age;
this.sex = sex;
this.sing = function(song){
console.log("即將為您播放天王"+ this.name +"的歌曲-" + song);
}
}
var Liudehua = new Star('劉德華', 18, '男');
var Guofucheng = new Star('郭富城', 18, '男');
var Zhangxueyou = new Star('張學友', 20, '男');
var Liming = new Star('黎明', 17, '男');
console.log(typeof Liudehua); // object
console.log(Liudehua.name);
Liudehua.sing('冰雨');
構造函數和對象
-
構造函數:如Stars(),抽象了對象的公共部分,封裝到了函數裡面,它泛指某一大類( class )
-
創建對象:如new Stars(),特指某一個,通過new關鍵字創建對象的過程我們也稱為對象實例化
11.3 new關鍵字
new 關鍵字執行過程
- new 構造函數可以在記憶體中創建了一個空的對象
- this 就會指向剛纔創建的空對象
- 執行構造函數裡面的代碼給這個空對象添加屬性和方法
- 返回這個對象(所以構造函數裡面不需要 return)
11.4 遍歷對象屬性
for...in 語句用於對數組或者對象的屬性進行迴圈操作。
語法格式:
for (變數 in 對象){
...
}
案例:
var obj = {
uname: '張三',
age: 18,
address: '深圳'
}
for(var k in obj){
// console.log(k); // 輸出屬性名
console.log(obj[k]); // 輸出屬性值
}
12 內置對象
12.1 內置對象
- JavaScript中的對象分為3種∶自定義對象、內置對象、瀏覽器對象
- 前面兩種對象是JS基礎內容,屬於ECMAScript;
- 第三個瀏覽器對象屬於我們S獨有的,我們JS API講解
- 內置對象就是指JS語言自帶的一些對象,這些對象供開發者使用,並提供了一些常用的或是最基本而必要的功能(屬性和方法)
- 內置對象最大的優點就是幫助我們快速開發
- JavaScript提供了多個內置對象:Math、Date 、Array、String等
12.2 查文檔
MDN
學習一個內置對象的使用,只要學會其常用成員的使用即可,我們可以通過查文檔學習,可以通過MDN/W3C來查詢。
Mozilla開發者網路(MDN )提供了有關開放網路技術 (Open Web )的信息,包括HTML、CSS和萬維網及HTML5應用的API。
MDN首頁:https://developer.mozilla.org/zh-CN/
如何學習對象中的方法
1)查閱該方法的功能
2)查看裡面參數的意義和類型
3)查看返回值的意義和類型
4)通過 demo 進行測試
12.3 Math對象
Math概述
Math對象不是構造函數,它具有數學常數和函數的屬性和方法。跟數學相關的運算(求絕對值,取整、最大值等)可以使用Math 中的成員。
Math.PI; // 圓周率
Math.floor(); // 向下取整
Math.ceil(); // 向上取整
Math.round(); // 四捨五入版 就近取整 註意 -3.5 結果是 -3
Math.abs(); // 絕對值
Math.max(); // 最大值
Math.min(); // 最小值
隨機數方法 Math.random()
Math.random()
函數返回一個浮點數,偽隨機數在範圍從0 到小於1,也就是說,從 0(包括 0)往上,但是不包括 1(排除 1)
更多解釋請見:Math.random
12.4 日期對象
創建一個新Date
對象的唯一方法是通過new
操作符,例如:let now = new Date();
若將它作為常規函數調用(即不加 new
操作符),將返回一個字元串,而非 Date
對象。
Date概述
- Date對象和Math對象不一樣,他是一個構造函數,所以我們需要實例化後才能使用
- Date 實例用來處理日期和時間
Date()方法的使用
獲取當前時間必須實例化
var now = new Date();
console.log(now);
Date()構造函數的參數
如果括弧裡面有時間,就返回參數裡面的時間。例如日期格式字元串為‘2019-5-1’,可以寫成 new Date(2019-5-1) 或者new Date(2019/5/1)
日期格式化
我們想要 2019-8-8 8:8:8 格式的日期,要怎麼辦?
需要獲取日期指定的部分,所以我們要手動的得到這種格式。
方法名 | 說明 | 代碼 |
---|---|---|
getFullYear() | 獲取當年 | dObj.getFullYear() |
getMonth() | 獲取當月(0-11) | dObj.getMonth() |
getDate() | 獲取當天日期 | dObj.getDate() |
getDay() | 獲取星期幾(周日0到周六6) | dObj.getDay() |
getHours() | 獲取當前小時 | dObj.getHours() |
getMinutes() | 獲取當前分鐘 | dObj.getMinutes() |
getSeconds() | 獲取當前秒鐘 | dObj.getSeconds() |
獲取日期的總的毫秒形式
Date 對象是基於1970年1月1日(世界標準時間)起的毫秒數
我們經常利用總的毫秒數來計算時間,因為它更精確。
獲取總的毫秒數(時間戳)有以下4種方法:
// 1、通過 valueOf() 或者 getTime() 獲取
var date = new Date();
console.log(date.valueOf()) // 現在時間距離1970年1月1日的毫秒數
console.log(date.getTime())
console.log('----------------------')
// 2、簡單寫法(最常用的寫法)
var date1 = +new Date(); // +new Date() 返回總的毫秒數
console.log(date1)
console.log('----------------------')
// 3、H5新增的寫法,獲得總的毫秒數
console.log(Date.now())
案例:倒計時
案例分析
- 核心演算法∶輸入的時間減去現在的時間就是剩餘的時間,即倒計時,但是不能拿著時分秒相減,比如05分減去25分,結果會是負數的。
- 用時間戳來做。用戶輸入時間總的毫秒數減去現在時間的總的毫秒數,得到的就是剩餘時間的毫秒數。
- 把剩餘時間總的毫秒數轉換為天、時、分、秒(時間戳轉換為時分秒)
轉換公式如下:
d = parselnt(總秒數/60/60/24); //計算天數
h = parseInt(總秒數/60/60%24); //計算小時
m = parseInt(總秒數/60%60); // 計算分數
s = parseInt(總秒數%60); //計算當前秒數
代碼實現:
function countDown(time){
var nowTime = +new Date(); // 返回當前時間總的毫秒數
var inputTime = +new Date(time); // 用戶輸入的總的毫秒數
var times = (inputTime - nowTime) / 1000; // 轉換為秒
var d = parseInt(times/60/60/24); //計算天數
d = d<10 ? '0' + d: d;
var h = parseInt(times/60/60%24); //計算小時
h = h<10 ? '0' + h: h;
var m = parseInt(times/60%60); // 計算分數
m = m<10 ? '0' + m: m;
var s = parseInt(times%60); //計算當前秒數
s = s<10 ? '0' + s: s;
return d + '天' + h + '時' + m + '分' + s + '秒';
}
console.log(countDown('2022-11-20 23:00:00'))
12.5 數組對象
創建數組的兩種方式
1)利用數組字面創建數組
var arr = [1, 2, 3];
console.log(arr[0]);
2)利用 new Array()
var arr1 = new Array();
var arr2 = new Array(2); // 2 表示數組長度為2,裡面有兩個空數組元素
var arr3 = new Array(2, 3); // 等價於[2, 3],這樣寫表示裡面有2個數組元素是2和3
判斷是否是數組
1)instanceof 運算符,可以用來檢測是否為數組
var arr = [1, 2, 3];
var obj = {};
console.log(arr instanceof Array); // true
console.log(obj instanceof Array); // false
2)Array.isArray(參數);H5新增的方法
var arr = [1, 2, 3];
var obj = {};
console.log(Array.isArray(arr)); // true
console.log(Array.isArray(obj)); // false
添加刪除數組元素的方法
方法名 | 說明 | 返回值 |
---|---|---|
push(參數1...) | 末尾添加一個或多個元素,註意修改原數組 | 並返回新的長度 |
pop() | 刪除數組最後一個元素,把數組長度減1無參數、修改原數組 | 返回它刪除的元素的值 |
unshift(參數1...) | 向數組的開頭添加一個或更多元素,註意修改原數組 | 並返回新的長度 |
shift() | 刪除數組的第一個元素,數組長度減1無參數、修改原數組 | 並返回第一個元素的值 |
案例:有一個包含工資的數組[1500,1200,2000,2100,1800],要求把數組中工資超過200O的冊除,剩餘的放到新數組裡面
var arr = [1500, 1200, 2000, 2100,1800];
var newArr = [];
for (var i=0; i<=arr.length; i++){
if (arr[i] < 2000){
// newArr[newArr.length] = arr[i];
newArr.push(arr[i]);
}
}
console.log(newArr);
數組排序
方法名 | 說明 | 是否修改原數組 |
---|---|---|
reverse() | 顛倒數組中元素的順序,無參數 | 該方法會改變原來的數組返回新數組 |
sort() | 對數組的元素進行排序 | 該方法會改變原來的數組返回新數組 |
數組索引方法