一、初識JavaScript
JavaScript 是 Web 的編程語言。
所有現(xiàn)代的 HTML 頁面都使用 JavaScript。
在網(wǎng)頁中,JavaScript 代碼,需要在script標簽中定義。
script標簽可以放在的網(wǎng)頁的任何地方,但是,通常會放到body標簽的最下方,
確保JavaScript 代碼,在網(wǎng)頁的內(nèi)容全部加載完畢后再執(zhí)行。
1.輸出語句
console.log 輸出信息
console.warn 輸出警告信息
console.error 輸出錯誤信息
console.table 以表格的方式展開對象的成員信息
console.time(name) 開始測試時間
console.timeEnd(name) 結(jié)束測試時間
2.定義變量
1.什么變量
就是內(nèi)存中的一個空間,用于存儲數(shù)據(jù),數(shù)據(jù)的種類是不一樣的,所以對空間的要求也不一樣。
定義不同類型的變量,其實就是定義不同的存儲空間,存儲不同的數(shù)據(jù)。
var是定義變量的關鍵字,定義變量的方式是:var 變量名 = 變量值。
變量名就是變量的標識,用于之后重新獲取變量里面保存的值。
注意:js是一門弱類型語言,不像java,C#是強類型語言。
強類型語言,在定義變量的時候,就必須要明確類型,并且之后不能再改變類型。
弱類型語言,在定義變量的時候,不需要明確類型,類型由具體的數(shù)據(jù)確定,并且之后可以改變類型。
2.類型
number是數(shù)字類型,注意:在js中,整型和浮點型的數(shù)據(jù)都是number類型。
string是字符串類型,由一對雙引號 或 單引號 引起來的數(shù)據(jù)都是字符串。
boolean是布爾類型,布爾類型用于表示:真 或 假。只有兩個屬性值:true 和 false。
undefined是未定義類型,變量已經(jīng)定義,但是還沒有賦值。
object是對象類型,用于定義復雜的數(shù)據(jù)格式。
null是空類型,用于表示空對象,所以,null本質(zhì)上也是object類型,但是不具有object默認的屬性和行為。
symbol是ES6新增了一個數(shù)據(jù)類型,用于確定一個唯一的數(shù)據(jù),通常用于給對象添加唯一的屬性 或 方法。
ES6指的是ECMAScript2015之后的版本
注意:在js中,每條語句采用分號結(jié)尾,分號可以省略。
總結(jié):在js中,數(shù)據(jù)類型一共有7個。
分別是:number(數(shù)字類型),string(字符串類型),boolean(布爾類型),undefined(未定義類型),
object(對象類型),null(空對象類型),symbol(唯一值類型)。
3.算術運算符
算術運算符:+ - * / %
注意:字符串 + 任何數(shù)據(jù) 都是拼接,重新返回新的字符串。
表達式是從左往右執(zhí)行,當遇到字符串時,整個表達式才當做字符串處理。
除法運算,除法會保留小數(shù)。
parseInt()函數(shù),用于取整數(shù),注意:并不是四舍五入,而且去掉小數(shù)。
簡寫形式:
b += a //b = b + a
b -= 10 //b = b - 10
b *= 2 //b = b * 2
b /= 5 //b = b / 5
b %= 3 //b = b % 3
num++ // num = num + 1
++num // ++可以放在變量的后面,也可以放在變量的前面
++在變量的后面,表示先返回變量的原值,再加1
++在變量的前面,表示變量的值先加1,再返回變量的值
4.比較運算符
比較運算符:> >= < <= == !=?===(全等于,恒等于)?!==(恒不等于)
使用比較運算符的表達式是比較表達式,比較表達式返回的數(shù)據(jù)類型是boolean類型
注意:采用==比較兩份數(shù)據(jù)是否相等,只比較值,不比較類型。
注意:采用===比較兩份數(shù)據(jù)是否相等,值要相等,類型也要相等。
注意:采用!=比較兩份數(shù)據(jù)是否不相等,只比較值,不比較類型。
注意:采用!==比較兩份數(shù)據(jù)是否不相等,值不相等或者類型不相等。
5.邏輯運算符
邏輯運算符:&&(并且) ||(或者) !(取反)
|| 是或運算符,左右兩個表達式,其中一個返回true,整個表達式返回true
&& 是與運算符,左右兩個表達式,都返回true,整個表達式才返回true
! 是非運算符,用于將表達式的值取反值,如果表達式返回true,取反就是false
6.運算符的優(yōu)先級
運算符的優(yōu)先級:() > 算術運算符 > 關系運算符 > ! > && > ||
7.命名規(guī)范
變量里面保存的是一份數(shù)據(jù),為了方便將來獲取里面存儲的數(shù)據(jù),變量名命名一定要規(guī)范。
就是看到變量名就知道里面存儲的是什么數(shù)據(jù)。(見名知意)
在JS中,變量名的規(guī)范有:
只能使用:字母、數(shù)字、_、$ 做為變量名稱。
數(shù)字不要開頭
不能使用JS的關鍵字
多個單詞組成的變量名,要使用駝峰命名法,第一個單詞的首字母小寫,其余單詞的首字母大寫。
二、選擇結(jié)構(gòu)
1.JavaScript的組成
1.三大核心
ESMAScript 核心語法(標準規(guī)范)-> SE6
BOM 瀏覽器對象模式,其實就是window對象,該對象可以操作瀏覽器
DOM 文檔對象模型,其實就是document對象,該對象可以操作網(wǎng)頁里面的所有元素
2.window對象的常用方法
alert()方法,用于打開消息框
prompt()方法,用于打開輸入框,輸入框返回的數(shù)據(jù)的類型是string類型
confirm()方法,用于打開確定框,確認框里面有兩個按鈕,確定和取消,點擊確定按鈕返回true,點擊取消按鈕返回false
parseInt()方法,用于將字符串數(shù)據(jù),強轉(zhuǎn)為整型
parseFloat()方法,用于將字符串數(shù)據(jù),強轉(zhuǎn)為浮點型
isNaN()方法,用于判斷一份數(shù)據(jù)是不是NaN數(shù)據(jù)(not a number)
3.if選擇結(jié)構(gòu)
if選擇結(jié)構(gòu)的語法是:if(判斷條件){滿足條件之后,執(zhí)行的代碼塊}
if-else選擇結(jié)構(gòu),if()里面的條件成立執(zhí)行if{}里面的代碼塊,否則執(zhí)行else{}里面的代碼塊
注意:當if或者else里面只有條件語句的時候,可以省略{}
建議:初學者,不要省略{}
4.多重if選擇結(jié)構(gòu)
多重if選擇結(jié)構(gòu)里面,滿足其中一個條件,執(zhí)行該條件對應的代碼,執(zhí)行完成后跳出整個程序結(jié)構(gòu)。
如果所有的條件都不成立,有else,就執(zhí)行else;沒有else,整個程序結(jié)構(gòu)結(jié)束。
練習題:
如果有500萬存款,買一輛奔馳-邁巴赫S600
如果有300萬存款,買一輛寶馬740
如果有100萬存款,買一輛奧迪A6L
如果有50萬存款,買一輛大眾途觀L
如果有10萬存款,買一輛奧拓
否則,買一輛捷安特
4.嵌套if選擇結(jié)構(gòu)
嵌套if選擇結(jié)構(gòu):就是在一個完整的if或者else的結(jié)構(gòu)中,繼續(xù)使用if結(jié)構(gòu)語句。
練習題:
請輸入是否是會員,輸入y是會員,輸入n不是會員
請輸入消費金額
會員:消費打8折,滿100元打6折
非會員:消費滿200元打9折,不滿200元不打折
最后輸出本次實際消費金額
多重if和嵌套if的綜合練習題:
輸入年 月 輸出該月份有多少天?
閏年公式:年份能被4整除,但不能被100整除;或者年份能被400整除。閏年的2月份是29天,平年的2月份是28天。
5.switch選擇結(jié)構(gòu)
switch選擇結(jié)構(gòu),也是用于進行多分支判斷,語法結(jié)構(gòu)比多重if簡潔。
但是,switch選擇結(jié)構(gòu)只能進行等值判斷。
語法結(jié)構(gòu)是:將需要進行等值判斷的變量,放到()里面。在{}里面通過case后面的值跟它進行等值判斷。
注意1:case語句,在結(jié)束之前,通常都要加上break,表示跳出switch選擇結(jié)構(gòu),因為,
switch選擇結(jié)構(gòu),里面的case一旦判斷成立,后面的case就不會再進行判斷了。
注意2:如果多個case的輸出結(jié)果相同,可以將多個case的結(jié)果合并,并省略前面case的break。
6.三元運表達式
三元表達式,可以簡化基本的if-else語句結(jié)構(gòu)
varc=a>10?100:200
三元表達式,也可以簡化復雜的if-else語句結(jié)構(gòu)
vare=a>20?200:(a>10?100:300)
7.作業(yè)
計算器:輸入第一個數(shù),輸入第二個數(shù),輸入操作類型(+ - * / %),輸出兩個數(shù)的計算結(jié)果
成績:輸入html成績,輸入javascript成績,
如果html成績大于80分,并且javascript成績大于70分,或者 html成績等于100分,javascript成績大于60分,獎勵手機一部
如果html成績大于70分,并且javascript成績大于60分,或者 javascript成績等于100分,html成績大于60分,獎勵mp4一個
否則,沒有任何獎勵
結(jié)婚:輸入身高,輸入顏值(0-10),輸入收入
如果身高超過180,顏值超過8分,輸入超過10000,全部滿足,立馬結(jié)婚。
滿足其中兩個,考慮一下。
滿足其中一個,你是一個好人。
一個都不滿足,滾。
三、循環(huán)結(jié)構(gòu)1
1.var let const
使用var關鍵字定義的變量,變量名可以重復,后面的變量會將前面的變量覆蓋掉。
var方式定義變量,會統(tǒng)一提升到全局作用域的頂端定義,然后再指定的地方賦值。
var定義的變量,即使在指定的代碼塊中,仍然會提升到全局作用域的頂端。
因為使用var定義變量,存在上面的各種問題,所以從ES6開始,又引入的新的方式定義變量
使用let,在同一個作用域中,不能定義同名的變量。
let定義的變量,不存在提升。
const關鍵字,用于定義常量,常量的特點是:不能重新賦值,并且在定義時,必須要賦值。
2.模板字符串
使用 '' 和 "" 定義的數(shù)據(jù)是字符串數(shù)據(jù)
console.log('大家好!我叫'+name+',今年'+age+'歲,性別是'+gender+',職業(yè)是'+job);
在ES6中,又加入 `` ,在反引號里面,可以定義模板字符串,方式是${變量名}
console.log(`大家好!我叫${name},今年${age}歲,性別是${gender},職業(yè)是${job}`);
如果字符串采用""包裹,里面可以定義''
如果字符串采用''包裹,里面可以定義""
如果希望我們定義的字符串中,既包括雙引號,又包括單引號,過去是采用轉(zhuǎn)義字符的方式定義的。
轉(zhuǎn)義字符串:\" 表示 " \' 表示 '
console.log("\'大家好\'!\"才是真的好\"!");
現(xiàn)在可以直接在模板字符串中使用雙引號和單引號
console.log(`'大家好'!"才是真的好"!`);
轉(zhuǎn)義字符的其他用法
\t 表示水平制表符,其實就是一個Tab鍵
\n 表示換行符,其實就是一個Enter鍵
\\ 表示一個\
3.while循環(huán)
//()里面是循環(huán)的條件,條件成立,執(zhí)行{}里面的操作while(條件){操作}
練習題1:找出100以內(nèi),能被3整除的數(shù),并輸出
練習題2:找出21世紀里面所有的閏年,并打印出來
練習題3:輸入年 月 日,算出該日期是全年的第多少天
4.do-while循環(huán)
do{操作}while(條件)
while循環(huán)的特點是:先判斷條件,再執(zhí)行循環(huán)操作
do-while循環(huán)的特點是:先執(zhí)行一次循環(huán)操作,再判斷循環(huán)條件
所以,do-while循環(huán),沒有入口判斷,無論循環(huán)條件是否滿足,至少會執(zhí)行一次循環(huán)體
練習題1:系統(tǒng)菜單:輸入 1.添加學生,2.修改學生,3.查詢學生,4.刪除學生,0.退出系統(tǒng)
練習題2:小型ATM機系統(tǒng)
5.作業(yè)
打印輸出3位數(shù)里面所有的水仙花數(shù),百位數(shù)的3次方+十位數(shù)的3次方+個位數(shù)的3次方===這個數(shù)
輸入你的出生年月日,再輸入當前日期的年月日,計算出你一共活了多少天
輸入一個指定的日期,輸出該日期是星期幾,提示:1900-1-1是星期一
四、循環(huán)結(jié)構(gòu)2
1.for循環(huán)
for(條件變量;循環(huán)條件;迭代部分){操作}
for循環(huán),就是由while循環(huán)演變而來
在for循環(huán),可以將循環(huán)的條件變量,判斷條件,對象循環(huán)變量重新賦值,放在一起,好處是不容易遺漏任何一部分
for循環(huán)結(jié)構(gòu)中的循環(huán)變量可以定義多個
while,do-while,for,如何選擇:
當循環(huán)的次數(shù)是固定的時候,通常使用for循環(huán)
當循環(huán)的次數(shù)不固定的時候,通常會使用while和do-while循環(huán)
2.循環(huán)的跳出語句(continue,break)
在循環(huán)結(jié)構(gòu)中break,表示跳出整個循環(huán)
在循環(huán)結(jié)構(gòu)中continue,表示跳出本次循環(huán)
練習題1:會員登錄,一共有3次登錄機會,如果,第一次登錄失敗,提示失敗原因,并告知還剩下幾次機會
如果,登錄名輸入錯誤,顯示信息,并且密碼就不需要在輸入了
如果,第一次就登錄成功,后面的機會就不需要了
練習題2:會員注冊,注冊會員信息,輸入會員號(必須是4位整數(shù)),輸入姓名,輸入性別(只能是男或女)
一共有三次機會,會員信息輸入錯題,提示錯誤信息,并顯示還有幾次機會
練習題3:猜數(shù)小游戲,系統(tǒng)隨機返回一個1-100之間的數(shù),給5次機會,猜這個數(shù)
每次猜的數(shù),要提示用戶,猜大了還是猜小了
提示:Math.random()隨機返回0到1之間的小數(shù)
五、多重循環(huán)
在二重循環(huán)中,外層循環(huán)變量變化一次,內(nèi)層循環(huán)變量變化整個
練習題1:有三個班級,每個班級有四名學生,輸入所有學生的成績,并計算出每個班級的平均分
練習題2:打印直角三角形
練習題3:打印倒直角三角形
練習題4:打印等腰三角形
練習題5:打印99乘法表
練習題6:數(shù)字等腰三角形
練習題7:找出100以內(nèi)所有的質(zhì)數(shù)
在內(nèi)層循環(huán)中,使用continue,break,只是作用于內(nèi)層循環(huán)
練習題:有5家店,每家店最多可以買3件衣服,進入一家店后,提示是否離開本店,
輸入y表示離開(會進入下一家店),輸入n表示買一件衣服,最后輸出用戶一共買了多少件衣服。
作業(yè)
雞兔同籠:有25個頭,94只腳,請問雞和兔各多少只
百錢買百雞:公雞5文錢一只,母雞3文錢一只,小雞1文錢3只,請問公雞母雞小雞各多少只
打印菱形
打印空心菱形
六、字符串和數(shù)組
1.字符的常用方法
length屬性,返回的是字符串的長度
charAt()方法,根據(jù)字符串中字符的索引(下標)獲取對應的字符,注意:索引從0開始
獲取字符串的中指定索引的字符,也可以通過[索引]的方式獲取
charCodeAt()方法,用于獲取字符串中指定位置字符的Unicode編碼值
什么是Unicode編碼,不同國家的人,使用不同的字符描述數(shù)據(jù),這些字符計算機不認識
計算機只認識二進制數(shù)字,也就是0和1,所以將全世界范圍內(nèi)使用的常用字符都定義一個對應的十進制數(shù)字編碼
而這個十進制的數(shù)字編碼就是Unicode編碼,再將這些十進制的Unicode編碼轉(zhuǎn)為二進制編碼傳給計算機識別
比如:A -> 65 a -> 97 你 -> 20320
concat()方法,用于拼接字符串,通常情況下,我們可以直接使用 加號 去拼接,該方法,可以同時拼接多個字符串數(shù)據(jù)
fromCharCode()方法,用于將指定的Unicode編碼轉(zhuǎn)為指定字符,注意該方法是有String類型來調(diào)用的,該方法,可以傳遞多個Unicode編碼
indexOf()方法,用于從字符串中返回指定字符串第一次出現(xiàn)的位置(注意:索引從0開始,找不到返回-1)
lastIndexOf()方法,是從后往前找,找到后,下標是從前往后數(shù)(注意,如果找不到返回-1)
slice()方法,用于截取指定區(qū)間范圍內(nèi)的字符串,該方法需要傳兩個參數(shù),分別是起始位置和結(jié)束位置,能夠取到起始位置,取不到結(jié)束位置,注意:slice()方法的參數(shù),可以傳負數(shù),表示從后往前數(shù)索引
substring()方法,用于截取指定區(qū)間范圍內(nèi)的字符串,該方法需要傳兩個參數(shù),分別是起始位置和結(jié)束位置,能夠取到起始位置,取不到結(jié)束位置,注意:substring()方法參數(shù),只能傳正數(shù),不能傳負數(shù)
substr()方法,也是用于截取字符串,它的兩參數(shù)分別是:起始位置和截取長度
注意:slice,substring,substr方法,如果只傳1個參數(shù),就表示從起始位置到最后全部截取
toLowerCase()方法,用于返回字符串轉(zhuǎn)的小寫版本,注意:不是改自身
toUpperCase()方法,用于返回字符串的大寫版本,注意:不是改自身
trim()方法,用于去除字符串兩端空格
2.字符串練習題
輸入郵箱地址,驗證郵箱格式是否正確
輸入登錄名和密碼,要求登錄名長度為2-4位,密碼長度是6-10位,用戶名不能是全數(shù)字
輸入手機號碼,要求長度必須是11位,第一位必須是1,后面的必須是數(shù)字
3.數(shù)組
變量:就是在內(nèi)存中,開辟一個合適的空間,存儲一份對應的數(shù)據(jù)
數(shù)組:就是在內(nèi)層中,開辟一段連續(xù)的空間,存儲一組數(shù)據(jù)
創(chuàng)建數(shù)組的第一種方式,使用數(shù)組的構(gòu)造函數(shù),new一個數(shù)組類型的對象
letarr1=newArray(5)
創(chuàng)建數(shù)組的第二種方式:使用字面量方式直接定義
letarr2=["hello","world"]
length屬性,返回的是數(shù)組的長度
根據(jù)數(shù)組的下標(索引),向數(shù)組中存放數(shù)據(jù),數(shù)組中可以存放任意類型的數(shù)據(jù)
注意:在創(chuàng)建數(shù)組對象時,可以給一個固定的長度,但是沒有意義,因為在js中數(shù)組的長度是可以隨意變化的
4.數(shù)組的常用方法
concat()方法,用于合并兩個或多個數(shù)組,返回一個全新的數(shù)組
copyWithin()方法,從數(shù)組的指定位置拷貝元素到數(shù)組的另一個指定位置中
注意:第一個參數(shù)是目標位置,第二個參是拷貝元素的起始位,第三個參數(shù)是拷貝元素的結(jié)束位置
如果不設置第三個參數(shù),拷貝元素結(jié)束位置就是目標位置的前一位
fill()方法,使用一個固定值來填充數(shù)組
includes()方法,從數(shù)組中檢查指定的數(shù)據(jù)是否存在,存在返回true,不存在返回false
indexOf()方法,從數(shù)組中檢查指定的數(shù)據(jù)的位置(從前往后找第一個),不存在返回-1
lastIndexOf()方法,從數(shù)組中檢查指定的數(shù)據(jù)的位置(從后往前找第一個),不存在返回-1
isArray()方法,用于檢查指定的對象是否是數(shù)組,注意:該方法屬于Array類型,不屬于Arrary的對象
join()方法,用于將一個數(shù)組根據(jù)某個字符串拼接成字符串,該方法不傳參數(shù),默認是根據(jù)逗號拼接
push()方法,向數(shù)組的末尾添加一個或更多元素,并返回新的長度
pop()方法,刪除數(shù)組的最后一個元素并返回刪除的元素
unshift()方法,向數(shù)組的開頭添加一個或更多元素,并返回新的長度
shift()方法,刪除并返回數(shù)組的第一個元素
reverse()方法,反轉(zhuǎn)數(shù)組的元素順序
slice()方法,選取數(shù)組的一部分,并返回一個新數(shù)組
注意:該方法的第一個參數(shù)是起始位置,第二個參數(shù)是結(jié)束位置(取不到結(jié)束位置)
第二個參數(shù)可以省略,表示從起始位置到最后全部返回
splice()方法,從數(shù)組中添加或刪除元素
如何刪除,該方法需要傳兩個參數(shù):第一個是起始位置,第二個是刪除長度
如果第二個參數(shù)不傳,就表示從起始位置往后全部刪除
刪除方法,刪除的是原始數(shù)組里面的數(shù)據(jù),返回的是刪除的數(shù)據(jù)
該方法也可以傳三個參數(shù),第三個參數(shù)就是刪除部分插入的新內(nèi)容
repeat(num) 方法,用于重復指定的字符串多少次
toString()方法,把數(shù)組轉(zhuǎn)換為字符串,并返回結(jié)果
5.數(shù)組練習題
如何反轉(zhuǎn)字符串
先將字符串轉(zhuǎn)為數(shù)組,再將數(shù)組反轉(zhuǎn),然后將反轉(zhuǎn)后的數(shù)組,再轉(zhuǎn)為字符串
學生管理系統(tǒng)
定義四個數(shù)組,分別存儲學生的學號,姓名,年齡,性別
6.作業(yè)
隨機生成一組雙色球號碼,存放到數(shù)組中
雙色球號碼的規(guī)則是:前六組號碼是1-32之間不重復的隨機數(shù),第七組號碼是1-16之間的隨機數(shù)
隨機生成一組七星彩號碼,存放到數(shù)組中
七星彩號碼的規(guī)則是:七組0-9之間的可重復的隨機數(shù)
七、Math和Date
1.排序算法
sort()方法,用于對數(shù)組排序
注意:該排序方法,是根據(jù)數(shù)組中,每一個元素首字符的unicode編碼進行排序的
手寫排序算法:
冒泡排序算法
選擇排序算法
2.Math對象
Math對象 里面提供的方法,可以幫助我們解決算術問題
提供的方法:
Math.random() 返回一個0到1之間的隨機數(shù)
abs() 返回一個數(shù)的絕對值
ceil() 向上取整
floor() 向下取整
max() 返回最大值
min() 返回最小值
pow() 返回指定數(shù)的次冪
round() 四舍五入
PI屬性,返回圓周率
3.Date對象
創(chuàng)建并返回系統(tǒng)當前日期
letdate1=newDate()
在創(chuàng)建日期對象時,可以傳遞一個時間戳參數(shù)
時間戳:是從1970-1-1開始的毫秒數(shù)
letdate2=newDate(123456789)
也可以根據(jù)一個指定的時間,返回一個日期對象
letdate3=newDate('2011-1-1 12:12:12')
提供的方法:
getFullYear() 返回年份
getMonth() 返回月份 返回的值是0-11(0表示1月份,11表示12月份)
getDate() 返回月份的日期
getDay() 返回星期幾 返回的值是0-6,(0表示星期天)
getHours() 返回小時 返回的值是0-23(0表示凌晨12點)
getMinutes() 返回分鐘
getSeconds() 返回秒
getMilliseconds() 返回毫秒
getTime() 返回時間戳
getXXX方法用于獲取時間對象中指定的部分
setXXX方法用于設置時間對象中指定的部分
練習題:計算兩個日期相差多少天,注意:兩日期對象相減,返回的是兩個日期時間戳相減后的值
八、函數(shù)
1.定義
function 是定義函數(shù)的關鍵字,函數(shù)也稱為方法。
函數(shù)分為:無參函數(shù)、帶參函數(shù)、帶返回值的函數(shù)
定義函數(shù)
functionfn(形參){方法體}
調(diào)用函數(shù)
fn(實參)
2.實現(xiàn)字符串函數(shù)
將字符串身上的常用函數(shù),手動實現(xiàn)一遍
3.實現(xiàn)數(shù)組的函數(shù)
將數(shù)組身上的常用函數(shù),手動實現(xiàn)一遍
4.定義函數(shù)的幾種方式
第一個方式:通過function關鍵字直接定義
第二種方式:定義一個變量,接收定義的函數(shù)
ES6又推出了定義函數(shù)的簡寫方式,俗稱:箭頭函數(shù)
在箭頭函數(shù)中,如果方法體只有一條語句,可以省略{}
在箭頭函數(shù)中,如果方法只有一個參數(shù),可以省略()
在箭頭函數(shù)中,如果方法體只有一條語句,并該語句是返回語句,那么在省略{}的同時,必須省略return關鍵字
5.定義幾個工具方法
檢查一個年份是否是閏年
對個位數(shù)字補零
返回一個日期的短日期格式
返回一個中國式的日期格式
對字符串反轉(zhuǎn)
6.遞歸方法
什么是遞歸方法:就是一個方法,自己調(diào)用自己
注意:遞歸方法,一定要控制好合適跳出,否則就是死循環(huán)
練習題1:計算1-20之間所有數(shù)之和
functioncalc(num){if(num===1){returnnum}letsum=num+calc(num-1)returnsum}
練習題2:實現(xiàn)系統(tǒng)菜單
functionmenu(){letno=parseInt(prompt('1.添加學生,2.修改學生,3.刪除學生,0.退出系統(tǒng)'))switch(no){case1:alert('執(zhí)行添加學生')menu()break;case2:alert('執(zhí)行修改學生')menu()break;case3:alert('執(zhí)行刪除學生')menu()break;default:return//表示退出方法}}
九、高階函數(shù)
什么是高階函數(shù):就是一個函數(shù)的參數(shù)是函數(shù),或者返回值是函數(shù),滿足其中一個就是高階函數(shù)
開閉原則:對擴展是開發(fā)的,對修改是封閉的
1.定義計算器方法
functioncalc(num1,num2,callback){callback(num1,num2)}
2.回調(diào)函數(shù)
輸出數(shù)組中所有的數(shù)
輸出數(shù)組中所有的奇數(shù)
輸出數(shù)組中所能被3整除的數(shù)
分析問題:都用到了for循環(huán)
定義一個通用的for方法:
function bingFor(arr, callback) {
????for(leti=0; i<arr.length; i++) {
????????if(callback(arr[i])) {
????????????console.log(arr[i]);
????????}
????}
}
3.數(shù)組的高階方法
forEach()方法,用于循環(huán)遍歷整個數(shù)組
該方法的參數(shù)是一個回調(diào)函數(shù),回調(diào)函數(shù)可以傳兩個參數(shù),第一個參數(shù)是數(shù)組中的每一項元素,
第二個參數(shù)是每一項元素對應的下標。
注意:第二個參數(shù)可以省略。
filter()方法,用于過濾數(shù)組中的元素,返回過濾結(jié)果
find()方法,用于獲取數(shù)組中滿足規(guī)則的第一個元素
findIndex()方法,用于獲取數(shù)組中滿足規(guī)則的第一個元素下標
some()方法,用于表示數(shù)組中是否有滿足指定規(guī)則的元素,有返回true,一個都沒有返回false
every()方法,用于表示數(shù)組中是否所有元素都滿足指定的規(guī)則
map()方法,用于將原始數(shù)組里面的數(shù)據(jù)根據(jù)指定的規(guī)則返回新的數(shù)組
sort()方法,對數(shù)組的元素進行排序
回調(diào)函數(shù)需要傳兩個參數(shù),返回參數(shù)1-參數(shù)2是升序,返回參數(shù)2-參數(shù)1是降序
reduce()方法,統(tǒng)計數(shù)組中元素的值(從左到右)
reduceRight()方法,統(tǒng)計數(shù)組中元素的值(從右到左)
4.閉包函數(shù)
定義一個a方法,在a方法中定義一個b方法,并且b方法里面用到了a方法里面定義的變量,
那么此時就形成了閉包函數(shù)
由于內(nèi)部方法里面,用到外部方法里面的變量,外部方法里面的那個變量會一直在內(nèi)存中存保存著
總結(jié):兩個方法嵌套定義,里面的方法,用到了外面方法里面定義的變量,此時這兩個方法就形成了閉包。
閉包案例:計算機
functioncalc(n1, n2, type){
????// 數(shù)據(jù)定義在函數(shù)里面,用參數(shù)傳值,保證了數(shù)據(jù)的安全性
????let num1 = n1
????let num2 = n2
????switch(type){
????????case '+':
????????????return function(){
????????????????console.log(`${num1} + ${num2} = ${num1 + num2}`);
????????????}
????????case '-':
????????????return function(){
????????????????console.log(`${num1} - ${num2} = ${num1 - num2}`);
????????????}
????}
}
5.作業(yè)
實現(xiàn)數(shù)組的高階函數(shù)的原理:
forEach
filter
find
findIndex
some
every
map
十、函數(shù)其他
1.實現(xiàn)數(shù)組的高階函數(shù)
2.arguments
arguments對象里面保存這方法的所有參數(shù)
arguments對象里面有個一個callee方法,該方法指向當前方法本身
定義穩(wěn)定的遞歸函數(shù):
functioncalc(num){if(num===1){returnnum}// 因為arguments.callee 就時 指向當前方法本身。// 這樣的做的好處是,防止外部方法名修改后,導致遞歸調(diào)用失效。letsum=num+arguments.callee(num-1)returnsum}
3.分頁方法
//定義一個分頁方法,方法的三個參數(shù)分別是:原始數(shù)組,頁碼,每頁數(shù)量
function pageData(arr, pageIndex, pageSize) {
????//思路:就是對原始數(shù)組中的數(shù)據(jù),做截取
????//定義截取數(shù)據(jù)的起始位置
????let start = (pageIndex - 1) * pageSize
????//定義截取數(shù)據(jù)的結(jié)束位置
????let end = start + pageSize
????return arr.slice(start, end)
}
十一、對象
如果 a.b ,那么a就是對象,b是a的屬性
如果 a.c(),那么a就是對象,c是a的方法
對象就是擁有一組屬性和方法的集合
定義對象有兩種方式:1.采用字面量賦值方式直接定義。2.采用構(gòu)造函數(shù)的方式new一個對象
1.采用字面量賦值方式定義對象
letobj={//定義屬性//定義方法}
通過對象名.屬性,調(diào)用對象的屬性,可以獲取屬性的值,也可以修改屬性的值,也可以添加新的屬性
通過對象名.方法(),調(diào)用對象的方法,執(zhí)行方法里面的代碼
案例:定義計算器對象,實現(xiàn)加減乘除。
2.采用構(gòu)造函數(shù)的方式new一個對象
可以直接new一個Object對象
letobj=newObject()
可以定義一個構(gòu)造函數(shù),再出new這個構(gòu)造函數(shù)的對象
構(gòu)造函數(shù)也稱為:類,是自定義的一種類型
//定義學生類functionStudent(形參...){//定義屬性(必須使用this.)//定義方法(必須使用this.)}//創(chuàng)建學生對象lets1=newStudent(實參...)
3.作業(yè)
定義一個棋子類,里面有四個屬性,分別是:名稱,顏色,X軸位置,Y軸位置
比如:紅色的馬,當前位置是(X=15,Y=11)
里面有兩個方法:分別是:
1.顯示當前棋子在什么位置
2.移動方法,該方法,需要傳兩個參數(shù),就是X軸和Y軸的新坐標,移動方法執(zhí)行完后,在方法的最下面,調(diào)用一次顯示當前位置的方法。
十二、對象進階
1.this
構(gòu)造函數(shù)里面的this,用于給類定義成員(屬性和方法)
方法里面的this,指向方法的調(diào)用者
箭頭函數(shù)中沒有this,如果在箭頭函數(shù)中使用了this,會向外層尋找this的指向
如果所有的外層都沒有this,最終會指向window對象
注意:用于var定義的成員(變量和方法)都會成為window對象的成員
解決this指向問題:
方式一:備份this
方式二:使用箭頭函數(shù)
2.call apply bind
call apply bind 更改方法里面this的指向
使用call()改變方法里面,this的指向
call()方法的第一個參數(shù)必須是指定的對象,方法的原有參數(shù),挨個放在后面
使用apply(),也可以改變方法里面this的指向,第一個參是指定的對象,方法的原有參數(shù),統(tǒng)一放到第二個數(shù)組參數(shù)中。
使用bind(),也可以改變方法里面this的指向,用法給call()一樣
call()是直接運行方法,bind()是返回新的方法,然后再重新調(diào)用。
3.將一個對象轉(zhuǎn)為字符串
獲取對象的屬性值,有兩種方式:
對象名.屬性名
對象名["屬性名"]
//定義一個手機對象
let phone = {name:"小米10",
????color:'紅色',
????size:'1000*200*500',
????price:'2999'
}
//轉(zhuǎn)成下面的字符串
//"name=小米10&color=紅色&size=1000*200*500&price=2999"
for in 循環(huán),可以循環(huán)出對象里面的所有的key,(key就是屬性名)
在ES6中新增了獲取對象所有key的方法 -> ECMAScript2015 其實就是最新版本的javascript標準
Object.keys(指定的對象),該方法可以獲取指定對象的所有key,返回值是一個數(shù)組
Object.values(指定的對象),該方法可以獲取指定對象的所有的value,返回值是一個數(shù)組
4.將字符串轉(zhuǎn)為對象
//定義一個字符串
let str = "name=小米10&color=紅色&size=1000*200*500&price=2999"
//轉(zhuǎn)成一個對象 {name:"小米10",color:'紅色',size:'1000*200*500',price:'2999'}
5.封裝js庫
isLeepYear 判斷是否閏年
strReverse 字符串翻轉(zhuǎn)
getMiniDate 短日期
getChineseDate 中國式日期
getPageData 分頁方法
getStrByObj 對象轉(zhuǎn)字符串
getObjByStr 字符串轉(zhuǎn)對象
6.作業(yè)
統(tǒng)計字符串中每個字符串出現(xiàn)的次數(shù)
letstr="fasdfsadfsegsageqwgersfdhrhdfsergterwhefweteqheq"http://轉(zhuǎn)成下面格式的對象{a:5,b:7,c:9,...}
找出出現(xiàn)次數(shù)最多的字符
//定義一個對象接收結(jié)果letmax={name:'',count:0}
十三、對象數(shù)組
使用對象數(shù)組保存學生信息,實現(xiàn)對學生的增刪改查
作業(yè)
js經(jīng)典面試題
十四、ES6補充
1.講解面試題
2.自執(zhí)行方法
定義一個自執(zhí)行函數(shù),函數(shù)定義完成后,自己執(zhí)行一次,函數(shù)名可以省略,因為沒有任何意義
注意:要以分號結(jié)束,否則可能會影響后面的語句。
(function sayHello() {console.log('sayHello');})();
自執(zhí)行函數(shù)的簡寫形式
+function sayYes() {console.log('sayYes');}();
自執(zhí)行函數(shù),也可以直接定義成箭頭函數(shù)
(()=>{console.log('aaa');})()
3.rest參數(shù)
// ...args 就是rest參數(shù)
function fun1(a,b,c,...args) {console.log(a,b,c);
????// arguments 是一個類數(shù)組對象,結(jié)構(gòu)長得像數(shù)組,其實是一個object對象
????console.log(arguments);
????// rest參數(shù) 是一個數(shù)組對象,既然是數(shù)組,就可以直接使用數(shù)組的方法。
????console.log(args);
}
4.展開運算符
展開運算符就是...,可以將一個數(shù)組全部展開
letarr3=[...arr1,...arr2]
展開運算符,可以展開對象的全部成員,也可以將一個對象的成員,克隆給另一個對象
letlh2={...lh}
展開運算符,可以將多個對象的成員,合并到一個大的對象中,后面對象中的成員,如果跟前面對象中的成員同名,會覆蓋前面的
letlxt={...lh,...gxt}
5.解構(gòu)賦值
ES6中的解構(gòu)賦值語句,可以直接將數(shù)組中的每個元素提取出來
方式是:let [變量名1,變量名2,...] = 數(shù)組
ES6中的解構(gòu)賦值語句,可以直接將對象中的每個元素提取出來
方式是:let {name,age,gender,job} = obj
通常情況下,對象的屬性名稱叫什么,就定義什么名稱的變量去接,如果出現(xiàn)了同名,可以修改名稱
方式是:let {name,age:age1,gender,job} = obj
在ES6中,定義對象時,屬性的左右兩邊的表達式相同時,可以省略右邊的表達式,該對象在定義的時候,會自動往父級作用域?qū)ふ彝麑傩悦麑闹?/p>
十五、類和對象進階
1.值類型和引用類型
在js中,number,string,boolean,都是值類型,值類型的變量,直接將數(shù)據(jù)保存到內(nèi)存的棧空間中。
值類型的變量,在傳遞時,傳的是副本。
在js中,對象,數(shù)組,都是引用類型,引用類型的變量,將數(shù)據(jù)保存在堆中,然后將堆的地址保存到棧中。
2.原型對象
prototype屬性是類的原型對象
通常情況下,我們習慣將類的方法,定義到類的原型對象中,這樣做的好處是,提高代碼的利用率,不會開辟多余的內(nèi)存空間。
__proto__屬性是對象的原型對象,注意:同種類型多個對象上的原型對象 共同指向 類型上的原型對象。
類的原型對象上面的方法,類的對象,可以直接調(diào)用
3.ES6中定義類的新語法
// 定義一個Person類型
classPerson{
????// 構(gòu)造函數(shù)
????constructor(name, age, gender) {
????????this.name = name,
????????this.age = age
????????this.gender = gender
????}
????// 給類添加一個方法
????sayHi = function() {
????????console.log(this.name, this.age, this.gender);
????}
????//用這種方式定義的方法,是將方法定義的類的原型對象中去
????sayHello() {console.log('hello!');}
}
4.繼承
ES5:
// 定義一個人類
function Person(name,age,gender){this.name=namethis.age=agethis.gender=gender}Person.prototype.eat=function(){console.log(`我叫${this.name},我在吃飯...`);}Person.prototype.say=function(){console.log(`大家好!我叫${this.name} 今年${this.age}歲 性別是${this.gender}`);}// 通過Person類型,創(chuàng)建出了兩個對象letp1=newPerson('劉德龍',20,'男')p1.say()p1.eat()letp2=newPerson('高德政',21,'男')p1.say()p1.eat()console.log('-------------------------------------');//定義了學生類functionStudent(name,age,gender,no){// 繼承Person類的屬性Person.call(this,name,age,gender)// Student類特有的屬性this.no=no}// 給Student類的prototype屬性 new一個Person類型的對象// 用于繼承Person類的方法Student.prototype=newPerson()Student.prototype.study=function(){console.log(`我叫${this.name},我的學號是${this.no},我在學習...`);}lets1=newStudent('張三',20,'女','1001')s1.study()s1.eat()s1.say()
ES6:
// 定義人類
class Person{
????// 定義構(gòu)造函數(shù)
????constructor(name,age,gender){
????????this.name=name
????????this.age=age
????????this.gender=gender
????}
????// 說話方法
????say() {console.log(`大家好!我叫${this.name},今年${this.age}歲,性別是${this.gender}。`);}
????// 吃方法
????eat() {console.log(`我叫${this.name},我在吃飯...`);
????}
}
// 每個類型都一個prototype屬性,我們稱它為類的原型對象。
// 類的原型對象上面的成員,給類的所有實例(實例就是類創(chuàng)建出來的對象)共享。
console.log(Person.prototype);
// 通過Person類型,創(chuàng)建出了兩個對象
let p1 = new Person('劉德龍', 20, '男')
console.log(p1);
p1.say()
p1.eat()
let p2 = new Person('高德政',21,'男')
console.log(p2);
p1.say()
p1.eat()
console.log('-------------------------------------');
// extends關鍵字,表示繼承
class Student extends Person{
????// 構(gòu)造函數(shù)
????constructor(name, age, gender, no){
????????// 調(diào)用父類的構(gòu)造函數(shù)
????????super(name, age, gender)
????????// 學生特有的屬性
????????this.no = no
????}
????//學生學習的方法
????study() {
????????console.log(`我叫${this.name},我的學號是${this.no},我在學習...`);
????}
}
let s1 = new Student('張三', 20, '女', '1001')
console.log(s1);
s1.study()
s1.eat()
s1.say()
十六、項目
迷你DVD管理系統(tǒng)
完成:1.查看DVD 2.租售DVD 3.歸還DVD 4.添加DVD 5.刪除DVD 0.退出系統(tǒng)