?
[if !supportLists]第一章 [endif]基本語法
[if !supportLists]一预皇、[endif]JavaScript組成
JavaScript是一種基于對(duì)象和事件驅(qū)動(dòng)編程語言咨跌。一個(gè)完整的JavaScript應(yīng)該由三個(gè)不同的部分組成:
核心(ECMAScript)齐唆,提供核心語言功能瀏覽器對(duì)象模型(BOM),提供與瀏覽器交互的方法和接口文檔對(duì)象模型(DOM)辖佣,提供訪問和操作網(wǎng)頁內(nèi)容的方法和接口
[if !supportLists]1.[endif]核心(ECMAScript)
ECMAScript是一種語法標(biāo)準(zhǔn),提供核心語言功能
ECMAScript與Web瀏覽器沒有依賴關(guān)系嘿歌。ECMA定義的只是這門語言的基礎(chǔ),而在此基礎(chǔ)之上可以構(gòu)建更完善的腳本語言哪雕。我們常見的Web瀏覽器只是ECMAScript實(shí)現(xiàn)可能的宿主環(huán)境之一钾麸。宿主環(huán)境不僅提供基本的ECMAScript實(shí)現(xiàn),同時(shí)也會(huì)提供該語言的擴(kuò)展,以便語言與環(huán)境之間對(duì)接交互更振。而這些擴(kuò)展——如DOM,則利用ECMAScript的核心類型和語法提供更多更具體的功能,以便實(shí)現(xiàn)針對(duì)環(huán)境的操作。其他宿主環(huán)境包括Node(一種服務(wù)器端JavaScript平臺(tái))
ECMAScript規(guī)定了這門語言的下列組成部分:語法饭尝、變量和數(shù)據(jù)類型肯腕、運(yùn)算符、邏輯控制語句钥平、關(guān)鍵字实撒、保留字、對(duì)象
[if !supportLists]2.[endif]瀏覽器對(duì)象模型(BOM)
BOM:Browser Object Model(瀏覽器對(duì)象模型)提供與瀏覽器交互的方法和接口
[if !supportLists]3.[endif]文檔對(duì)象模型(DOM)
DOM:Document Object Model(文檔對(duì)象模型)提供訪問和操作網(wǎng)頁內(nèi)容的方法和接口
[if !supportLists]二涉瘾、[endif]在Web網(wǎng)頁里添加JavaScript
[if !supportLists]1.[endif]方法一
把js語句寫在<script></script>里面奈惑,
<script>
...javscript語句...
</script>
元素沒有任何必須設(shè)置的屬性(在HTML5里,type屬性是可選的)睡汹。如果在HTML4.x或XHTML頁面里添加JavaScript,就需要使用type屬性了寂殉。
[if !supportLists]2.[endif]方法二
把JavaScript代碼保存到單獨(dú)的文件(后綴是.js)囚巴,然后利用<script>標(biāo)簽的src(源)屬性把這個(gè)文件包含到頁面里
<script src="mycode.js"></script>
注意:外部文件里面不能使用標(biāo)簽,也不能使用任何HTML標(biāo)簽,只能是純粹的JavaScript代碼彤叉。
[if !supportLists]第二章 [endif]詞法結(jié)構(gòu)
詞法結(jié)構(gòu)就是一套基礎(chǔ)性規(guī)則庶柿,用來描述如何使用這門語言來編寫程序
[if !supportLists]一、[endif]變量
ECMAScript的變量是松散類型的秽浇,所謂松散類型就是可以用來保存任何類型的數(shù)據(jù)浮庐。換句話說,每個(gè)變量僅僅是一個(gè)用于保存值的占位符而已柬焕。定義變量時(shí)要使用var操作符(注意var是一個(gè)關(guān)鍵字)审残,后跟變量名(即一個(gè)標(biāo)識(shí)符),如下所示:var message;
[if !supportLists]1.[endif]什么是變量
變量是一個(gè)值的符號(hào)名稱斑举,可以通過名稱來獲得對(duì)值的引用搅轿。變量就是值的引用。
[if !supportLists]2.[endif]為什么要使用變量
值太長富玷,每次書寫不方便璧坟;將值保存起來以備將來使用,也方便以后多次使用
[if !supportLists]3.[endif]如何聲明變量
應(yīng)當(dāng)先聲明變量赎懦,再使用變量雀鹃;變量是使用關(guān)鍵字var或let來聲明的,后跟變量名(即一個(gè)標(biāo)識(shí)符)可以一次聲明多個(gè)變量励两,用逗號(hào)隔開黎茎;可以在聲明變量的同時(shí)給變量賦值
var message = "hi",
????found = false,
????age = 29;
這個(gè)例子定義并初始化了3個(gè)變量。同樣由于ECMAScript是松散類型的伐蒋,因而使用不同類型初始化變量的操作可以放在一條語句中來完成工三。雖然代碼里的換行和變量縮進(jìn)不是必需的,但這樣做可以提高可讀性先鱼。
在嚴(yán)格模式下俭正,不能定義名為eval或者arguments的變量,否則會(huì)導(dǎo)致語法錯(cuò)誤焙畔。
可以在修改變量的同時(shí)修改值的類型,如下所示:
var message = "h1";message = 100; //有效掸读,但不推薦
在這個(gè)例子,變量message一開始保存了字符串值”h1”, 然后該值又被一個(gè)數(shù)字值100取代宏多。雖然不建議修改變量所保存值的類型儿惫,但這種操作在ECMAScript中完全有效。
JS中的變量可以用來保存任何類型的數(shù)據(jù)伸但,變量的數(shù)據(jù)類型由其存儲(chǔ)的值的類型決定肾请;使用變量名等效于直接使用變量中存儲(chǔ)的數(shù)據(jù)
注意
使用var或let聲明了變量,但是沒有給變量指定初始值更胖,它的初始值就是undefined給一個(gè)未聲明的變量賦值是一個(gè)不好的習(xí)慣铛铁,在嚴(yán)格模式下也會(huì)導(dǎo)致拋出ReferenceError錯(cuò)誤隔显。因此,應(yīng)當(dāng)始終使用var或let來聲明變量使用既沒有聲明也沒有賦值的變量饵逐,會(huì)報(bào)錯(cuò)
[if !supportLists]4.[endif]var括眠,let和const區(qū)別
var會(huì)變量提升;let不會(huì)變量提升倍权,var支持重復(fù)聲明掷豺;let 不支持重復(fù)聲明(聲明變量之后就不能再次聲明它。雖然可以給變量重新賦值薄声,但不能重新聲明變量当船,否則將導(dǎo)致編譯階段錯(cuò)誤。)var沒有塊級(jí)作用域奸柬;let有塊級(jí)作用域(if 生年,for循環(huán),do...while的花括號(hào))var兼容IE7廓奕,let兼容IE11
[if !supportLists]二抱婉、[endif]常量
使用const關(guān)鍵字聲明的是常量,
特性同let:不支持預(yù)解析桌粉,也就是不支持聲明提前蒸绩;不支持重復(fù)聲明
區(qū)別是一旦聲明,常量的值就不可以改變每個(gè)通過const聲明的常量必須進(jìn)行初始化铃肯,也就是必須賦值患亿,否則會(huì)拋出語法錯(cuò)誤
[if !supportLists]三、[endif]區(qū)分大小寫
ECMAScript中的一切(變量押逼、函數(shù)名和操作符)都區(qū)分大小步藕。這就是說, 變量名test和變量名Test分別表示兩個(gè)不同的變量,而函數(shù)名不能使用typeof, 因?yàn)樗且粋€(gè)關(guān)鍵字, 但typeOf則完全可以是一個(gè)有效的函數(shù)名
[if !supportLists]四挑格、[endif]標(biāo)識(shí)符
標(biāo)識(shí)符就是指變量咙冗、函數(shù),屬性的名字漂彤,或者函數(shù)的參數(shù)
標(biāo)識(shí)符可以按照下列格式規(guī)則組合起來的一或者多個(gè)字符由字母雾消、下劃線、美元符號(hào)和數(shù)字組成挫望,且首字符不能是數(shù)字不能把關(guān)鍵字立润,保留字、true媳板、false和null桑腮,以及預(yù)定義的全局變量和函數(shù)作為標(biāo)識(shí)符
為了與ECMAScript內(nèi)置的函數(shù)和對(duì)象命名格式保持一致,推薦使用駝峰式命名法:第一個(gè)字母小寫蛉幸,剩下的每個(gè)單詞的首字母大寫破讨,如:firstSecond , myCar , doSomethingImport
[if !supportLists]五旨巷、[endif]關(guān)鍵字和保留字
ECMAScript描述了一組具有特定用途的關(guān)鍵字, 這些關(guān)鍵字可用于表示控制語句的開始或者結(jié)束, 或者用于執(zhí)行特定操作等。按照規(guī)則, 關(guān)鍵字也是語言保留的, 不能用作標(biāo)識(shí)符添忘。
ECMAScript還描述了另外一組不能用作標(biāo)識(shí)符的保留字。盡管保留字在這門語言中還沒有任何特定的用途, 但它們有可能將來被用作關(guān)鍵字
[if !supportLists]六若锁、[endif]語句
ECMAScript中的語句以一個(gè)分號(hào)結(jié)尾搁骑;如果省略分號(hào),則由解析器確定語句的結(jié)尾
<script>???var sum = a + b //即使沒有分號(hào)也是有效的語句---不推薦???var diff = a - b; // 有效的語句---推薦</script>
JS使用分號(hào)將語句分隔開又固;為了方便閱讀仲器,我們建議每條JavaScript的每條語句獨(dú)占一行,且都加上分號(hào)
雖然語句結(jié)尾的分號(hào)不是必需的仰冠,但建議任何時(shí)候都不要省略它乏冀。加上這個(gè)分號(hào)可以避免很多錯(cuò)誤,開發(fā)人員也可以放心地通過刪除多余的空格來壓縮JS代碼。另外洋只,加上分號(hào)也會(huì)在某些情況下增進(jìn)代碼的性能, 因?yàn)檫@樣解析器就不必再花時(shí)間推測(cè)應(yīng)該在哪里插入分號(hào)了
可以使用C風(fēng)格的語法把多條語句組合到一個(gè)代碼中, 即代碼塊以左花括號(hào)({)開頭, 以右花括號(hào)(})結(jié)尾:
<script>???if (test) {??????test = false;??????alert(test);???}</script>
雖然條件控制語句(如if語句)只在執(zhí)行多條語句的情況下才要求使用代碼塊, 但最佳實(shí)踐是始終在控制語句中使用代碼塊——即使代碼中只用一條語句, 例如:
if (test)
alert(test); //有效但容易出錯(cuò), 不要使用
if (test) { alert(test); //推薦使用}
在控制語句中使用代碼塊可以讓編碼意圖更加清晰,而且也能降低修改時(shí)出錯(cuò)的幾率辆沦。
[if !supportLists]七、[endif]注釋
有些語句的作用并不是為了讓瀏覽器執(zhí)行识虚,而是為了方便需要閱讀代碼的人肢扯。我們把這些語句稱為“注釋”
寫在注釋里面的內(nèi)容,JavaScript的解釋器不會(huì)去執(zhí)行
[if !supportLists]1.[endif]單行注釋
以兩個(gè)斜杠開頭,如下所示//單行注釋
[if !supportLists]2.[endif]塊級(jí)注釋
以一個(gè)斜杠和一個(gè)星號(hào)(/*)開頭, 以一個(gè)星號(hào)和一個(gè)斜杠(*/)結(jié)尾, 不能嵌套担锤。
/*
? *這是一個(gè)多行 * (塊級(jí))注釋
?*/
雖然上面注釋中的第二和第三行都以一個(gè)星號(hào)開頭,但這不是必需的蔚晨。之所以添加那兩個(gè)星號(hào), 純粹是為了提高注釋的可讀性。
注釋的確會(huì)略微增加JavaScript源文件的大小肛循,從而對(duì)頁面加載時(shí)間產(chǎn)生不好的影響铭腕。一般來說,這種影響小到可以忽略不計(jì)多糠,但如果的確需要消除這種影響累舷,我們可以清除JavaScript文件里的全部注釋,形成所謂的“運(yùn)行”版本熬丧,用于實(shí)際的站點(diǎn)笋粟。
[if !supportLists]八、[endif]嚴(yán)格模式
ECMASript5引入嚴(yán)格模式(strict mode)的概念析蝴。嚴(yán)格模式是為JavaScript定義了一種不同的解析與執(zhí)行模型害捕。在嚴(yán)格模式下,ECMAScript3中的一些不確定的行為將得到處理闷畸,而且對(duì)某些不安全的操作也會(huì)報(bào)錯(cuò)尝盼。要在整個(gè)腳本中啟動(dòng)嚴(yán)格模式,可以在頂部添加如下代碼:
"use strict";
這行代碼看起來像是字符串佑菩,而且也沒有賦值給任何變量盾沫,但其實(shí)它是一個(gè)編譯指示(pragma)裁赠,用于告訴支持的JavaScript引擎切換到嚴(yán)格模式。這是為不破壞ECMAScript 3 語法而特意選定的語法赴精。
在函數(shù)內(nèi)部的上方包含這條編譯指示佩捞,也可以指定函數(shù)在嚴(yán)格模式下執(zhí)行:
function doSomething () {
??"use strict";
//函數(shù)體
}
嚴(yán)格模式下,JavaScript的執(zhí)行結(jié)果會(huì)有很大不同蕾哟,支持嚴(yán)格模式的瀏覽器包括IE10+一忱、Firefox4+、Safari5.1+谭确、Opera12+和chrome帘营。
[if !supportLists]第三章 [endif]數(shù)據(jù)類型
[if !supportLists]一、[endif]什么是數(shù)據(jù)類型
計(jì)算機(jī)的運(yùn)行需要對(duì)各種各樣的值進(jìn)行操作逐哈,比如數(shù)字3.14或文本“大家好”芬迄。在編程語言中,這些值的類型稱為數(shù)據(jù)類型昂秃。
[if !supportLists]二禀梳、[endif]JS有哪幾種數(shù)據(jù)類型
JS的數(shù)據(jù)類型分為兩類:原始類型(基本數(shù)據(jù)類型,簡(jiǎn)單數(shù)據(jù)類型)和對(duì)象類型 (引用數(shù)據(jù)類型械蹋,復(fù)雜數(shù)據(jù)類型)
[if !supportLists]1.[endif]原始類型
數(shù)字(Number)字符串(String)布爾值(Boolean)空(Null)未定義(Undefined )
[if !supportLists]2.[endif]對(duì)象類型
除了5種原始數(shù)據(jù)類型之外的都是對(duì)象(Object),對(duì)象是屬性的集合出皇,Object本質(zhì)是由一組無序的鍵值對(duì)組成的
ECMAScript不支持任何創(chuàng)建自定義類型的機(jī)制,而所有值最終都將是上述6種數(shù)據(jù)類型之一
[if !supportLists]三哗戈、[endif]使用typeof操作符檢測(cè)數(shù)據(jù)類型
使用typeof操作符檢測(cè)數(shù)據(jù)的類型郊艘,可能返回下列某個(gè)字符串:
"undefined"——值未定義;"boolean"——布爾值;"string"——字符串;"number"——數(shù)字;"object"——對(duì)象或者null;"function"——函數(shù)
調(diào)用typeof null會(huì)返回"object",因?yàn)樘厥庵祅ull被認(rèn)為是一個(gè)空的對(duì)象引用。
函數(shù)在ECMAScript中是對(duì)象, 不是一種數(shù)據(jù)類型唯咬。但是因?yàn)楹瘮?shù)有一些特殊的屬性纱注,所以通過typeof操作符來檢測(cè)函數(shù)會(huì)返回function 而不是 object
[if !supportLists]四、[endif]Undefined類型
Undefined類型只有一個(gè)值胆胰,即undefined
聲明了一個(gè)變量但沒有給它賦值狞贱,這個(gè)變量的默認(rèn)值就是undefined
????<script>
????????var message;
????????alert(message); // "undefined"
????</script>
既沒有聲明又沒有賦值的變量,會(huì)導(dǎo)致一個(gè)錯(cuò)誤蜀涨。此時(shí)只能執(zhí)行一項(xiàng)操作瞎嬉,即使用typeof操作符檢測(cè)其數(shù)據(jù)類型
????<script>
alert(age); //報(bào)錯(cuò):age is not defined
</script>
沒有聲明但是賦值了是有效的,但是不推薦這么做厚柳。建議加上var聲明
????<script>
num = 100; //有效但是不推薦
????????alert(num)
</script>
[if !supportLists]五氧枣、[endif]Null類型
Null類型只有一個(gè)值即null。
當(dāng)我們想讓變量具有有效值别垮,卻又不是任何具體值時(shí)便监,就把null賦給變量。
從邏輯角度來看,null值表示一個(gè)空對(duì)象指針烧董,而這也正是使用typeof操作符檢測(cè)null值時(shí)會(huì)返回"object"的原因毁靶。如果定義的變量準(zhǔn)備在將來用于保存對(duì)象,那么最好將該變量初始化為null而不是其他值逊移。這樣一來预吆,只要直接檢查null值就可以知道相應(yīng)的變量是否已經(jīng)保存了一個(gè)對(duì)象的引用,
如下面的例子所示:
????<script>
????????if (car != null) {
//對(duì)car對(duì)象執(zhí)行某些操作
????????}
????</script>
實(shí)際上, undefined值是派生自null值胳泉,因此ECMA-262規(guī)定對(duì)它們的相等性測(cè)試要返回true
????<script>
????????alert(null == undefined); // true
????</script>
盡管null和undefined有這樣的關(guān)系啡浊,但它們的用途完全不同。如前所屬胶背,無論什么情況下都沒有必要把一個(gè)變量的值顯式地設(shè)置為undefined,可是同樣的規(guī)則對(duì)null卻不適用。換句話說喘先,只要意在保存對(duì)象的變量還沒有真正保存對(duì)象钳吟,就應(yīng)該明確地讓該變量保存null值。這樣做不僅可以體現(xiàn)null作為空對(duì)象指針的慣例窘拯,而且也有助于進(jìn)一步區(qū)分null和undefined红且。
[if !supportLists]六、[endif]Boolean類型
boolean類型只有兩個(gè)值: true和false涤姊,注意必須小寫這兩個(gè)值與數(shù)字值不是一回事暇番,因此true不一定等于 1,而 false也不一定等于 0
[if !supportLists]七思喊、[endif]數(shù)字類型
數(shù)字類型包含整型和浮點(diǎn)型:
[if !supportLists]1.[endif]整型
十進(jìn)制整數(shù)壁酬,如正整數(shù)、負(fù)整數(shù)和0八進(jìn)制(以0開頭)恨课,如0123(嚴(yán)格模式下無效舆乔,不推薦使用)十六進(jìn)制(以0x或0X開頭),如0x8a, 0xab0080在進(jìn)行算術(shù)運(yùn)算時(shí)剂公,所有八進(jìn)制和十六進(jìn)制表示的數(shù)值最終都將被轉(zhuǎn)換成十進(jìn)制數(shù)值
[if !supportLists]2.[endif]浮點(diǎn)型
浮點(diǎn)數(shù)表示小數(shù)點(diǎn)前后可以有任意位希俩,好像小數(shù)點(diǎn)可以浮動(dòng)到任何數(shù)字的任何位置一樣。
就是該數(shù)值中必須包含一個(gè)小數(shù)點(diǎn)纲辽,且小數(shù)點(diǎn)后面必須至少有一個(gè)數(shù)字颜武。小數(shù)部分可以為0浮點(diǎn)數(shù)的表示形式可以是傳統(tǒng)方式,比如3.14159拖吼,也可以是指數(shù)形式鳞上,如35.4e5
在指數(shù)表示方法中,e表示“10的冪”绿贞,所以35.4e5表示:35.4乘以10的5次冪因块。利用指數(shù)表示法,可以方便地表示特別大或特別小的數(shù)值籍铁。
下面都是有效的浮點(diǎn)數(shù):3.0涡上, 0.00001趾断, -99.99, 2.5e12 , 1e-12
浮點(diǎn)數(shù)值的最高精度是17位小數(shù)吩愧,由于這個(gè)因素芋酌,程序中有時(shí)不能準(zhǔn)確處理浮點(diǎn)數(shù)運(yùn)算。如2-1.1=0.8999999999999999修正:toFixed(num)將數(shù)字保留小數(shù)點(diǎn)后num位且四舍五入雁佳,并轉(zhuǎn)化為字符串
<script>????var jg=2-1.1;????console.log(jg.toFixed(2))</script>
[if !supportLists]3.[endif]NaN
NaN表示非數(shù)值脐帝,not a number 不是個(gè)數(shù)字
當(dāng)腳本嘗試把一些非數(shù)字當(dāng)做數(shù)字進(jìn)行處理,卻無法得到數(shù)字時(shí)糖权,其返回值就是NaN堵腹。比如拿一個(gè)整數(shù)乘以一個(gè)字符串,結(jié)果就是NaN
NaN和任何數(shù)據(jù)比較星澳,永遠(yuǎn)返回false 任何與NaN進(jìn)行運(yùn)算的結(jié)果均為NaNNaN不與任何值相等疚顷,包括自身它屬于Number類型
一旦程序中出現(xiàn):NaN,肯定進(jìn)行了非法的運(yùn)算操作,如:alert('200px'-100);
[if !supportLists]4.[endif]isNaN
利用isNaN()函數(shù)能夠檢測(cè)其參數(shù)是否為一個(gè)“數(shù)字”禁偎,是數(shù)字返回false(不喜歡數(shù)字)腿堤,非數(shù)字返回為true
alert(isNaN(100)); ?falsealert(isNaN('你好')); truealert(isNaN('200'));內(nèi)部運(yùn)行規(guī)律:先用Number去轉(zhuǎn)
<script>????//用戶輸入數(shù)字????var num = prompt("請(qǐng)輸入一個(gè)數(shù)字:");????if(isNaN(num)){????????document.write("您輸入的不是數(shù)字,請(qǐng)確認(rèn)如暖!");????}else{????????document.write("您輸入的數(shù)字是:"+num);????}</script>
[if !supportLists]八笆檀、[endif]字符串類型
定義:字符串由零個(gè)或多個(gè)字符構(gòu)成。字符包括(但不限于)字母盒至、數(shù)字酗洒、標(biāo)點(diǎn)符號(hào)和空格。字符串必須包含在引號(hào)里枷遂,單引號(hào)或雙引號(hào)都可以寝蹈。如果字符串包含雙引號(hào),就把整個(gè)字符串放在單引號(hào)里如果字符串包含單引號(hào)登淘,就把整個(gè)字符串放在雙引號(hào)里箫老。
如果字符串中包含包含與語法沖突的特殊字符,可以使用轉(zhuǎn)義字符console.log('\t大家好黔州,\n歡迎學(xué)習(xí)\'JavaScript!\'');
[if !supportLists]1.[endif]模板字符串
放在反引號(hào)里面耍鬓,可以當(dāng)作普通字符串使用;可以用來定義多行字符串流妻;可以解析變量(把變量放在${}里面
[if !supportLists]九牲蜀、[endif]數(shù)據(jù)類型轉(zhuǎn)換
[if !supportLists]1.[endif]轉(zhuǎn)換為布爾值
ECMAScript中所有類型的值都有與這兩個(gè)Boolean值等價(jià)的值∩鹫猓可以對(duì)任何數(shù)據(jù)類型的值調(diào)用Boolean()函數(shù)涣达,而且總會(huì)返回一個(gè)Boolean值。至于返回的這個(gè)值是true還是false,取決于要轉(zhuǎn)換值的數(shù)據(jù)類型及其實(shí)際值度苔。參見對(duì)應(yīng)的轉(zhuǎn)換規(guī)則圖
????<script>
????????var message = "Hello world!";
????????var messageAsBoolean = Boolean(message);
</script>
這些轉(zhuǎn)換規(guī)則對(duì)理解流控制語句(如if語句)自動(dòng)執(zhí)行相應(yīng)的Boolean轉(zhuǎn)換非常重要匆篓,請(qǐng)看下面的代碼:
????<script>
????????var message = "Hello world!";
????????if (message) {
????????????alert("Value is true");
????????}
????</script>
因?yàn)樽址甿essage被自動(dòng)轉(zhuǎn)換成了對(duì)應(yīng)的Boolean值(true)
[if !supportLists]2.[endif]轉(zhuǎn)換為數(shù)字類型
把其他類型數(shù)據(jù)轉(zhuǎn)換為數(shù)字類型,主要有Number方法寇窑,parseInt()和parseFloat() 方法
Number()方法:可以用于任何數(shù)據(jù)钠糊,如果包含非法字符古胆,則返回NaN
JS提供了兩個(gè)可以把字符串強(qiáng)制轉(zhuǎn)換為數(shù)值格式的函數(shù)改鲫。
parseFloat()函數(shù)解析字符串并返回一個(gè)浮點(diǎn)數(shù)肮街。用法與parseInt完全相同,唯一區(qū)別:認(rèn)識(shí)第一個(gè)小數(shù)點(diǎn)(開頭是+饮笛,-咨察,空格時(shí),可以轉(zhuǎn))
<script>????console.log(parseFloat("21.4")); // 返回21.4????console.log(parseFloat("76 trombones")); // 返回76????console.log(parseFloat("The magnificent 7")); // 返回NaN</script>
parseInt()函數(shù)解析字符串并返回整數(shù)或NaN福青。它還可以有第二個(gè)可選參數(shù)扎拣,用于指定數(shù)值的基,從而返回二進(jìn)制素跺、八進(jìn)制或其他進(jìn)制數(shù)值所對(duì)應(yīng)的十進(jìn)制數(shù)值。從左到右一個(gè)一個(gè)轉(zhuǎn)換誉券,遇到不是數(shù)字的字符(包括小數(shù)點(diǎn))就停止轉(zhuǎn)換(開頭是+指厌,-,空格時(shí)踊跟,可以轉(zhuǎn))踩验。不能轉(zhuǎn),則返回NaN
<script>????console.log(parseInt("18.95, 10")); // 返回18????console.log(parseInt("12px", 10)); // 返回12????console.log(parseInt("1110", 2)); // 返回14????console.log(parseInt("Hello")); // 返回NaN</script>
使用parseInt()方法把以下數(shù)據(jù)轉(zhuǎn)為數(shù)字類型:'100px'; ??'100px125633'; ???'+100'; ?22.5商玫, ?空字符串
一般情況下parseInt和parseFloat都是用來去轉(zhuǎn)字符串箕憾,不要用它們?nèi)マD(zhuǎn)換函數(shù),布爾值等等拳昌,轉(zhuǎn)不了的袭异,因?yàn)樗麄儌z是從左到右一個(gè)一個(gè)轉(zhuǎn)
[if !supportLists]3.[endif]轉(zhuǎn)換為字符串
String()任何的數(shù)據(jù)類型都能轉(zhuǎn)(全局函數(shù),屬于window對(duì)象的方法炬藤,相當(dāng)于window.String() )toString()不能轉(zhuǎn)null和undefined類型御铃,其他類型都能轉(zhuǎn)(屬于字符串的方法,必須str.toString() )
[if !supportLists]第四章 [endif]運(yùn)算符
[if !supportLists]一沈矿、[endif]算術(shù)運(yùn)算符
+加上真、- 減、* 乘羹膳、/ 除睡互、% 取模(求余數(shù))
[if !supportLists]1.[endif]加(+)
用來做加法運(yùn)算
alert(100+200);結(jié)果:300alert(100+'200'); 結(jié)果:100200alert(10+5+'abc')結(jié)果:15abc
用來連接字符串:字符串和任何類型的數(shù)據(jù)相連接,最終都是字符串
數(shù)字+字符串:100+’100’ 5+5+'hello' ??'hello'+5+5 ???234 +‘ok’ + 111+ 222就珠,NaN+字符串null+字符串寇壳,undefined+字符串,布爾值+字符串嗓违,數(shù)組+字符串九巡,對(duì)象+字符串,函數(shù)+字符串
[if !supportLists]2.[endif]減(-)
用來做減法運(yùn)算數(shù)字和字符串相減,會(huì)把字符串自動(dòng)變成數(shù)字進(jìn)行運(yùn)算
alert(200-100);結(jié)果:100alert(200-'100');結(jié)果:100
[if !supportLists]3.[endif]乘(*)
用來數(shù)學(xué)乘法運(yùn)算蹂季。數(shù)字和字符串相乘冕广,會(huì)把字符串自動(dòng)變成數(shù)字進(jìn)行運(yùn)算
alert(3*7);結(jié)果:21alert(3*'7');結(jié)果:21
[if !supportLists]4.[endif]除(/)
用來數(shù)學(xué)除法運(yùn)算。數(shù)字和字符串相除偿洁,會(huì)把字符串自動(dòng)變成數(shù)字進(jìn)行運(yùn)算撒汉,如果除數(shù)為0,結(jié)果為Infinity 無窮大涕滋;Infinity 為數(shù)字類型
alert(81/9);結(jié)果:9alert('81'/9);結(jié)果:9alert(5/0);結(jié)果:Infinity0/0為 NaN
[if !supportLists]5.[endif]求余(%)
模運(yùn)算符%睬辐,就是求余數(shù),不夠除為它自己宾肺,0%3=0 溯饵,1%3=1 ,2%3=2锨用,3%3=0
用于被整除求一段范圍(如要讓一個(gè)數(shù)永遠(yuǎn)不超過10丰刊,那么取模10)
if(i===5){i=0}和 i%=5 是一個(gè)意思alert(8%5)為3alert(10%-3)為1,求余的正負(fù)數(shù)不是由后面的正負(fù)號(hào)決定增拥,而是由前面的正負(fù)號(hào)決定
秒轉(zhuǎn)分var s = 3605; alert( math.floor(s/60) + '分' + s%60 + '秒' ?);
[if !supportLists]6.[endif]遞增(++)
遞增運(yùn)算符(++)為其操作數(shù)增加1啄巧,返回一個(gè)數(shù)值。
[if !supportLists]7.[endif]遞減(--)
遞減運(yùn)算符(--)為其操作數(shù)減1掌栅,返回一個(gè)數(shù)值秩仆。
[if !supportLists]二、[endif]賦值運(yùn)算符
就是把右邊的值賦給左邊的變量
=猾封、+=澄耍、-=、*=晌缘、/=逾苫、%=
如果變量num要加 1 ,有三種寫法:num = num+1 num += 1num++ ?
如果變量num要減 1 枚钓,有三種寫法:num = num-1 num -= 1num--
如果變量值得增加或減少不是1铅搓,而是其他數(shù)值,JavaScript還允許把算術(shù)操作符與等號(hào)結(jié)合使用:total = total + 5相當(dāng)于 total += 5
counter = counter - step相當(dāng)于 counter -= step
[if !supportLists]三搀捷、[endif]比較運(yùn)算符
<星掰、>多望、<=、>=氢烘、(等于:==怀偷、不等于!=)、(全等于===播玖、全不等于!==)
返回的是一個(gè)布爾值
==等于椎工,判斷值是否相等(數(shù)據(jù)類型不同時(shí)會(huì)先轉(zhuǎn)換類型,然后比較值)===全等蜀踏,判斷值和類型是否完全相等(數(shù)據(jù)類型不同時(shí)不會(huì)轉(zhuǎn)換類型)
例:
var a = 3;var b = "3";
a==b返回 truea===b返回 false 维蒙,因?yàn)閍,b的類型不一樣
隱式類型轉(zhuǎn)換:
> <運(yùn)算符 ?一定要注意是數(shù)字的比較還是字符串的比較
alert('10'>9);顯示為true ?此時(shí)為數(shù)字的比較alert('10'>'9');顯示為false ?兩個(gè)字符串則按照字符的Unicode編碼去顯示
數(shù)字的比較和字符串的比較是不一樣的字符串比較是一位一位的比較即'10'>'9'先拿1和9 比較,當(dāng)然是false了
[if !supportLists]四果覆、[endif]邏輯運(yùn)算符
[if !supportLists]1.[endif]且運(yùn)算
運(yùn)算符:&&一假且必假:兩個(gè)有一個(gè)假的颅痊,值就是假的那個(gè);兩個(gè)都真局待,值為后斑响;
[if !supportLists]2.[endif]或運(yùn)算
運(yùn)算符:||一真或必真:兩個(gè)有一個(gè)是真的,值就是真的那個(gè)钳榨;兩個(gè)都真舰罚,值為前;
[if !supportLists]3.[endif]取反
alert(!true);alert(!'ok');alert(!100);把右邊的數(shù)據(jù)類型轉(zhuǎn)成布爾值
所有邏輯運(yùn)算符的優(yōu)先級(jí)都低于比較運(yùn)算符
[if !supportLists]五薛耻、[endif]三目運(yùn)算符
和if判斷的第2種寫法作用是一樣的营罢。優(yōu)先級(jí)高于賦值,低于其他運(yùn)算符
條件?語句1 : 語句2
var num=51;num%2==0 ? alert('雙數(shù)'):alert('單數(shù)');
[if !supportLists]第五章 [endif]程序結(jié)構(gòu)
程序的三種基本結(jié)構(gòu)
[if !supportLists]一昭卓、[endif]順序結(jié)構(gòu)
從上到下,從左到右執(zhí)行的順序瘟滨,就叫做順序結(jié)構(gòu)候醒,程序默認(rèn)就是順序結(jié)構(gòu)
[if !supportLists]二、[endif]選擇結(jié)構(gòu)
選擇結(jié)構(gòu)也叫分支結(jié)構(gòu)杂瘸。在任何的編程語言中倒淫,代碼需要依靠不同的輸入作出決定并且采取行動(dòng)。例如败玉,在游戲中敌土,如果玩家的生命值變成了0,那么游戲就結(jié)束了运翼。在天氣應(yīng)用中返干,如果在早晨運(yùn)行,就顯示一張日出的圖片血淌;如果在晚上矩欠,就顯示星星和月亮的圖片财剖。這就要用到條件語句。
[if !supportLists]1.[endif]if語句
if語句括號(hào)里面的表達(dá)式癌淮,會(huì)自動(dòng)調(diào)用Boolean()轉(zhuǎn)型函數(shù)將這個(gè)表達(dá)式轉(zhuǎn)換成一個(gè)布爾值
if (條件 ) { 語句塊 }if (條件 ) { 語句塊 } ?else ?{ 語句塊 }if (條件 ) { 語句塊 } ?else if (條件) { 語句塊 } ... else { 語句塊 }
當(dāng)條件表達(dá)式成立時(shí)(值為true)躺坟,執(zhí)行 語句塊。
注意:所有的相對(duì)路徑(src路徑乳蓄,href路徑)咪橙、顏色值、innerHTML 值 都別拿來做判斷虚倒!除非是絕對(duì)路徑:如src=‘http://www.baidu.com/logo.jpg’
我們可以把代碼縮的更短一些美侦。當(dāng)檢查某項(xiàng)數(shù)據(jù)是否是null值時(shí),其實(shí)是在檢查它是否存在裹刮。這種檢查可以簡(jiǎn)化為直接把被檢查的數(shù)據(jù)用作if語句的條件音榜。if(something)與if(something != null)完全等價(jià)捧弃,但是前者顯然更簡(jiǎn)明赠叼。此時(shí),如果something存在违霞,則if語句的條件為真嘴办;如果something不存在,則if語句的條件為假买鸽。
[if !supportLists]2.[endif]switch語句
和多分支if...else if...else語句 作用是一樣的switch語句評(píng)估一個(gè)表達(dá)式涧郊,將表達(dá)式的值與case子句匹配,并執(zhí)行與該情況相關(guān)聯(lián)的語句眼五。
語法:
<script>????switch (expression) {????????case value1:????????????// 當(dāng)?expression 的結(jié)果與?value1 匹配時(shí)妆艘,執(zhí)行此處語句????????????[break;]????????case value2:????????????// 當(dāng)?expression 的結(jié)果與?value2 匹配時(shí),執(zhí)行此處語句????????????[break;]????????...????????case valueN:????????????// 當(dāng)?expression 的結(jié)果與?valueN 匹配時(shí)看幼,執(zhí)行此處語句????????????[break;]????????????[default:????????????// 如果?expression 與上面的?value 值都不匹配批旺,執(zhí)行此處語句????????????[break;]]????}</script>
expression一個(gè)用來與case子語句匹配的表達(dá)式。
case valueN可選用于匹配expression的 case 子句诵姜。如果 expression 與給定的 valueN 相匹配汽煮,則執(zhí)行該 case 子句中的語句直到該 switch 語句結(jié)束或遇到一個(gè) break 。
default可選一個(gè)default子句棚唆;如果給定暇赤,這條子句會(huì)在 expression 的值與任一 case 語句均不匹配時(shí)執(zhí)行。default在switch語句中的最末尾可以不加break,但是在中間或頭部要加break
[if !supportLists]三宵凌、[endif]循環(huán)結(jié)構(gòu)
[if !supportLists]1.[endif]for循環(huán)
想做這么一件事:重復(fù)執(zhí)行某些代碼每次執(zhí)行的時(shí)候鞋囊,有個(gè)數(shù)字在變化
思考:讓alert(1);重復(fù)執(zhí)行3次
var i=0;
for(;i<3;){
alert(1);
i++
}
以上代碼還可以這么寫:
for(i=0;i<3;i++){
alert(1);
}
再看如下例子:
for(i=0;i<3;i++){
alert(i);
}
在循環(huán)體內(nèi)i為0,1瞎惫,2但是:如果在for循環(huán)體外alert(i);那么i為3去掉i++變成死循環(huán)
[if !supportLists]2.[endif]for...in循環(huán)
已知數(shù)組:var arr=['15','11','999']
x指代數(shù)組里面的下標(biāo)0 失暴, 1坯门, ?2...
for( x in arr ){
alert('第'+x+'個(gè)東西是:'+arr[x]);
}
[if !supportLists]3.[endif]while循環(huán)
while循環(huán)會(huì)一直循環(huán)代碼塊,只要指定的條件為 true(先判斷再執(zhí)行)
語法
while (條件) { 要執(zhí)行的代碼塊}
當(dāng)條件為真時(shí)逗扒,
<script>????var a = 0;????while (a < 3) {????????console.log(a);????????a++;????}</script>
[if !supportLists]4.[endif]do...while循環(huán)
在檢查條件是否為真之前古戴,會(huì)先執(zhí)行一次do里面的代碼,然后只要條件為真就會(huì)重復(fù)循環(huán)矩肩。(先執(zhí)行再判斷)
如下:a的值為 3 现恼,不滿足條件 a < 3, 但是仍然會(huì)執(zhí)行一次 do 里面的代碼
<script>????var a = 3;????do {????????console.log(a);????????a++????} while (a < 3)</script>
[if !supportLists]5.[endif]雙重循環(huán)
什么是雙重循環(huán)
一個(gè)循環(huán)體內(nèi)又包含另一個(gè)完整的循環(huán)結(jié)構(gòu),比如:
<script type="text/javascript">????while(循環(huán)條件1){????????//循環(huán)操作1????????while(循環(huán)條件2){????????????//循環(huán)操作2????????}????}</script>
<script type="text/javascript">????for(循環(huán)條件1){????????//循環(huán)操作1????????for(循環(huán)條件2){????????????//循環(huán)操作2????????}????}</script>
<script type="text/javascript">????while(循環(huán)條件1){????????//循環(huán)操作1????????for(循環(huán)條件2){????????????//循環(huán)操作2????????}????}</script>
雙重循環(huán)注意:
各循環(huán)可互相嵌套一般不超過三層外層循環(huán)變量變化一次黍檩,內(nèi)層循環(huán)變量要變化一遍
使用雙重循環(huán)輸出九九乘法表
<script type="text/javascript">????for(var i=1;i<=9;i++){????????for(var j=1;j<=i;j++){????????????document.write(i+"*"+j+"="+i*j+"???")????????}????????document.write("<br/>");????}</script>
[if !supportLists]四叉袍、[endif]break
break跳出當(dāng)前循環(huán)結(jié)構(gòu)或switch分支結(jié)構(gòu)
不要再執(zhí)行這個(gè)循環(huán)結(jié)構(gòu)了
循環(huán)五次錄入五個(gè)人的成績,如果錄入的成績小于0刽酱,則退出循環(huán)結(jié)構(gòu):
<script type="text/javascript">????for (let i = 1; i <= 5; i++) {????????fenshu = prompt('請(qǐng)輸入成績',"");????????if (fenshu < 0) {????????????document.write(`第${i}名同學(xué)的成績輸入有誤喳逛,強(qiáng)制退出!`);????????????break;????????}????????document.write(`第${i}名同學(xué)的成績?yōu)椋?{fenshu}?<br>`);????}</script>
[if !supportLists]五棵里、[endif]continue
continue跳過本次循環(huán)润文,執(zhí)行下一次循環(huán)。(就是不要再走continue后面的語句了)注意:只能在循環(huán)結(jié)構(gòu)內(nèi)使用(while,do/while,for,for/in)
[if !supportLists]1.[endif]for循環(huán)跳過
<script type="text/javascript">????for (let i = 0; i < 5; i++) {????????if (i == 3) {????????????continue;????????}????????console.log(i)????}</script>
[if !supportLists]2.[endif]例子
<script type="text/javascript">????for (let i = 1; i <= 5; i++) {????????fenshu = prompt('請(qǐng)輸入成績',"");????????if (fenshu < 0) {????????????document.write(`第${i}名同學(xué)的成績輸入有誤殿怜,該成績作廢典蝌!<br>`);????????????continue;????????}????????document.write(`第${i}名同學(xué)的成績?yōu)椋?{fenshu}?<br>`);????}</script>
[if !supportLists]第六章 [endif]數(shù)組對(duì)象
[if !supportLists]一、[endif]什么是數(shù)組
數(shù)組是一組數(shù)據(jù)的集合头谜。數(shù)組中的每個(gè)元素可以保存任何類型(比如布爾值骏掀,數(shù)值,字符串柱告,函數(shù)截驮,對(duì)象,數(shù)組等)
[if !supportLists]二际度、[endif]怎么創(chuàng)建數(shù)組
[if !supportLists]1.[endif]三種方法
<script>???var arr1 = new Array('hello', 100, '張三'); // new方法???var arr2 = ['hello', 100, '張三']; // 字面量方法???var arr3 = Array.of('hello', 100, '張三'); // ES6方法?IE11不支持</script>
[if !supportLists]三葵袭、[endif]數(shù)組的長度
數(shù)組的長度就是數(shù)組中元素的數(shù)量,數(shù)組的長度可讀可寫
<script>???var arr = ['a', 'b', 'c']???arr.length = 1???console.log(arr) // ["a"]</script>
[if !supportLists]四甲脏、[endif]數(shù)組的下標(biāo)
數(shù)組中元素的下標(biāo)從0開始眶熬,最后一個(gè)元素的下標(biāo):數(shù)組的長度減1:arr.length-1
[if !supportLists]1.[endif]通過下標(biāo)添加元素
<script>???var arr1 = new Array();???arr1[0] = 'hello';???arr1[1] = 100;???arr1[2] = '張三';???console.log(arr1);???var arr2 = [];???arr2[0] = 'hello';???arr2[1] = 100;???arr2[2] = '張三';???console.log(arr2);???var arr3 = Array.of();???arr3[0] = 'hello';???arr3[1] = 100;???arr3[2] = '張三';???console.log(arr3);</script>
[if !supportLists]2.[endif]通過下標(biāo)修改元素:
<script>???var arr = ['a', 'b', 'c', 'd'];???arr[2] = 'xyz';???console.log(arr);</script>
通過下標(biāo)在數(shù)組的最后增加一個(gè)元素:
<script>???let arr = ['張三', '李四', '王五', 1, 234, 55, 'last'];???arr[arr.length] = '888'???console.log(arr[arr.length - 1])</script>
[if !supportLists]五妹笆、[endif]快速清空數(shù)組
<script>???let arr = ['張三', '李四', '王五', 1, 234, 55, 'last'];???console.log(arr.length)???// arr.length = 0;???arr = []; // 效率會(huì)高些???console.log(arr)</script>
[if !supportLists]六块请、[endif]二維數(shù)組
<script>???let arr = [[1, 3, 4], ['a', 'b'], ['張三', '李四', '王五', '趙六']];???console.log(arr.length);???console.log(arr[1]);???console.log(arr[2][0]);</script>
[if !supportLists]七、[endif]數(shù)組的遍歷
記兹:只要你想依次把數(shù)組里面每一個(gè)元素都取出來墩新,那么就要用到for循環(huán)了
for, while , for...in
<script>???let arr = ['張三', '李四', '王五', 'a', 'b', 'c'];???for (let i = 0; i < arr.length; i++) {??????const element = arr[i];??????console.log(element);???}???let i = 0;???while (i < arr.length) {??????console.log(arr[i]);??????i++;???}???for (const i in arr) {??????//console.log(i); //i 下標(biāo)??????console.log(arr[i]);???}</script>
二維數(shù)組的遍歷
<script>???let arr = [[1, 3, 4], ['a', 'b'], ['小明', '小李', '張三', '李四']];???for (let i = 0; i < arr.length; i++) {??????for (let j = 0; j < arr[i].length; j++) {?????????console.log(arr[i][j]);??????}???}</script>
[if !supportLists]八、[endif]數(shù)組的方法
[if !supportLists]1.[endif]數(shù)組中元素的添加和刪除
開頭添加和刪除:unshift()和shift()窟坐,末尾添加和刪除:push()和 pop()
[if !supportLists]2.[endif]slice()
slice(start,end)截取數(shù)組中的元素海渊;不操作數(shù)組本身绵疲,(字符串也有這個(gè)方法,用法一樣,但是數(shù)組沒有substring方法)
返回start(包含)到end(不包含)之間的元素組成的數(shù)組臣疑,位置從0開始如果start大于或等于end盔憨,返回一個(gè)空數(shù)組如果只有一個(gè)參數(shù),則默認(rèn)為start讯沈,則返回start(包含)到數(shù)組的末尾如果值為負(fù)數(shù)郁岩,會(huì)被當(dāng)做數(shù)組長度+負(fù)數(shù) 處理
[if !supportLists]3.[endif]splice()
操作數(shù)組本身兼具刪除,添加和替換功能splice(索引,刪除的數(shù)量缺狠,添加的元素)索引:從0開始刪除的數(shù)量:可選问慎;整數(shù),表示要移除的數(shù)組元素的個(gè)數(shù)挤茄。添加的元素:可選如叼;一個(gè)或多個(gè)元素
[if !supportLists]4.[endif]indexOf()
返回某個(gè)指定的元素在數(shù)組中首次出現(xiàn)的位置
indexOf(element,n)從下標(biāo) n開始向右搜索element,找到后將其下標(biāo)返回穷劈;如果沒有找到則返回-1
[if !supportLists]5.[endif]lastIndexOf()
返回某個(gè)指定的元素在數(shù)組中最后出現(xiàn)的位置
lastIndexOf(element,n)從下標(biāo)n開始向左搜索element笼恰,找到后將其下標(biāo)返回;如果沒有找到則返回-1
[if !supportLists]6.[endif]concat() ?
用于合并兩個(gè)或多個(gè)數(shù)組囚衔。此方法不會(huì)更改現(xiàn)有數(shù)組挖腰,而是返回一個(gè)新數(shù)組。
[if !supportLists]7.[endif]join()
join()方法把數(shù)組元素按指定分隔符組合成一個(gè)字符串练湿;如果沒有分隔符猴仑,默認(rèn)是逗號(hào)。不操作數(shù)組本身
[if !supportLists]8.[endif]reverse()
將數(shù)組中元素的位置顛倒肥哎,并返回該數(shù)組辽俗。數(shù)組的第一個(gè)元素會(huì)變成最后一個(gè),數(shù)組的最后一個(gè)元素變成第一個(gè)篡诽。該方法會(huì)改變?cè)瓟?shù)組
[if !supportLists]9.[endif]includes()
includes()方法用來判斷一個(gè)數(shù)組是否包含一個(gè)指定的值崖飘,如果包含則返回 true,否則返回false杈女。
[if !supportLists]10.[endif]sort()
按照字符的unicode編碼排序朱浴,默認(rèn)升序,先排第一個(gè)字符达椰,以此類推
<script>????var arr=[4,3,5,76,2,0,8];????arr.sort( function(a,b){????????return a-b;????});????alert(arr);</script>
結(jié)果:0,2,3,4,5,8,76
[if !supportLists]九翰蠢、[endif]迭代方法
所謂的迭代,就是對(duì)數(shù)組的每一項(xiàng)都進(jìn)行相應(yīng)的操作啰劲。
[if !supportLists]1.[endif]forEach()
循環(huán)數(shù)組或集合中的對(duì)象梁沧、數(shù)據(jù)
arr.forEach(callback[, thisArg]);arr.forEach(回調(diào)函數(shù),this對(duì)象);
[if !supportLists]2.[endif]map()
返回一個(gè)由原數(shù)組每個(gè)元素執(zhí)行回調(diào)函數(shù)的結(jié)果組成的新數(shù)組。
<script>????var array1 = [1, 4, 9, 16];????// pass a function to map????const map1 = array1.map(x => x * 2);????console.log(map1);????// expected output: Array [2, 8, 18, 32]</script>
[if !supportLists]3.[endif]filter()
返回讓回調(diào)函數(shù)為true的元素組成的數(shù)組
<script>????var words = ['spray', 'limit', 'elite', 'exuberant', 'destruction', 'present'];????const result = words.filter(word => word.length > 6);????console.log(result);????// expected output: Array ["exuberant", "destruction", "present"]</script>
[if !supportLists]4.[endif]every()
有一個(gè)元素讓條件為false蝇裤,則返回false?廷支。且剩余的元素不會(huì)再進(jìn)行檢測(cè)频鉴。
<script>????function isBelowThreshold(currentValue) {????????return currentValue < 40;????}????var array1 = [1, 30, 39, 29, 10, 13];????console.log(array1.every(isBelowThreshold));????// expected output: true</script>
[if !supportLists]5.[endif]some()
有一個(gè)元素讓條件為true,則返回true?恋拍。且剩余的元素不會(huì)再進(jìn)行檢測(cè)垛孔。
下面的例子檢測(cè)在數(shù)組中是否有元素大于10。
<script>????function isBiggerThan10(element, index, array) {????????return element > 10;????}????[2, 5, 8, 1, 4].some(isBiggerThan10); ?// false????[12, 5, 8, 1, 4].some(isBiggerThan10); // true</script>
[if !supportLists]6.[endif]reduce()
循環(huán)數(shù)組中的每一項(xiàng)進(jìn)行累計(jì)操作
[if !supportLists]7.[endif]find()
返回滿足條件的第一個(gè)元素的值施敢。否則返回undefined似炎。
<script>????var array1 = [5, 12, 8, 130, 44];????var found = array1.find(function(element) {????????return element > 10;????});????console.log(found);????// expected output: 12</script>
[if !supportLists]8.[endif]findIndex()
返回?cái)?shù)組中滿足條件的第一個(gè)元素的索引。否則返回-1悯姊。
<script>????var array1 = [5, 12, 8, 130, 44];????function isLargeNumber(element) {????????return element > 13;????}????console.log(array1.findIndex(isLargeNumber));????// expected output: 3</script>
[if !supportLists]第七章 [endif]日期對(duì)象
[if !supportLists]一羡藐、[endif]Date對(duì)象的構(gòu)造函數(shù)
創(chuàng)建一個(gè)日期對(duì)象:new Date()
[if !supportLists]二、[endif]實(shí)例化Date對(duì)象
創(chuàng)建一個(gè)新Date對(duì)象的唯一方法是通過new 操作符:
<script>????let now = new Date();</script>
[if !supportLists]三悯许、[endif]語法
Date()構(gòu)造函數(shù)有四種基本形式
[if !supportLists]1.[endif]沒有參數(shù)
new Date()
如果沒有輸入任何參數(shù)仆嗦,則Date的構(gòu)造器會(huì)依據(jù)系統(tǒng)設(shè)置的當(dāng)前時(shí)間(也就是執(zhí)行JavaScript的客戶端電腦所設(shè)置的時(shí)間)來創(chuàng)建一個(gè)Date對(duì)象。
[if !supportLists]2.[endif]Unix時(shí)間戳
new Date(milliseconds)
一個(gè)Unix時(shí)間戳(Unix Time Stamp)先壕,它是一個(gè)整數(shù)值瘩扼,表示自1970年1月1日00:00:00 UTC(the Unix epoch)以來的毫秒數(shù),忽略了閏秒垃僚。請(qǐng)注意大多數(shù) Unix 時(shí)間戳功能僅精確到最接近的秒集绰。
[if !supportLists]3.[endif]時(shí)間戳字符串
new Date(dateString)
注意:由于瀏覽器之間的差異與不一致性,強(qiáng)烈不推薦使用Date構(gòu)造函數(shù)來解析日期字符串 (或使用與其等價(jià)的Date.parse)谆棺。
<script>????var birthday = new Date('March 21, 1987 23:15:30');????var day1 = birthday.getDay();????// Sunday - Saturday : 0 - 6????console.log(day1); // 6????console.log(birthday.getHours()); // 23</script>
[if !supportLists]4.[endif]分別提供日期與時(shí)間的每一個(gè)成員
new Date(year, monthIndex [, date [, hours [, minutes [, seconds [, milliseconds]]]]]);
當(dāng)至少提供了年份與月份時(shí)栽燕,這一形式的Date()返回的 Date 對(duì)象中的每一個(gè)成員都來自下列參數(shù)。沒有提供的成員將使用最小可能值(對(duì)日期為1改淑,其他為0)碍岔。
new Date(2018,9,16,0,50,0); //月份從0開始,
[if !supportLists]四朵夏、[endif]Date對(duì)象轉(zhuǎn)換為字符串
它們是很實(shí)用的蔼啦,能夠把日期轉(zhuǎn)換為更容易理解的格式。
本地格式:該字符串格式因不同語言而不同
<script>????var myDate = new Date();????// 日期和時(shí)間:Wed Nov 06 2019 08:44:11 GMT+0800 (中國標(biāo)準(zhǔn)時(shí)間)????console.log(myDate.toString());????console.log(myDate.toDateString()); ?????????// 日期部分:Wed Nov 06 2019????console.log(myDate.toTimeString()); ?????????// 時(shí)間部分:08:49:00 GMT+0800 (中國標(biāo)準(zhǔn)時(shí)間)????console.log(myDate.toLocaleString()); ?// 本地格式的日期和時(shí)間:2019/11/6 上午8:56:35????console.log(myDate.toLocaleDateString()); ?// 本地格式的日期部分:2019/11/6????console.log(myDate.toLocaleTimeString()); ?// 本地格式的時(shí)間部分:上午8:56:35????// 根據(jù)世界時(shí)仰猖,把Date對(duì)象轉(zhuǎn)換為字符串:Wed, 06 Nov 2019 00:49:00 GMT????console.log(myDate.toUTCString()); ???</script>
[if !supportLists]五捏肢、[endif]Date對(duì)象的方法
[if !supportLists]1.[endif]獲取時(shí)間
這些方法返回的都是number類型
<script>????let now = new Date();????console.log(now.getFullYear()); // 返回一個(gè)四位數(shù)字的年份????console.log(now.getMonth()); //返回一個(gè)?0 到?11的整數(shù)值: 0代表一月份,1代表二月份饥侵,依次類推????console.log(now.getDate()); // 返回一個(gè)?1 到?31 的整數(shù)值鸵赫,表示一個(gè)月中的第幾天????console.log(now.getHours()); // 返回一個(gè)?0 到?23 的整數(shù)值,表示小時(shí)????console.log(now.getMinutes()); // 返回一個(gè)?0 到?59 的整數(shù)值爆捞,表示分鐘數(shù)????console.log(now.getSeconds()); // 返回一個(gè)?0 到?59 的整數(shù)值奉瘤,表示秒數(shù)????console.log(now.getMilliseconds()); // 方法返回一個(gè)0 到?999的整數(shù)勾拉,表示毫秒數(shù)????console.log(now.getDay()); // 返回一個(gè)?0到?6的整數(shù)值:?0 代表星期日煮甥,1代表星期一盗温,依次類推????console.log(now.getTime()); // 返回距?1970 年?1 月?1 日之間的毫秒數(shù)</script>
[if !supportLists]第八章 [endif]字符串對(duì)象
[if !supportLists]一、[endif]字符串長度
字符串屬性:length成肘,獲取字符串的長度
例如:var str = 'www.aixue8.com';alert(str.length);
注意:空格也要計(jì)算在長度內(nèi)
[if !supportLists]二卖局、[endif]字符串方法
[if !supportLists]1.[endif]str.charAt(下標(biāo))
返回指定下標(biāo)所在的字符,第一個(gè)字符的下標(biāo)為0双霍。
例如:
<script>????var str = '好代碼';????alert(str.charAt(1));????alert(str.charAt(0)); //或?alert(str.charAt())</script>
用[]訪問單個(gè)字符和charAt()這兩種方式都可以獲取到字符串對(duì)應(yīng)位置的字符砚偶,獲取的位置都是從0開始。區(qū)別在于:使用string[]的方式洒闸,對(duì)于超出字符長度范圍的染坯,會(huì)返回undefined而使用charAt()的方式,對(duì)于超出范圍的會(huì)返回一個(gè)空的字符串丘逸。
-----------------
[if !supportLists]2.[endif]str.charCodeAt(下標(biāo))
根據(jù)下標(biāo)獲取字符的Unicode編碼单鹿,下標(biāo)從0開始
var str='愛學(xué)吧';alert( str.charCodeAt(0) );
[if !supportLists]3.[endif]slice()和substring()
截取一個(gè)字符串的一部分,并返回一新的字符串深纲,主要有兩個(gè)方法:str.substring(start,end)和str.slice(start仲锄,end)
str.slice(start翎嫡,end)返回start(包含)到end(不包含)之間的字符串厌秒,位置從0開始如果start大于或等于end,返回一個(gè)字符串如果只有一個(gè)參數(shù)后豫,則默認(rèn)為start币呵,則返回start(包含)到字符串的末尾如果值為負(fù)數(shù)怀愧,會(huì)被當(dāng)做數(shù)組長度+負(fù)數(shù) 處理
str.substring(start,end)和slice()方法一樣,區(qū)別:如果start大于end余赢,則交換位置參數(shù)值為負(fù)數(shù)掸驱,則被視為0任何大于字符串長度的參數(shù)值都被視為字符串長度任何NaN參數(shù)值都被視為0
[if !supportLists]4.[endif]search('string') ?
找到了返回其下標(biāo),找不到返回-1(類似indexOf()方法)
[if !supportLists]5.[endif]match('string')
只能匹配一個(gè)没佑。返回?cái)?shù)組或null
[if !supportLists]6.[endif]replace('string1','string2')
把string1替換成string2
var str = 'www.aixue8.com';document.write(str.replace('aixue8','soucloud'))
[if !supportLists]7.[endif]split('string'[,limit])
使用指定的分隔符字符串將一個(gè)字符串分割成字符串?dāng)?shù)組毕贼;limit一個(gè)整數(shù),限定返回的分割片段數(shù)量
可以使用正則表達(dá)式:str.split(regExp)
[if !supportLists]8.[endif]toUpperCase()
轉(zhuǎn)換為大寫str.toUpperCase()
[if !supportLists]9.[endif]和toLowerCase()
轉(zhuǎn)換為小寫str.toLowerCase()
[if !supportLists]10.[endif]trim()
刪除字符串兩端的空白字符蛤奢。在這個(gè)上下文中的空白字符是所有的空白字符(space, tab, no-break space等) 以及所有行終止符字符(如 LF鬼癣,CR等)。
[if !supportLists]11.[endif]includes()
includes()方法用于判斷一個(gè)字符串是否包含另一個(gè)字符串啤贩,如果當(dāng)前字符串包含被搜尋的字符串待秃,就返回 true;否則返回 false痹屹。區(qū)分大小寫
[if !supportLists]12.[endif]indexOf('string',下標(biāo))
返回某個(gè)指定的字符串值在字符串中首次出現(xiàn)的位置
[if !supportLists]13.[endif]lastIndexOf('string',Number)
str.lastIndexOf('string',Number)返回某個(gè)指定的字符串值在字符串中最后出現(xiàn)的位置
[if !supportLists]14.[endif]startsWith('string')
字符串string是否在原字符串的開頭章郁,返回布爾值
[if !supportLists]15.[endif]endsWith('string')
字符串string是否在原字符串的結(jié)尾,返回布爾值
[if !supportLists]16.[endif]concat()
str.concat(str1,str2,...) ?將多個(gè)字符串連接成一個(gè)字符串用+更簡(jiǎn)單一些,推薦
[if !supportLists]17.[endif]repeat()
str.repeat(n) ??將原字符串重復(fù)n次后返回一個(gè)新字符串
[if !supportLists]第九章 [endif]Math對(duì)象
與Date對(duì)象不同的是暖庄,Math對(duì)象不需要?jiǎng)?chuàng)建就可以使用聊替。我們直接調(diào)用它的方法就可以了。
Math是一個(gè)內(nèi)置對(duì)象培廓, 它具有數(shù)學(xué)常數(shù)和函數(shù)的屬性和方法惹悄。不是一個(gè)函數(shù)對(duì)象。
[if !supportLists]一肩钠、[endif]ceil()
語法:Math.ceil(x)參數(shù)x是一個(gè)數(shù)字泣港,向上取整,返回 大于或等于 給定數(shù)字的最小整數(shù)
[if !supportLists]二价匠、[endif]floor()
語法:Math.floor(x)參數(shù)x是一個(gè)數(shù)字当纱;向下取整,返回 小于或等于 給定數(shù)字的最大整數(shù)
[if !supportLists]三踩窖、[endif]round()
語法:Math.round(x)參數(shù)x是一個(gè)數(shù)字惫东;返回一個(gè)數(shù)字四舍五入后最接近的整數(shù)
[if !supportLists]四、[endif]random()
Math.random()函數(shù)返回一個(gè)大于等于0毙石,小于1之間的隨機(jī)數(shù)然后您可以縮放到所需的范圍廉沮。實(shí)現(xiàn)將初始種子選擇到隨機(jī)數(shù)生成算法;它不能被用戶選擇或重置。
[if !supportLists]1.[endif]得到一個(gè)兩數(shù)之間的隨機(jī)數(shù)
min≤x<max徐矩。
公式:Math.random() * (max - min) + min;
[if !supportLists]2.[endif]得到一個(gè)兩數(shù)之間的隨機(jī)整數(shù)
min≤x<max滞时。公式:Math.floor(Math.random()*(max-min)+min)
min<x≤max。公式:Math.ceil(Math.random()*(max-min)+min)
[if !supportLists]五滤灯、[endif]max()
語法:Math.max(value1[,value2, ...])參數(shù)value1, value2, ... 是一組數(shù)值坪稽。返回給定的一組數(shù)字中的最大值,
[if !supportLists]六鳞骤、[endif]min()
語法:Math.min(value1[,value2, ...])參數(shù)value1, value2, ... 是一組數(shù)值窒百;返回給定的一組數(shù)字中的最小值,
[if !supportLists]七豫尽、[endif]PI
Math.PI
圓周率篙梢,一個(gè)圓的周長和直徑之比,約等于3.14159
[if !supportLists]八美旧、[endif]平方根
Math.SQRT1_2
1/2的平方根, 約等于 0.707
Math.SQRT2
2的平方根,約等于 1.414
[if !supportLists]九渤滞、[endif]abs()
Math.abs(x); ?返回x的絕對(duì)值,參數(shù)x是一個(gè)數(shù)字
[if !supportLists]第十章 [endif]函數(shù)
[if !supportLists]一榴嗅、[endif]什么是函數(shù)
JavaScript函數(shù)是用來完成特定任務(wù)的代碼塊妄呕。JavaScript把部分代碼包裝為能夠重復(fù)使用的模塊,稱為函數(shù)嗽测。
[if !supportLists]二绪励、[endif]創(chuàng)建函數(shù)
[if !supportLists]1.[endif]函數(shù)聲明
函數(shù)聲明的語法:
function函數(shù)名(參數(shù)1,參數(shù)2,...) { 函數(shù)體(代碼塊) return返回值;}
[if !supportLists]2.[endif]函數(shù)表達(dá)式
var fn = function (參數(shù)1,參數(shù)2,...) { 函數(shù)體 return返回值;};
推薦這種方式疏魏,因?yàn)楹瘮?shù)聲明方式會(huì)提前
[if !supportLists]3.[endif]ES6箭頭函數(shù)表達(dá)式
箭頭函數(shù)表達(dá)式的語法比函數(shù)表達(dá)式更簡(jiǎn)潔停做,并且沒有自己的this,arguments蠢护,super或 new.target。這些函數(shù)表達(dá)式更適用于那些本來需要匿名函數(shù)的地方养涮,并且它們不能用作構(gòu)造函數(shù)葵硕。
箭頭函數(shù)不能用作構(gòu)造器,和new一起用會(huì)拋出錯(cuò)誤贯吓。var Foo = () => {};var foo = new Foo(); // TypeError: Foo is not a constructor
箭頭函數(shù)沒有prototype屬性懈凹。var Foo = () => {};console.log(Foo.prototype); // undefined
基礎(chǔ)語法:(參數(shù)1, 參數(shù)2, …, 參數(shù)N) => { 語句 }
(參數(shù)1, 參數(shù)2, …, 參數(shù)N) => 表達(dá)式(單一)相當(dāng)于:(參數(shù)1, 參數(shù)2, …, 參數(shù)N) =>{ return 表達(dá)式; }
當(dāng)只有一個(gè)參數(shù)時(shí),圓括號(hào)是可選的:(單一參數(shù)) => {函數(shù)聲明}單一參數(shù)=> {函數(shù)聲明}
沒有參數(shù)的函數(shù)應(yīng)該寫成一對(duì)圓括號(hào)悄谐。() => {函數(shù)聲明}
箭頭函數(shù)沒有arguments對(duì)象介评。可以用rest參數(shù)代替
[if !supportLists]4.[endif]使用Function構(gòu)造函數(shù)
var fn = new Function('arg1','arg2',...,'argN','代碼塊;returen 返回值');
arg是參數(shù)爬舰;必須加引號(hào)们陆;return返回值不是必須的不建議使用,效率低情屹,影響性能
[if !supportLists]三坪仇、[endif]調(diào)用函數(shù)
函數(shù)只有在調(diào)用時(shí)才能執(zhí)行函數(shù)體里面的代碼,不調(diào)用就永遠(yuǎn)不會(huì)執(zhí)行垃你。
[if !supportLists]1.[endif]函數(shù)名加小括號(hào)
函數(shù)名稱()或 變量名()
如:fn();
fn存儲(chǔ)的是一個(gè)地址椅文,代表的是當(dāng)前的整個(gè)函數(shù)塊fn()表示執(zhí)行函數(shù)里面的代碼
[if !supportLists]2.[endif]通過事件調(diào)用
obj.事件 = 函數(shù)名稱 或 變量名 或 整個(gè)函數(shù)塊
[if !supportLists]3.[endif]整個(gè)函數(shù)加小括號(hào)
( function () {alert('ok');} )() ; ?
可以避免代碼庫中的函數(shù)有重名問題,且只會(huì)在運(yùn)行時(shí)執(zhí)行一次惜颇,一般用作初始化工作
[if !supportLists]4.[endif]通過函數(shù)的apply或call或bind方法調(diào)用
call()方法使用一個(gè)指定的 this 值和單獨(dú)給出的一個(gè)或多個(gè)參數(shù)來調(diào)用一個(gè)函數(shù)皆刺。(就是說可以指定誰來調(diào)用這個(gè)函數(shù),且調(diào)用時(shí)可以傳參)
語法
fun.call(thisArg, arg1, arg2, ...)
參數(shù)
thisArg:在 fun 函數(shù)運(yùn)行時(shí)指定的 this 值凌摄。arg1, arg2, ...:指定的參數(shù)列表羡蛾。
[if !supportLists]四、[endif]函數(shù)傳參
[if !supportLists]1.[endif]實(shí)參和形參
函數(shù)的參數(shù)分為實(shí)參和形參:實(shí)參:在調(diào)用函數(shù)的時(shí)候锨亏,小括號(hào)中傳入的變量或值;實(shí)際傳入的參數(shù)形參:在創(chuàng)建函數(shù)的時(shí)候林说,小括號(hào)中定義的變量,用來接收實(shí)參屯伞。ES6允許為函數(shù)的參數(shù)設(shè)置默認(rèn)值腿箩,在ES6之前,不可以劣摇。設(shè)置方法:直接在形參里面設(shè)置
參數(shù)的類型可以是任何數(shù)據(jù)類型
傳參的作用:可以動(dòng)態(tài)的改變函數(shù)體內(nèi)對(duì)應(yīng)的變量的值或類型珠移,使同一函數(shù)體得到不同的結(jié)果,減少代碼重復(fù)對(duì)參數(shù)進(jìn)行判斷,根據(jù)判斷的結(jié)果進(jìn)行相應(yīng)的處理
[if !supportLists]2.[endif]實(shí)參==形參
正好一對(duì)一
<script>????function fn(a) {????????console.log(a);????}????fn(100)</script>
<script>????fn('我喜歡');????fn('javascript');????function fn(a) {????????console.log(a.charAt(2));????}</script>
多個(gè)實(shí)參之間用英文逗號(hào)隔開:
<script>????fn(100, 'px');????function fn(a, b) {????????console.log(a + b);????}</script>
[if !supportLists]3.[endif]實(shí)參<形參
不會(huì)報(bào)錯(cuò)钧惧,會(huì)自動(dòng)賦值為undefined
<script>????function f(a) {????????console.log(a); // undefined????}????f();</script>
[if !supportLists]4.[endif]實(shí)參>形參
不會(huì)報(bào)錯(cuò)暇韧,可以用arguments對(duì)象或ES6剩余參數(shù) 獲取到
arguments對(duì)象是所有(非箭頭函數(shù))函數(shù)中都可用的局部變量,只能在函數(shù)體內(nèi)使用浓瞪。每創(chuàng)建一個(gè)函數(shù)懈玻,該函數(shù)就會(huì)隱式創(chuàng)建一個(gè)arguments對(duì)象,它包含了當(dāng)前函數(shù)的所有實(shí)參乾颁。
arguments對(duì)象具有如下屬性:arguments.length:返回實(shí)參的數(shù)量arguments.callee:返回當(dāng)前函數(shù)塊(就是函數(shù)本身)(匿名函數(shù)可以使用該屬性實(shí)現(xiàn)遞歸調(diào)用)
<script>????fn(1, 2, 3); //實(shí)參涂乌,實(shí)際傳遞的參數(shù)????function fn(a, b, c) { ?//a,b英岭,c是形參湾盒,用來接收實(shí)參????????console.log(arguments); // 實(shí)參的集合????????console.log(arguments.length); // 實(shí)參的數(shù)量????????console.log(arguments[0]); // 第一個(gè)實(shí)參????????console.log(arguments[arguments.length - 1]); // 最后一個(gè)實(shí)參????????console.log(arguments instanceof Array); // false????}</script>
剩余語法(Rest syntax)看起來和展開語法完全相同,不同點(diǎn)在于, 剩余參數(shù)用于解構(gòu)數(shù)組和對(duì)象诅妹。從某種意義上說罚勾,剩余語法與展開語法是相反的:展開語法將數(shù)組展開為其中的各個(gè)元素,而剩余語法則是將多個(gè)元素收集起來并“凝聚”為單個(gè)元素吭狡。
ES2015引入了rest參數(shù)尖殃,形式為:...變量名 ,用于獲取函數(shù)的多余參數(shù)划煮,這樣就不需要使用arguments對(duì)象了分衫。rest參數(shù)的變量是一個(gè)數(shù)組,里面包含了函數(shù)的參數(shù)般此。rest參數(shù)之后不能再有其他的參數(shù)蚪战,即只能是最后一個(gè)參數(shù),否則會(huì)報(bào)錯(cuò)
[if !supportLists]5.[endif]將函數(shù)作為值傳遞
將一個(gè)函數(shù)作為參數(shù)傳遞給其他函數(shù)铐懊。這看起來像《盜夢(mèng)空間》中的情形邀桑,但提供了強(qiáng)大的功能。從本質(zhì)上說科乎,函數(shù)視為一種類型壁畸,因此可將函數(shù)賦給變量,以后再通過變量來調(diào)用它們茅茂。
函數(shù)是一種對(duì)象類型捏萍,因此可將其傳遞給其他函數(shù)
[if !supportLists]五、[endif]this對(duì)象
在函數(shù)內(nèi)部除了有arguments這個(gè)對(duì)象空闲,還有個(gè)this對(duì)象在絕大多數(shù)情況下令杈,函數(shù)的調(diào)用方式?jīng)Q定了this的值。this不能在執(zhí)行期間被賦值碴倾,并且在每次函數(shù)被調(diào)用時(shí)this的值也可能會(huì)不同逗噩。對(duì)于箭頭函數(shù)掉丽,函數(shù)體內(nèi)this對(duì)象就是定義時(shí)所在的對(duì)象,而不是調(diào)用時(shí)所在對(duì)象
[if !supportLists]1.[endif]全局環(huán)境
無論是否在嚴(yán)格模式下异雁,在全局執(zhí)行環(huán)境中(在任何函數(shù)體外部)this都指向全局對(duì)象捶障。
<script>????// 在瀏覽器中, window 對(duì)象同時(shí)也是全局對(duì)象:????console.log(this === window); // true????a = 37;????console.log(window.a); // 37????this.b = "MDN";????console.log(window.b) ?// "MDN"????console.log(b) ????????// "MDN"</script>
[if !supportLists]2.[endif]作為對(duì)象的方法
當(dāng)函數(shù)作為對(duì)象里的方法被調(diào)用時(shí),它們的this是調(diào)用該函數(shù)的對(duì)象纲刀。
下面的例子中项炼,當(dāng)obj.f()被調(diào)用時(shí),函數(shù)內(nèi)的this將綁定到obj對(duì)象示绊。
<script>????var obj = {????????num: 100,????????f: function () {????????????console.log(this.num)????????}????};????obj.f(); // 100</script>
[if !supportLists]3.[endif]作為構(gòu)造函數(shù)
當(dāng)一個(gè)函數(shù)用作構(gòu)造函數(shù)時(shí)(使用new關(guān)鍵字)锭部,它的this被綁定到正在構(gòu)造的新對(duì)象。
[if !supportLists]4.[endif]作為一個(gè)DOM事件處理函數(shù)
當(dāng)函數(shù)被用作事件處理函數(shù)時(shí)耻台,它的this指向觸發(fā)事件的元素
<script>????var mybtn = document.querySelector('#btn');????mybtn.onclick = function () {????????console.log(this); // ?是按鈕調(diào)用了this所在的這個(gè)函數(shù), 所以this就是按鈕這個(gè)元素????}????mybtn.onclick = function () { fn2(); } // 相當(dāng)于?window.fn2()????function fn2() {????????console.log(this); // this => window????}????mybtn.onclick = function () { fn3(this); }????function fn3(a) {????????console.log(a); // this => 按鈕元素????}</script>
[if !supportLists]六空免、[endif]返回值
return語句終止函數(shù)的執(zhí)行空另,并返回一個(gè)指定的值給函數(shù)調(diào)用者盆耽。
[if !supportLists]1.[endif]語法
return [[expression]];
expression表達(dá)式的值會(huì)被返回。如果沒有expression扼菠,則返回 undefined摄杂。
任何函數(shù)都可以通過return語句來實(shí)現(xiàn)返回值,返回值可以是任何js的數(shù)據(jù)類型
<script>????function counter() {????????for (var count = 1; ; count++) { ?// 無限循環(huán)????????????console.log(count + "A"); // 執(zhí)行5次????????????if (count === 5) {????????????????return;????????????}????????????console.log(count + "B"); ?// 執(zhí)行4次????????}????????console.log(count + "C"); ?// 永遠(yuǎn)不會(huì)執(zhí)行????}????counter();</script>
[if !supportLists]七循榆、[endif]作用域
什么是作用域:一條數(shù)據(jù)起作用的范圍
[if !supportLists]1.[endif]全局作用域
聲明在任何函數(shù)以外的數(shù)據(jù)析恢,擁有全局作用域。全局作用域的數(shù)據(jù)秧饮,在這條數(shù)據(jù)聲明之后的任何地方都能訪問和修改映挂,且只有在頁面關(guān)閉后才被刪除。
[if !supportLists]2.[endif]局部作用域
函數(shù)的作用域就是局部作用域局部作用域的數(shù)據(jù)盗尸,只能在函數(shù)內(nèi)部進(jìn)行訪問和修改柑船,且在函數(shù)運(yùn)行以后被立即刪除
局部作用域的數(shù)據(jù):在函數(shù)內(nèi)部使用var或let聲明的變量(函數(shù)內(nèi)未使用var或let聲明而直接賦值的變量擁有全局作用域)函數(shù)的參數(shù);函數(shù)內(nèi)的聲明函數(shù)和函數(shù)表達(dá)式
[if !supportLists]3.[endif]作用域鏈
當(dāng)我們調(diào)用一條數(shù)據(jù)的時(shí)候泼各,會(huì)先在本作用域進(jìn)行查找鞍时,如果找不到就向上查找父作用域,如果還是沒有找到扣蜻,就繼續(xù)向上逆巍,一直找到全局作用域,還是找不到就報(bào)錯(cuò)莽使。
<script>????var authorName="山邊小溪";????function doSomething(){????????var blogName="夢(mèng)想天空";????????function innerSay(){????????????alert(blogName);????????}????????innerSay();????}????alert(authorName); //山邊小溪????alert(blogName); //腳本錯(cuò)誤????doSomething(); //夢(mèng)想天空????innerSay() //腳本錯(cuò)誤</script>
[if !supportLists]八锐极、[endif]閉包
[if !supportLists]1.[endif]什么是閉包
在一個(gè)函數(shù)內(nèi)部創(chuàng)建另一個(gè)函數(shù),通過另一個(gè)函數(shù)訪問這個(gè)函數(shù)的局部變量(參數(shù)和變量不會(huì)被垃圾回收機(jī)制所收回)
從技術(shù)的角度講芳肌,所有的JavaScript函數(shù)都是閉包:它們都是對(duì)象溪烤,它們都關(guān)聯(lián)到作用域鏈味咳。
<script>????function init() {????????var name = "Mozilla"; // name 是一個(gè)被?init 創(chuàng)建的局部變量????????function displayName() { // displayName() 是內(nèi)部函數(shù),一個(gè)閉包????????????alert(name); // displayName() 函數(shù)使用了父函數(shù)中聲明的變量????????}????????displayName();????}????init();</script>
因?yàn)椋阂粋€(gè)函數(shù)引用另一個(gè)函數(shù)的變量,因?yàn)樽兞勘灰弥圆粫?huì)被回收這是優(yōu)點(diǎn)也是缺點(diǎn)檬嘀,不必要的閉包只會(huì)增加內(nèi)存消耗
閉包中的this在運(yùn)行時(shí)指向window
[if !supportLists]2.[endif]閉包的用途
可以讀取函數(shù)內(nèi)部的變量槽驶,是將函數(shù)內(nèi)部和函數(shù)外部連接起來的一座橋梁。讓這些變量的值始終保持在內(nèi)存中鸳兽。
[if !supportLists]3.[endif]閉包的缺點(diǎn)
閉包會(huì)使得函數(shù)中的變量都被保存在內(nèi)存中掂铐,內(nèi)存消耗很大,所以不能濫用閉包揍异,否則會(huì)造成網(wǎng)頁的性能問題全陨,在IE中可能導(dǎo)致內(nèi)存泄露。過度使用閉包會(huì)導(dǎo)致性能下降衷掷,盡量少使用閉包辱姨,只在必要時(shí)使用。
閉包會(huì)在父函數(shù)外部戚嗅,改變父函數(shù)內(nèi)部變量的值
[if !supportLists]九雨涛、[endif]回調(diào)函數(shù)
回調(diào)(callback):把一個(gè)函數(shù)作為參數(shù)傳到一個(gè)主函數(shù)里面,當(dāng)主函數(shù)執(zhí)行完之后懦胞,再執(zhí)行傳進(jìn)去的這個(gè)函數(shù)替久。這個(gè)過程就叫做回調(diào)。
[if !supportLists]十躏尉、[endif]遞歸函數(shù)
在函數(shù)內(nèi)部直接或間接的調(diào)用自己使用遞歸時(shí)調(diào)用次數(shù)不要太多蚯根,防止內(nèi)存溢出;要有讓調(diào)用結(jié)束的條件
<script>????function fn(num) {????????if (num <= 1) {????????????return 1;????????} else {????????????return num * fn(num - 1)????????}????}????console.log(fn(4));</script>
[if !supportLists]十一胀糜、[endif]內(nèi)置全局函數(shù)
內(nèi)置:其實(shí)就是系統(tǒng)已經(jīng)編寫好的一些函數(shù)颅拦,具有特定的功能,可以直接使用頂層:全局函數(shù)教藻,可以作用于任何對(duì)象
[if !supportLists]第十一章 [endif]JS的預(yù)解析規(guī)則
[if !supportLists]一距帅、[endif]變量的預(yù)解析
JS會(huì)對(duì)整個(gè)script塊中的代碼進(jìn)行預(yù)解析,把var聲明的變量提前至作用域的頂部怖竭,且變量的值都是undefined變量重名的:只留后一個(gè)變量如果預(yù)解析這一步出現(xiàn)錯(cuò)誤:整個(gè)script塊的代碼都不會(huì)執(zhí)行锥债,但是不會(huì)影響其他script塊的代碼
預(yù)解析完畢后,開始執(zhí)行代碼痊臭,表達(dá)式可以修改預(yù)解析的值哮肚,表達(dá)式:= + - * / ++ -- %如果執(zhí)行代碼這一步錯(cuò)誤:只會(huì)影響其后代碼的執(zhí)行,不會(huì)影響其他script塊的代碼
[if !supportLists]二广匙、[endif]函數(shù)的預(yù)解析
JS會(huì)對(duì)整個(gè)script塊中的代碼進(jìn)行預(yù)解析允趟,把函數(shù)聲明的整個(gè)函數(shù)塊(函數(shù)名稱和函數(shù)體)提前至作用域的頂部
函數(shù)重名的:只留后一個(gè)函數(shù)變量和函數(shù)名重名了,就只留下函數(shù)如果預(yù)解析這一步出現(xiàn)錯(cuò)誤:整個(gè)script塊的代碼都不會(huì)執(zhí)行鸦致,但是不會(huì)影響其他script塊的代碼
預(yù)解析完畢后潮剪,執(zhí)行代碼涣楷,表達(dá)式可以修改預(yù)解析的值,表達(dá)式:= + - * / ++ -- %如果執(zhí)行代碼這一步錯(cuò)誤:只會(huì)影響其后代碼的執(zhí)行抗碰,不會(huì)影響其他script塊的代碼
函數(shù)執(zhí)行的時(shí)候會(huì)對(duì)函數(shù)中的變量和函數(shù)進(jìn)行預(yù)解析
[if !supportLists]第十二章 [endif]面向?qū)ο?/b>
面向?qū)ο螅∣bject-Oriented狮斗,OO)的語言有一個(gè)標(biāo)志,那就是它們都有類的概念弧蝇,而通過類可以創(chuàng)建任意多個(gè)具有相同屬性和方法的對(duì)象碳褒。ECMAScript5沒有類的概念,ES6才有看疗。
[if !supportLists]一沙峻、[endif]什么是對(duì)象
對(duì)象是某個(gè)特定引用類型的實(shí)例
對(duì)象類型,也叫引用數(shù)據(jù)類型两芳,復(fù)雜數(shù)據(jù)類型
[if !supportLists]二摔寨、[endif]對(duì)象分類
內(nèi)置對(duì)象,由ECMAScript定義的對(duì)象:數(shù)組(Array對(duì)象)怖辆,日期(Date對(duì)象)是复,函數(shù)(Function對(duì)象),Math對(duì)象疗隶,正則表達(dá)式(regExp對(duì)象)宿主對(duì)象:宿主環(huán)境提供的對(duì)象自定義對(duì)象
[if !supportLists]三佑笋、[endif]原始數(shù)據(jù)類型和對(duì)象類型
原始數(shù)據(jù)類型:在內(nèi)存中翼闹,存放在棧中的簡(jiǎn)單數(shù)據(jù)段斑鼻,它們直接存儲(chǔ)在變量訪問的位置。按照值來操作對(duì)象數(shù)據(jù)類型:在內(nèi)存中猎荠,存放在堆中的對(duì)象坚弱,存儲(chǔ)在變量處的值是一個(gè)指針,指向存儲(chǔ)對(duì)象的內(nèi)存處关摇。按照地址來操作
[if !supportLists]四荒叶、[endif]創(chuàng)建對(duì)象-New模式
JavaScript有一個(gè)內(nèi)置對(duì)象Object,利用它可以創(chuàng)建一個(gè)空白的對(duì)象:
var myNewObject = new Object();
這樣就得到了一個(gè)嶄新的對(duì)象myNewObject输虱,這時(shí)它還沒有任何屬性和方法些楣,因此沒有任何實(shí)際功能。我們可以使用點(diǎn)方式添加屬性:
myNewObject.info = 'I am a shiny object';
[if !supportLists]五宪睹、[endif]創(chuàng)建對(duì)象-對(duì)象字面量模式
早期的JS開發(fā)人員經(jīng)常使用new Object()方式創(chuàng)建新對(duì)象愁茁,現(xiàn)在,對(duì)象字面量成為創(chuàng)建新對(duì)象的首選方式亭病。上面的例子用對(duì)象字面量語法可以寫成這樣:
<script>????var person = {????????name: "小明",????????age: 18,????????job: "前端工程師",????????say: function () {????????????console.log('我是:' + this.name + ',年齡:' + this.age);????????}????};????console.log(person.age);????console.log(person['name']);????person.say();</script>
[if !supportLists]六鹅很、[endif]創(chuàng)建對(duì)象-工廠模式
使用Object構(gòu)造函數(shù)或?qū)ο笞置媪縿?chuàng)建對(duì)象的缺點(diǎn):使用同一個(gè)接口創(chuàng)建很多對(duì)象,會(huì)產(chǎn)生大量的重復(fù)代碼罪帖。為解決這個(gè)問題促煮,人們開始使用工廠模式的一種變體邮屁。
<script>????let p1 = {????????name: '張三',????????age: 18,????};????let p2 = {????????name: '李四',????????age: 26,????};</script>
工廠模式是軟件工程領(lǐng)域一種廣為人知的設(shè)計(jì)模式,這種模式抽象了創(chuàng)建具體對(duì)象的過程菠齿∮恿撸考慮ES5中無法創(chuàng)建類,開發(fā)人員就發(fā)明了一種函數(shù)绳匀,用函數(shù)來封裝以特定接口創(chuàng)建對(duì)象的細(xì)節(jié)迹蛤,如下面的例子所示:
<script>????function createPerson(name, age,job) {????????let obj = {};????????obj.name = name;????????obj.age = age;????????obj.job = job;????????obj.sayName = function () {????????????console.log(this.name);????????};????????return obj;????}????let p1 = createPerson('zhangsan', 29, "WEB"); // 第一個(gè)實(shí)例????let p2 = createPerson('lisi', 27,'UI'); // 第二個(gè)實(shí)例????p1.sayName();????p2.sayName();????console.log(p1.sayName === p2.sayName); ?// false</script>
工廠模式解決了代碼重復(fù)問題,弊端1:看不出對(duì)象的類型(都是Object類型)襟士,比如 new Date() 為日期Date類型弊端2:函數(shù)重復(fù)盗飒,浪費(fèi)資源,比如console.log(p1.say === p2.say); ?// false
[if !supportLists]七陋桂、[endif]創(chuàng)建對(duì)象-構(gòu)造函數(shù)模式
如果只需要某個(gè)對(duì)象的一個(gè)實(shí)例逆趣,使用直接創(chuàng)建對(duì)象實(shí)例的方法還算不錯(cuò)。但如果要?jiǎng)?chuàng)建同一個(gè)對(duì)象的多個(gè)實(shí)例嗜历,使用這種方式就要反復(fù)重復(fù)整個(gè)過程:創(chuàng)建對(duì)象宣渗、添加屬性、定義方法等梨州。
如果要?jiǎng)?chuàng)建可能具有多個(gè)實(shí)例的對(duì)象痕囱,更好的方式是“對(duì)象構(gòu)造函數(shù)”。它會(huì)創(chuàng)建某種模板暴匠,方便實(shí)現(xiàn)多次實(shí)例化鞍恢。
在把對(duì)象實(shí)例化時(shí),還可以通過給構(gòu)造函數(shù)傳遞一個(gè)或多個(gè)參數(shù)來定制對(duì)象每窖。
<script>????function Person(personname, personage, personjob) {????????this.name = personname;????????this.age = personage;????????this.job = personjob;????????this.sayName = function () {????????????console.log(this.name);????????}????}????var person1 = new Person('zhangsan', 29, "WEB");????var person2 = new Person('lisi', 27, 'UI');????person1.sayName();????person2.sayName();</script>
[if !supportLists]八帮掉、[endif]創(chuàng)建對(duì)象-原型模式
[if !supportLists]1.[endif]prototype
我們創(chuàng)建的每個(gè)函數(shù)都有一個(gè)prototype(原型)屬性,這個(gè)屬性是一個(gè)指針窒典,指向一個(gè)對(duì)象蟆炊,這個(gè)對(duì)象的用途是包含所有實(shí)例共享的屬性和方法。使用原型的好處是可以讓所有對(duì)象實(shí)例共享它所包含的屬性和方法瀑志。換句話說涩搓,不必在構(gòu)造函數(shù)中定義對(duì)象實(shí)例的信息,而是可以將這些信息直接添加到原型對(duì)象中:
<script>????function Person() {????}????Person.prototype.name = 'zhangsan';????Person.prototype.age = 28;????Person.prototype.job = 'Full Stack Developer';????Person.prototype.sayName = function () {????????console.log(this.name);????}????var person1 = new Person();????person1.sayName(); // zhangsan????var person2 = new Person();????person2.sayName(); // zhangsan????console.log(person1.sayName === person2.sayName); // true</script>
[if !supportLists]2.[endif]constructor
無論什么時(shí)候劈猪,只要?jiǎng)?chuàng)建了一個(gè)新函數(shù)昧甘,就會(huì)根據(jù)一組特定的規(guī)則為該函數(shù)創(chuàng)建一個(gè)prototype屬性,這個(gè)屬性指向函數(shù)的原型對(duì)象岸霹。在默認(rèn)情況下疾层,所有的原型對(duì)象都會(huì)自動(dòng)獲得一個(gè)constructor(構(gòu)造函數(shù))屬性,這個(gè)屬性是一個(gè)指向prototype屬性所在函數(shù)的指針贡避。
[if !supportLists]3.[endif]__proto__
Firefox痛黎、Safari和Chrome在每個(gè)對(duì)象上都支持一個(gè)屬性__proto__予弧;每個(gè)實(shí)例對(duì)象包含一個(gè)__proto__屬性,該屬性僅僅指向了Person.prototype湖饱;
[if !supportLists]4.[endif]instanceof
前面提到過掖蛤,在默認(rèn)情況下,所有的原型對(duì)象最初都只包含constructor(構(gòu)造函數(shù))屬性井厌,而該屬性也是共享的蚓庭,因此可以通過對(duì)象實(shí)例訪問。
console.log(person1.constructor === Person.prototype.constructor); // true
提到檢測(cè)對(duì)象類型仅仆,還是instanceof操作符要更可靠一些器赞。
[if !supportLists]九、[endif]創(chuàng)建對(duì)象-組合模式
創(chuàng)建自定義類型的最常見方式墓拜,就是組合使用構(gòu)造函數(shù)模式與原型模式港柜。構(gòu)造函數(shù)模式用于定義實(shí)例屬性,而原型模式用于定義共享的屬性和方法咳榜。結(jié)果夏醉,每個(gè)實(shí)例都會(huì)有自己的一份實(shí)例屬性的副本,但同時(shí)又共享著對(duì)方法的引用涌韩,最大限度地節(jié)省了內(nèi)存畔柔。另外,這種混成模式還支持向構(gòu)造函數(shù)傳遞參數(shù)臣樱;可謂是集兩種模式之長靶擦。
[if !supportLists]十、[endif]繼承
繼承是OO語言中的一個(gè)最為人津津樂道的概念擎淤。許多OO 語言都支持兩種繼承方式:接口繼承和實(shí)現(xiàn)繼承奢啥。接口繼承只繼承方法簽名秸仙,而實(shí)現(xiàn)繼承則繼承實(shí)際的方法嘴拢。如前所述,由于函數(shù)沒有簽名寂纪,在ECMAScript中無法實(shí)現(xiàn)接口繼承席吴。ECMAScript 只支持實(shí)現(xiàn)繼承,而且其實(shí)現(xiàn)繼承主要是依靠原型鏈來實(shí)現(xiàn)的捞蛋。
[if !supportLists]1.[endif]原型鏈繼承
ECMAScript中描述了原型鏈的概念孝冒,并將原型鏈作為實(shí)現(xiàn)繼承的主要方法。其基本思想是利用原型讓一個(gè)引用類型繼承另一個(gè)引用類型的屬性和方法拟杉。原型鏈繼承示例:
<script>????function Person() {????????this.country = "China";????}????Person.prototype.getCountry = function () {????????return "I love " + this.country;????}????function njPerson() {????????this.city = "NanJing";????}????// 繼承了?Person????njPerson.prototype = new Person();????njPerson.prototype.getCity = function () {????????return "I love " + this.city;????}????var njPerson1 = new njPerson();????console.log(njPerson1.city); // NanJing????console.log(njPerson1.getCity()); // I love NanJing????console.log(njPerson1.country); // China????console.log(njPerson1.getCountry()); // I love China</script>
[if !supportLists]2.[endif]借用構(gòu)造函數(shù)
在解決原型中包含引用類型值所帶來問題的過程中庄涡,開發(fā)人員開始使用一種叫做借用構(gòu)造函數(shù)(constructor stealing)的技術(shù)(有時(shí)候也叫做偽造對(duì)象或經(jīng)典繼承)。這種技術(shù)的基本思想相當(dāng)簡(jiǎn)單搬设,即在子類型構(gòu)造函數(shù)的內(nèi)部調(diào)用超類型構(gòu)造函數(shù)穴店。如下所示:
<script>????function SuperType() {????????this.colors = ["red", "blue", "green"];????}????function SubType() {????????// 繼承了?SuperType????????SuperType.call(this);????}????var instancel = new SubType();????instancel.colors.push("black");????console.log(instancel.colors); // ["red", "blue", "green", "black"]????var instance2 = new SubType();????console.log(instance2.colors); // ["red", "blue", "green"]</script>
借用構(gòu)造函數(shù)的問題
如果僅僅是借用構(gòu)造函數(shù)撕捍,那么也將無法避免構(gòu)造函數(shù)模式存在的問題——方法都在構(gòu)造函數(shù)中定義涯呻,因此函數(shù)復(fù)用就無從談起了玷坠∶嵬停考慮到這些問題轨香,借用構(gòu)造函數(shù)的技術(shù)也是很少單獨(dú)使用的咽笼。
[if !supportLists]3.[endif]組合繼承
組合繼承(combination inheritance)来颤,有時(shí)候也叫做偽經(jīng)典繼承杨名,指的是將原型鏈和借用構(gòu)造函數(shù)的技術(shù)組合到一塊雁刷,從而發(fā)揮二者之長的一種繼承模式呕诉。其背后的思路是使用原型鏈實(shí)現(xiàn)對(duì)原型屬性和方法的繼承缘厢,而通過借用構(gòu)造函數(shù)來實(shí)現(xiàn)對(duì)實(shí)例屬性的繼承。這樣甩挫,既通過在原型上定義方法實(shí)現(xiàn)了函數(shù)復(fù)用昧绣,又能夠保證每個(gè)實(shí)例都有它自己的屬性。