今天好像是情人節(jié)?所以最適合面向?qū)ο笏埽琂avaScript 也有對象萍肆,我們也可以隨時(shí)面向?qū)ο螅奖愕煤苷陀欤窃鯓硬庞袑ο竽靥链В肯旅娓嬖V你!
1. 數(shù)組
數(shù)組宿崭,字面意思就是一堆數(shù)的組合亲铡,但是它是有順序的,學(xué)了數(shù)組就不僅可以存儲(chǔ)一個(gè)數(shù)據(jù)葡兑,還可以存儲(chǔ)一堆數(shù)據(jù)奖蔓,這就是我們?yōu)槭裁磳W(xué)了簡單數(shù)據(jù)類型之后還要學(xué)數(shù)組的原因。
1.1 聲明數(shù)組
可以看到讹堤,數(shù)組里面的定義和 python 里的差不多吆鹤,也可以存儲(chǔ)不同數(shù)據(jù)類型。獲取數(shù)組元素也是一樣通過下標(biāo)獲取洲守,下標(biāo)從 0 開始檀头,而且 JavaScript 的數(shù)組可以隨意根據(jù)下標(biāo)進(jìn)行賦值轰异,不管你的數(shù)組長度,因?yàn)?JavaScript 的數(shù)組長度是動(dòng)態(tài)的暑始。
1.2 遍歷數(shù)組
遍歷數(shù)組搭独,根據(jù)數(shù)組長度可以輕易知道循環(huán)次數(shù),所以可以使用 for 循環(huán)廊镜,獲取數(shù)組的長度可以通過 length 屬性進(jìn)行獲取牙肝。
這里有個(gè)提高效率的地方,就是在獲取數(shù)組的長度時(shí)放在了 for 語句的初始化表達(dá)式里嗤朴,而不是放在判斷表達(dá)式里配椭,當(dāng)你這個(gè)值需要運(yùn)算才能獲得的時(shí)候,這樣做就可以不用在每次判斷時(shí)都需要通過運(yùn)算獲得雹姊,減少運(yùn)算股缸,也就提高效率了,當(dāng)然吱雏,數(shù)組的長度在這里只是一個(gè)屬性敦姻,不需要運(yùn)算,放不放在初始化表達(dá)式都差不多歧杏。
1.3 清空數(shù)組
JavaScript 這里清空數(shù)組簡單粗暴镰惦,直接將**長度賦值為 0 **即可。
1.4 數(shù)組小練習(xí)
- 找出數(shù)組中最大的值
這個(gè)直接通過遍歷數(shù)組犬绒,然后將每個(gè)值進(jìn)行比較即可旺入,很容易。
- 翻轉(zhuǎn)數(shù)組
這個(gè)就是將數(shù)組中的元素前后互相替換凯力,也不多說了茵瘾。
2. 函數(shù)
當(dāng)我們需要在對多個(gè)數(shù)組進(jìn)行上面的其中練習(xí)之一,比如進(jìn)行尋找最大值咐鹤,我們總不能每個(gè)數(shù)組都各自寫一段尋找最大值的代碼龄捡,否則這樣子的話代碼的復(fù)用性太低了。
函數(shù)的出現(xiàn)就是解決這個(gè)問題的慷暂,函數(shù)就是把一段相對獨(dú)立的具有特定功能的代碼抽取出來進(jìn)行封裝聘殖,形成一個(gè)獨(dú)立的個(gè)體。當(dāng)需要多次使用的時(shí)候行瑞,我們只需要使用函數(shù)名調(diào)用即可奸腺。
2.1 函數(shù)的定義
函數(shù)定義這里有兩種方法,如下:
- 使用函數(shù)聲明血久,語法為
- 使用函數(shù)表達(dá)式突照,語法為:
上面只是函數(shù)的定義而已,并不會(huì)去執(zhí)行氧吐,只有你調(diào)用函數(shù)的時(shí)候才會(huì)去執(zhí)行讹蘑。
2.2 函數(shù)調(diào)用
調(diào)用函數(shù)的語法也比較簡單末盔,就是函數(shù)加上一個(gè)括號(hào)就行了。
所以當(dāng)需要多次使用這段功能的時(shí)候座慰,就多次調(diào)用即可陨舱,不需要每次都寫一段相同的代碼。
2.3 函數(shù)參數(shù)
不需要多次寫同一段代碼解決了版仔,但是當(dāng)有不同的數(shù)據(jù)內(nèi)容參與運(yùn)算時(shí)游盲,好像我還需要重復(fù)寫呀!就比如前面說的求數(shù)組最大值蛮粮。這個(gè)時(shí)候就需要我們的函數(shù)參數(shù)了益缎,函數(shù)參數(shù)就是解決這個(gè)不確定的數(shù)據(jù)內(nèi)容的。當(dāng)我們需要對不確定數(shù)據(jù)內(nèi)容進(jìn)行操作時(shí)然想,只需要在調(diào)用函數(shù)的時(shí)候把數(shù)據(jù)內(nèi)容當(dāng)作參數(shù)傳進(jìn)去即可莺奔。
函數(shù)的參數(shù)定義與調(diào)用語法:
形參:在聲明函數(shù)時(shí),有些值是固定的变泄,而有些值不是固定的令哟,對于這些不固定的值,我們可以給它們設(shè)置參數(shù)杖刷,但是這個(gè)參數(shù)不是具體的值,只是一個(gè)形式而已驳癌,所以叫做形參
實(shí)參:在函數(shù)聲明設(shè)置的形參滑燃,我們調(diào)用函數(shù)就需要傳入對應(yīng)的參數(shù),而這個(gè)參數(shù)就是實(shí)參颓鲜。
了解了這個(gè)之后表窘,是不是很容易就可以寫出一個(gè)求數(shù)組最大值的函數(shù)了?
咦甜滨?上面的我都看明白了乐严,但是 return 那個(gè)語句又是什么?return 后面跟的內(nèi)容就是函數(shù)的返回值衣摩,當(dāng)函數(shù)運(yùn)行到這里的時(shí)候就會(huì)結(jié)束函數(shù)并且把該值返回給調(diào)用處昂验,就相對于一段代碼執(zhí)行之后的反饋。所以 return 語句也會(huì)常常用于終止函數(shù)的運(yùn)行艾扮,還有也可以不寫 return 語句既琴,但是會(huì)默認(rèn)返回 undefined
2.4 函數(shù)內(nèi)部的 arguments 對象
JavaScript 中,函數(shù)的內(nèi)部都有一個(gè) arguments 對象泡嘴,用來記錄在調(diào)用函數(shù)時(shí)所傳進(jìn)來的參數(shù)甫恩,可以說是一個(gè)偽數(shù)組。
這個(gè)對象可以用于當(dāng)我們需要傳進(jìn)來的參數(shù)個(gè)數(shù)不確定時(shí)就可以使用這個(gè)酌予,就比如求一堆數(shù)的和磺箕。
2.5 匿名函數(shù)
匿名函數(shù)就是沒有名字的函數(shù)奖慌,當(dāng)我們只需要只需要調(diào)用一次的話就可以使用匿名函數(shù),或者需要回調(diào)函數(shù)的時(shí)候就會(huì)使用匿名函數(shù)松靡,至于什么是回調(diào)函數(shù)简僧,以后遇到了就說,匿名函數(shù)聲明如下:
這是將匿名函數(shù)賦值給一變量击困,然后可以通過該變量進(jìn)行調(diào)用涎劈,也可以傳參的,除了這樣子調(diào)用匿名函數(shù)阅茶,匿名函數(shù)還可以進(jìn)行自調(diào)用蛛枚。
這里需要注意的是在自調(diào)用的時(shí)候別忘了定義函數(shù)的部分需要加括號(hào)括起來。這自調(diào)用的匿名函數(shù)就常用于防止全局被污染脸哀,就是當(dāng)你寫的代碼量大了蹦浦,難免會(huì)有些全局變量會(huì)有重名的可能,這時(shí)候使用匿名函數(shù)自調(diào)用就可以新開辟了一個(gè)作用域撞蜂,不同作用域的變量就算同名也不怕了盲镶,至于具體的后面我也會(huì)應(yīng)用到,到時(shí)再詳講蝌诡。
2.6 函數(shù)其他
- 函數(shù)也是一種數(shù)據(jù)類型溉贿,可以說是一個(gè)對象吧,至于具體的后面再詳講浦旱,現(xiàn)在了解就好宇色。
- 函數(shù)不僅可以作為參數(shù)進(jìn)行傳遞,還可以作為返回值颁湖,畢竟函數(shù)也是一種數(shù)據(jù)類型宣蠕。作為參數(shù)傳遞主要就是我們所說的回調(diào)函數(shù),遇到就會(huì)說甥捺,作為返回值的應(yīng)用抢蚀,閉包就是一個(gè)應(yīng)用,也不多說镰禾,以后會(huì)講皿曲。
2.7. 作用域
作用域就是變量可以起作用的范圍,在 JavaScript 中定義的變量符合詞法作用域吴侦,就是說變量的作用域是在定義時(shí)決定的谷饿,不是在執(zhí)行時(shí)決定的,即變量作用域只需要通過源碼分析就知道了妈倔。
1. JavaScript 中 詞法作用域的規(guī)則為:
函數(shù)內(nèi)部的變量允許訪問函數(shù)外部的博投。
整個(gè)代碼結(jié)構(gòu)只能函數(shù)限定作用域,這就是為什么上文說使用自調(diào)用函數(shù)來開辟新的作用域的原因了盯蝴。
作用域規(guī)則首先使用提升規(guī)則分析毅哗,下文說的預(yù)解析就是這個(gè)
如果當(dāng)前作用域有該變量了缠黍,就不會(huì)考慮外面的了涩盾。
2. 下面再看看 JavaScript 中三種作用域
全局作用域:JavaScript 中認(rèn)為在函數(shù)外部定義的變量就是全局變量邓梅,而這個(gè)全局變量所在的作用域就是全局作用域蚀之。
局部作用域:在函數(shù)內(nèi)部就是局部作用域,在這里定義的內(nèi)部變量也就是局部變量翅睛。
塊級作用域:這個(gè)是 ES6 才有的声搁,簡單說下,就是只使用一對大括號(hào){} 括起來的就是塊級作用域捕发。
3. 作用域鏈
只有函數(shù)才可以限定作用域疏旨,那么在要有代碼,這里就至少存在一個(gè)全局作用域扎酷,而寫代碼難免又會(huì)有函數(shù)檐涝,這里的函數(shù)就會(huì)構(gòu)成另一個(gè)作用域,如果函數(shù)中還有函數(shù)法挨,則他還會(huì)構(gòu)成一個(gè)新的作用域谁榜,等等。將上面的這些作用域列出來凡纳,就會(huì)形成一個(gè)結(jié)構(gòu)窃植,這個(gè)結(jié)構(gòu)就是作用域鏈。如下面代碼:
按照全局作用域就是 0 級鏈荐糜,函數(shù)就是 1 級鏈巷怜,函數(shù)的函數(shù)就是 2級鏈,就會(huì)有下圖:
2.8 預(yù)解析
JavaScript 的解釋器在執(zhí)行代碼的時(shí)候有兩個(gè)過程狞尔,就是預(yù)解析和再從上往下執(zhí)行代碼過程丛版。預(yù)解析就是先把代碼中的變量提升巩掺,然后函數(shù)提升偏序,接著再執(zhí)行代碼。
變量提升:變量的聲明會(huì)被提升到作用域的最上面胖替,注不會(huì)將賦值提升研儒。
函數(shù)提升:把當(dāng)前作用域的函數(shù)聲明提升到當(dāng)前作用域的最上面。
如果你懂了再看看下面幾段代碼會(huì)不會(huì)報(bào)錯(cuò)独令?
解答:不會(huì)報(bào)錯(cuò)端朵,因?yàn)榻?jīng)過預(yù)解析后代碼成這樣
解答:也不會(huì)報(bào)錯(cuò),不過 a 打印的值為 undefined
解答:會(huì)報(bào)錯(cuò)燃箭,原因可以結(jié)合上下兩張圖看即可冲呢。
3. 對象 object
對象是一個(gè)具體的事物,比如你和我都是對象招狸,但是汽車和手機(jī)不是事物敬拓,可以說它們是一個(gè)類別邻薯。
JavaScript 中的對象可以說是一個(gè)無序的屬性的集合,屬性可以包括基本值乘凸、對象或函數(shù)厕诡,也可以把 JavaScript 中的對象想像為一組鍵值對。
把現(xiàn)實(shí)中的事物抽象為代碼中的對象营勤,其的特征可以作為對象的屬性灵嫌,其的行為可以作為方法。
3.1 創(chuàng)建對象
JavaScript 中創(chuàng)建對象的方法有四種葛作,并不像其他語言中只能通過 new 來創(chuàng)建寿羞。
- 直接聲明一個(gè)鍵值對的集合
這個(gè) obj 變量就是一個(gè)對象了里面有兩個(gè)屬性和一個(gè)方法。使用這種方法也只適合創(chuàng)建一個(gè)類进鸠,因?yàn)楫?dāng)需要?jiǎng)?chuàng)建大量同類型的對象時(shí)稠曼,使用這個(gè)方法就需要寫大量的方法。
- 使用 new Object() 創(chuàng)建
這個(gè)是先創(chuàng)建一個(gè)空對象客年,然后動(dòng)態(tài)增加對象的屬性和方法霞幅,也是只適合創(chuàng)建只有一個(gè)對象的類型,還不如第一種量瓜,也不推薦司恳。
- 使用工廠模式創(chuàng)建
這種方法就是使用一個(gè)模板函數(shù),就相當(dāng)于一個(gè)工廠绍傲,還有記得返回創(chuàng)建的對象扔傅。當(dāng)需要?jiǎng)?chuàng)建對象的時(shí)候只需要調(diào)用一下函數(shù)傳參就可以了,就比上面兩種代碼的復(fù)用性提高了烫饼。
但是這有一個(gè)問題猎塞,我們在判斷對象類型的時(shí)候,結(jié)果都是 Object
判斷對象類型使用 instanceof杠纵,而使用 typeof 判斷對象荠耽,無論什么對象的結(jié)果都是 Object
- 自定義構(gòu)造函數(shù)來創(chuàng)建
這個(gè)自定義構(gòu)造函數(shù)名字需要首字母大寫,當(dāng)然這只是個(gè)規(guī)范而已比藻。
里面使用了 this 關(guān)鍵字铝量,這個(gè) this 的指向就是使用構(gòu)造函數(shù)創(chuàng)建的對象,也不需要返回 對象了银亲。
注意:創(chuàng)建對象也需要使用 new 關(guān)鍵字慢叨,如上圖,通過這種方法就既可以創(chuàng)建大量同類型的對象务蝠,也可以判斷所屬類型拍谐,非常方便。
這個(gè) new 創(chuàng)建對象的過程為:
在內(nèi)存中先創(chuàng)建一個(gè)空的對象
讓構(gòu)造函數(shù)的 this 指向剛剛創(chuàng)建的對象
執(zhí)行構(gòu)造函數(shù)內(nèi)部的屬性和方法定義
返回當(dāng)前對象
3.2 對象屬性和方法的相關(guān)操作
- 訪問屬性語法為對象.屬性,還可以 對象['屬性名'] 這樣轩拨, 當(dāng)然也可以通過這兩個(gè)來修改對象屬性的值
當(dāng)然力穗,當(dāng)對一個(gè)不存在的屬性訪問的時(shí)候就會(huì)返回 undefined,若是修改一個(gè)不存在的屬性就是向該對象動(dòng)態(tài)增加一個(gè)新的屬性气嫁。
這兩種方法推薦第二種当窗,因?yàn)橛袝r(shí)我們得到的屬性是一個(gè)變量名,并不知道具體的名字寸宵,這時(shí)候就只能使用第二種方法
- 訪問方法直接使用 對象.函數(shù)名() 即可
- 遍歷對象成員
可以使用 for...in... 語句
- 刪除對象成員
使用 delete 關(guān)鍵字
3.3 簡單數(shù)據(jù)類型和復(fù)雜數(shù)據(jù)類型的區(qū)別
基本類型又叫做值類型崖面,復(fù)雜類型又叫做引用類型
值類型:簡單數(shù)據(jù)類型,基本數(shù)據(jù)類型梯影,在存儲(chǔ)時(shí)巫员,變量中存儲(chǔ)的是值本身,因此叫做值類型甲棍。
引用類型:復(fù)雜數(shù)據(jù)類型简识,在存儲(chǔ)時(shí),變量中存儲(chǔ)的僅僅是地址(引用)感猛,因此叫做引用數(shù)據(jù)類型七扰。
終于寫完了,下一篇常用內(nèi)置對象走起陪白。