簡介
ECMAScript是JavaScript的標(biāo)準(zhǔn),JavaScript實(shí)現(xiàn)了ECMAScript选泻,ECMAScript規(guī)范了JavaScript。
JavaScript體系
- 語言核心
- DOM
- BOM
JavaScript書寫位置
body里面寫script標(biāo)簽美莫,例如:
<body>
<script>
alert('hello, world');
</script>
</body>
或者
<script src=" .js" type="text/javascript" charset="utf-8"></script>
認(rèn)識輸出页眯、輸入語句
alert( ) 語句 彈窗
console.log( ) 語句 控制臺輸出
比如:
alert('haha');
alert( ) 是內(nèi)置函數(shù),函數(shù)就是功能的封裝厢呵,調(diào)用函數(shù)需要使用小括號窝撵。
'haha' 是函數(shù)的參數(shù),因?yàn)槭亲址竺砸靡柊?/p>
console.log('test');
console是js的內(nèi)置對象碌奉,通過 打點(diǎn) 可以調(diào)用它內(nèi)置的 log 方法。
所謂方法就是對象能夠調(diào)用的函數(shù)蝌矛。
var input = prompt('請輸入內(nèi)容');
輸入語句 prompt( ) 函數(shù)道批,彈出框輸入,輸入的內(nèi)容會轉(zhuǎn)為字符串類型入撒。
學(xué)會處理報(bào)錯
常見兩個錯誤:
Uncaught SyntaxError: Invalid or unexpected token
未捕獲的語法錯誤:不合法或錯誤的符號隆豹。
Uncaught ReferenceError: a is not defined
未捕獲的引用錯誤:a沒有被定義。
函數(shù)名拼寫錯誤也會引發(fā) ReferenceError茅逮。
控制臺
控制臺也是一個REPL環(huán)境璃赡,可以使用它臨時測試判哥。
REPL:read 讀 eval 執(zhí)行 print 打印 loop 循環(huán)
變量
變量能儲存計(jì)算結(jié)果 或 表示一個值;
變量不是數(shù)值本身碉考,只是儲存值的容器塌计。
定義變量
var 關(guān)鍵字, 定義變量后侯谁,就可以使用了锌仅,可以用等號賦值。如果沒有負(fù)值墙贱,默認(rèn)值為undefined热芹。可以同時聲明多個變量惨撇,用逗號隔開伊脓。
var a;
console.log(a); //此時打印undefined
a = 7;
var b,
c,
d;
變量的合法命名
變量命名可以用多種風(fēng)格,例如:
- 小駝峰命名法:首字母小寫魁衙,后面每個單詞頭字母大寫报腔。
- C風(fēng)格命名法:每個單詞用下劃線分隔。
變量命名符合JS標(biāo)識符命名規(guī)則剖淀,變量纯蛾、函數(shù)、類名祷蝌、對象的屬性等都要遵守茅撞。
標(biāo)識符命名規(guī)則
- 只能由字母帆卓、數(shù)字巨朦、下劃線、美元符號$組成剑令,不能以數(shù)字開頭糊啡。
- 不能是關(guān)鍵字或保留字,例如float等吁津。
- 變量名大小寫敏感棚蓄,例如a和A不同。
全局變量聲明提升
全局預(yù)編譯
- 生成AO對象碍脏。
- 找變量聲明梭依,將變量名作為GO的屬性名,值為undefined典尾。
- 在函數(shù)體里找函數(shù)聲明役拴。
數(shù)據(jù)類型
- 基本數(shù)據(jù)類型:number、string钾埂、boolean河闰、undefined科平、null
- 復(fù)雜數(shù)據(jù)類型:Array、function姜性、object 等...
typeof 運(yùn)算符
- 使用 typeof 運(yùn)算符可以檢測值或變量的類型瞪慧,檢測復(fù)雜類型可能會有出入。
- typeof 返回值是字符串類型的值部念。
- typeof 檢測5種基本類型的的結(jié)果弃酌,除了null會返回object外,其他同名儡炼。
- typeof 可接未定義的變量不會報(bào)錯矢腻。
基本數(shù)據(jù)類型
number 數(shù)字類型
所有數(shù)字不分大小、不分整數(shù)小數(shù)射赛、不分正負(fù)多柑,都是數(shù)字類型。
零點(diǎn)幾的0可以省略楣责。
科學(xué)計(jì)數(shù)法:3e7 => 3*10?竣灌。
不同進(jìn)制的數(shù)字
二進(jìn)制數(shù)值以 0b 開頭:0b10 => 2;
八進(jìn)制數(shù)值以 0 開頭:017 => 15;
十六進(jìn)制數(shù)值以 0x 開頭秆麸。
一個特殊的數(shù)字類型值NaN
- not a number 初嘹,不是一個數(shù),但它是一個數(shù)值類型的值沮趣。
- 0除以0的結(jié)果是 NaN 屯烦;運(yùn)算結(jié)果不是數(shù)字的數(shù)學(xué)運(yùn)算,返回值都是NaN房铭。任何涉及NaN的運(yùn)算都返回NaN驻龟。
- NaN 不自等,即 NaN == NaN; 返回 false缸匪。
- 用isNaN( ) 函數(shù)可以用來判斷變量值是否為NaN翁狐,返回值是boolean布爾值,函數(shù)里的參數(shù)也會隱式轉(zhuǎn)換為數(shù)字類型凌蔬,所以判斷不了undefined露懒。
一個特殊的數(shù)字類型值Infinity
- Infinity 也是數(shù)值類型的的值,正數(shù)除以0得Infinite砂心,負(fù)數(shù)除以0得-Infinity懈词。
string 字符串類型
- 字符串要用引號包裹,雙引號或者單引號均可辩诞。
- 加號可以用來拼接多個字符串(拼串兒)旅掂。
- 直接書寫閉合的引號可得到空串搀菩。
字符串的length屬性:表示字符串的長度横腿。
字符串的常用方法:
方法名 | 功能 |
---|---|
charAt( ) | 得到指定位置字符 |
substring( ) | 提取子串 |
substr | 提取子串 |
slice | 提取子串 |
toUpperCase | 將字符串變?yōu)榇髮?/td> |
toLowerCase | 將字符串變?yōu)樾?/td> |
indexOf | 檢索字符串 |
charAt( )方法
- 可以得到指定位置的字符屎媳,比如:
'abcdef'.charAt(0)
返回a。 - 得到指定位置字符串還可以用方括號方法,例如:
'abcdef'[3]
返回d。就是直接讀取可遍歷對象方括號里寫索引。 - charCodeAt() 返回相應(yīng)索引號的字符ASCII值
substring( )方法
sub 子衰抑,string字符串。
substring(a,b) 得到從 a 開始到 b 結(jié)束(不包括 b 處)的子串荧嵌。
如果省略第二個參數(shù)呛踊,返回的子串會一直到字符串的結(jié)尾。
參數(shù)會自動從小排到大啦撮,比如 (5,3) 會自動變?yōu)?(3,5)谭网。(慎用,可讀性差)
substr( )方法
substr(a,b) 得到從a開始的長度為b的子串赃春。
a可以是負(fù)數(shù)愉择,表示倒數(shù)位置。b不能是負(fù)數(shù)织中,否則會返回空串锥涕。
slice( )方法
slice(a,b) 得到從a開始到b結(jié)束(不包括b處)的子串。
a 可以是負(fù)數(shù)狭吼,表示倒數(shù)层坠,倒數(shù)的下標(biāo)從-1開始。
參數(shù) a 必須小于參數(shù) b刁笙。
toUpperCase( )轉(zhuǎn)為大寫破花,toLowerCase( )轉(zhuǎn)為小寫
indexOf( )方法
返回某個指定的字符串值再字符串中首次出現(xiàn)的位置(索引值)。
如果要檢索的字符串沒有出現(xiàn)疲吸,則返回-1座每。
傳入的參數(shù)是字符串,例如'abcdef'.indexOf('de')
返回3磅氨。
此方法還可以傳入第二個參數(shù)尺栖,代表開始檢索嫡纠、搜索的索引位置烦租。
boolean 布爾類型
小知識:布爾(Boole.George)英國19世紀(jì)數(shù)學(xué)家及邏輯學(xué)家。
布爾類型 值只有兩個:true 和 false 除盏,分別表示真假叉橱。
undefined 類型
undefinded 又是值,又是一種類型者蠕。
undefined 是全局對象上的一個屬性窃祝,window.undefined
不可寫 writable: false,比如window.undefined = 1
無效踱侣。
不可配置 configurable: false粪小,比如delete window.undefined
無效大磺。
不可枚舉 enumerable: flase ,比如
for(var k in window){
if(k === undefined){
console.log(k);
}
}
不打印內(nèi)容
不可重新定義 cannot redefine property: undefined;
系統(tǒng)會給一個未賦值的變量自動賦值為undefined探膊,類型也是undefined 杠愧。
函數(shù)內(nèi)部不寫返回值的時候,返回的也是一個undefined逞壁。
在函數(shù)內(nèi)部可以把undefined當(dāng)作一個變量名來用流济,但盡量別用。例如:
function test(){
var undefined = 1;
console.log(undefined);
}
test();
會打印1
void(0) 會返回undefined
null
null是基本數(shù)據(jù)類型的值腌闯,typeof返回類型是object绳瘟。
代表空、空對象姿骏。
可用于對象銷毀糖声,數(shù)組銷毀,事件清空分瘦。
顯式類型轉(zhuǎn)換
其他類型 轉(zhuǎn) 數(shù)字
- 使用 Number( ) 函數(shù)
字符串 → 數(shù)字:純數(shù)字字符串能變?yōu)閿?shù)字姨丈,不是純數(shù)字的轉(zhuǎn)為NaN,空串轉(zhuǎn)為0.
布爾值 → 數(shù)字:true轉(zhuǎn)為1擅腰,false轉(zhuǎn)為0.
undefined → 數(shù)字:undefined轉(zhuǎn)為NaN蟋恬。
null → 數(shù)字:null轉(zhuǎn)為0。 - 使用 parseInt( ) 函數(shù)趁冈。
用在字符串上時:將自動截?cái)嗟谝粋€非數(shù)字字符之后的所有字符歼争,點(diǎn)也算,不會四舍五入渗勘。 - 使用 parseFloat( ) 函數(shù)沐绒。
將字符串轉(zhuǎn)為浮點(diǎn)數(shù),只會識別到第一個點(diǎn)旺坠。
其他類型 轉(zhuǎn) 字符串
- 使用 String( ) 函數(shù)乔遮,變?yōu)殚L得相同的字符串。
- 使用 toString( ) 方法取刃,數(shù)字使用 toString 要加括號蹋肮,例如
(7).toString();
其他類型 轉(zhuǎn) 布爾值
使用 Boolean( ) 函數(shù)。
數(shù)字→布爾:除了0和NaN是false璧疗,其他true坯辩。
字符串→布爾:空窗false,其他true崩侠。
undefined和null:轉(zhuǎn)成布爾值都是false漆魔。
表達(dá)式 和 運(yùn)算符 和 隱式類型轉(zhuǎn)換
表達(dá)式
表達(dá)式,由運(yùn)算元和運(yùn)算符構(gòu)成,并產(chǎn)生運(yùn)算結(jié)果的語法結(jié)構(gòu)改抡。
表達(dá)式的種類有:算術(shù)矢炼、關(guān)系、邏輯阿纤、賦值裸删、綜合。
算術(shù)運(yùn)算符
符號 | 功能 |
---|---|
+ | 加法阵赠、正數(shù)涯塔、連字符 |
- | 減法、負(fù)數(shù) |
* | 乘法 |
/ | 除法 |
% | 取余 |
取余清蚀,也叫求模運(yùn)算匕荸,用百分號 % 表示,小數(shù)模大數(shù)得小數(shù)枷邪。
乘除余運(yùn)算優(yōu)先級高于加減運(yùn)算榛搔。
算術(shù)運(yùn)算符的隱式類型轉(zhuǎn)換
如果參與數(shù)學(xué)運(yùn)算的值不是數(shù)值型,會自動轉(zhuǎn)換為數(shù)值型然后運(yùn)算东揣,加號例外因?yàn)橛衅创δ芗蟆F浔举|(zhì)是內(nèi)部調(diào)用 Number( ) 函數(shù),例如:
true + true嘶卧;
//Number(true) + Number(true) 然后返回一個2
+'1' //會返回一個數(shù)字1
3*'2天' //會返回NaN
算術(shù)運(yùn)算符中浮點(diǎn)運(yùn)算問題IEEE754
在JavaScript中尔觉,有些浮點(diǎn)運(yùn)算不是很精準(zhǔn),因?yàn)椴捎玫氖荌EEE754二進(jìn)制浮點(diǎn)數(shù)算術(shù)標(biāo)準(zhǔn)芥吟,會產(chǎn)生“精度丟失”問題侦铜。
解決方法:可以用數(shù)字的 toFixed() 方法保留指定的小數(shù)位數(shù),類型會變成字符串钟鸵。例如:
(3.141592654).toFixed(2)
其他運(yùn)算的Math方法
-
冪和開根:
冪和開根沒有運(yùn)算符钉稍,需調(diào)用Math對象的方法實(shí)現(xiàn)。
冪:Math.pow(底數(shù),次方數(shù));
開方:Math.sqrt(開根數(shù));
-
向上取整和向下取整:(相對數(shù)軸而言)
向上取整:Math.ceil(取整的數(shù));
向下取整:Math.floor(取整的數(shù));
-
隨機(jī)數(shù):
Math.random( );
得到0到1的隨機(jī)小數(shù)棺耍。(大于等于0小于1)
想得到[a,b]區(qū)間的整數(shù)贡未,公式為:
parseInt(Math.random()*(b-a+1))+a;
封裝成函數(shù)就是
function getRandom(min,max){
return parseInt(Math.random()*(max-min+1))+min;
}
-
絕對值:
Math.abs();
關(guān)系運(yùn)算符
符號 | 意義 |
---|---|
> | 大于 |
< | 小于 |
>= | 大于或等于 |
<= | 小于或等于 |
== | 等于 |
!= | 不等于 |
=== | 全等于 |
!== | 不全等于 |
進(jìn)行關(guān)系運(yùn)算符運(yùn)算候的結(jié)果返回值是boolean布爾值。
除了全等和不全等以外蒙袍,其他關(guān)系運(yùn)算符都會隱式轉(zhuǎn)換兩邊值為數(shù)字類型俊卤。
例如:
1 == '1'; //返回true
undefined == null; //這是個例外,undefined轉(zhuǎn)數(shù)字是NaN的左敌,但返回true
undefined === null; //返回false
NaN == NaN; //返回false瘾蛋,NaN不自等,所以要用isNaN( ) 函數(shù)判斷
沒有數(shù)學(xué)書寫上的連比3<=16<=15
矫限,要連比只能用邏輯運(yùn)算符
邏輯運(yùn)算符
符號 | 意義 |
---|---|
! | 非 |
&& | 與 |
|| | 或 |
! 非
- 也可以稱為“置反運(yùn)算”。
- 是一個“單目操作符”,只需要一個操作數(shù)叼风。
- 置反運(yùn)算的結(jié)果一定是布爾值取董,要置放的值會先隱式轉(zhuǎn)換為布爾值。所以用雙非
!!
可以用來隱式轉(zhuǎn)換一個值為布爾值无宿。
&& 與運(yùn)算
找假返回假茵汰,如果沒有假則返回最后一個真。(都真就真)
|| 或運(yùn)算
找真返回真孽鸡,如果沒有真則返回最后一個假蹂午。(有真就真)
邏輯運(yùn)算符優(yōu)先級:非>與>或
賦值表達(dá)式
賦值運(yùn)算符
符號 | 意義 |
---|---|
= | 賦值 |
+= | 快速賦值 |
-= | 快速賦值 |
*= | 快速賦值 |
/= | 快速賦值 |
%= | 快速賦值 |
++ | 自增運(yùn)算 |
-- | 自減運(yùn)算 |
賦值運(yùn)算也會產(chǎn)生值,例如:
var a;
console.log(a=7);
//a=7會返回7彬碱,所以會打印7而不是a=7豆胸。
所以可以連續(xù)使用賦值運(yùn)算(實(shí)際開發(fā)禁止使用),例如:
var a,b,c;
a=b=c=7;
//先c=7返回7巷疼,再b=c=77晚胡,再a=b=c=77
快速賦值:+= 、-= 嚼沿、*= 估盘、 /= 、%=
在原數(shù)值基礎(chǔ)上進(jìn)一步運(yùn)算骡尽。
自增自減:++遣妥、--
自身基礎(chǔ)上加一或減一。
a++和++a區(qū)別:a++先用再加攀细,++a先加再用燥透。例如:
var n1=1,n2=2;
var n3 = (n1++)+n2
//此時n3等于3
綜合表達(dá)式
綜合運(yùn)算順序:非運(yùn)算>數(shù)學(xué)運(yùn)算>關(guān)系運(yùn)算>邏輯運(yùn)算 (非數(shù)關(guān)邏)
流程控制語句
條件語句:if、if elseif else辨图、switch班套、三元運(yùn)算符。
循環(huán)語句:for故河、while吱韭、break和continue、do while鱼的。
條件語句
if語句
if(條件){
語句塊1理盆,當(dāng)條件為真時執(zhí)行
}else{
語句塊2,當(dāng)條件為假時執(zhí)行
}
if語句執(zhí)行流程圖
graph TD
A[程序執(zhí)行] -->| | B(執(zhí)行)
B --> C{測試條件}
C -->|條件1| D[語句塊1]
C -->|條件2| E[語句塊2]
- if語句中的else可以省略
- 如果if語句體中只有一行語句凑阶,可以省略大括號和換行猿规,且結(jié)尾加分號
else if 否則如果
else if( ) 條件分支“暗含”不符合之前的所有條件。
if( 測試表達(dá)式1){
當(dāng)測試表達(dá)式1為true時執(zhí)行
}else if(測試表達(dá)式2){
當(dāng)測試表達(dá)式2為true時執(zhí)行
}else{
所有表達(dá)式為false時執(zhí)行
}
if 語句算法題
第一題: 判斷水仙花數(shù)宙橱。
如何拆位姨俩?
- 數(shù)學(xué)方法:百位是原數(shù)值除以100取整蘸拔。十位是原數(shù)字除以10取整,再與10求模环葵。個位是原數(shù)字與10求模
- 字符串方法:直接將原數(shù)字變?yōu)樽址髑希缓笫褂胏harAt( )方法。
第二題: 游樂園門票計(jì)算张遭。
年齡大于等于10 | 年齡小于10歲 | |
---|---|---|
平日 | 300 | 140 |
周末 | 500 | 210 |
switch 語句
用途:當(dāng)一個變量被分類討論的情形邓萨。
- switch( ) 括號內(nèi)一般是一個變量名,這個變量被分類討論菊卷。
- case表示情況缔恳,后面直接跟一個值,程序會將這個值依次與switch括號內(nèi)的變量匹配洁闰,如果全等歉甚,則執(zhí)行case后的語句,多條case可以共用一個語句體渴庆。
- default 表示默認(rèn)情況铃芦。
- break 跳出switch語句。
三元運(yùn)算符
條件表達(dá)式 ? 表達(dá)式1 : 表達(dá)式2
當(dāng)條件為真執(zhí)行1襟雷,為假執(zhí)行2刃滓。
循環(huán)語句
for 循環(huán)語句
for的小括號有三個表達(dá)式:
表達(dá)式1:for循環(huán)內(nèi)可用的變量,循環(huán)變量一般定為i耸弄,意為iterator迭代器咧虎。
表達(dá)式2:只要這條返回true,就會繼續(xù)執(zhí)行后面的語句塊计呈。
表達(dá)式3:一般用來更新循環(huán)變量砰诵。
for循環(huán)執(zhí)行機(jī)理:
for(var i=1①; i<=10②; i++④){
console.log(i)③;
}
//①→②→③→④
也就是說,for循環(huán)小括號內(nèi)的第三條語句捌显,是先執(zhí)行中括號內(nèi)的語句塊茁彭,再執(zhí)行的。
for循環(huán)算法題
- 累加器
- 1到100哪個數(shù)除3余1扶歪,除4余2理肺,除5余3.(窮舉法)
while 循環(huán)語句
是一種“不定范圍”循環(huán)。先不指定循環(huán)開始和結(jié)束范圍善镰。只要滿足測試條件妹萨,就一直執(zhí)行循環(huán)體。
while(測試條件){
循環(huán)執(zhí)行的語句塊;
}
循環(huán)注意: 當(dāng)循環(huán)條件終止值與更新的循環(huán)體內(nèi)的值不是同一個時炫欺,當(dāng)要求的值是循環(huán)值時乎完,注意“出一錯誤”
循環(huán)語句中的break和continue
執(zhí)行 break; 會立即終止循環(huán)。
執(zhí)行 continue; 會跳過循環(huán)中的一個迭代品洛,跳過其中一次循環(huán)树姨,這一次循環(huán)體內(nèi)的continue后面的其他語句將跳過執(zhí)行一次摩桶。
do while 循環(huán)
先執(zhí)行一次循環(huán)體或杠,再判斷測試條件是否滿足以清。
do{
循環(huán)執(zhí)行的語句塊(會先執(zhí)行一次);
}while(循環(huán)執(zhí)行條件)
while循環(huán)算法題 猜數(shù)字
流程語句經(jīng)典算法題
可以先用偽代碼寫下解決思路,再翻譯成js語法。
累加器與累乘器
- 計(jì)算 3/2 + 4/3 + 5/4 + 6/5 + ...... + (n+1)/n 的結(jié)果
- 由用戶輸入數(shù)字n台丛,計(jì)算n的階乘。
for(var i=n; i>=1; i--){result*=i;}
result要從1開始- 圓周率可以由萊布尼茨級數(shù)公式計(jì)算砾肺,用戶輸入n挽霉,計(jì)算圓周率Π。
Π/2= 1 + 1/3 + 1*2/3*5 + 1*2*3/3*5*7 + 1*2*...n/3*5*...(2n-1)
窮舉法
- 100以內(nèi)变汪,能整除3也能整除5的數(shù)侠坎。
- 輸入一個數(shù),在控制臺顯示這個數(shù)的全部約數(shù)裙盾。
- 尋找全部水仙花數(shù)实胸。(每個數(shù)位的立方和等于它本身)。
綜合算法題
- 尋找100以內(nèi)的質(zhì)數(shù)番官。(用到給外層for循環(huán)套label庐完,然后用continue label)
- 雞兔同籠,35頭徘熔,94足门躯。
數(shù)組
Array ,存儲一組值酷师。
如何定義數(shù)組
- 使用方括號:
var arr = ['A','B','C'];
- 使用 new Array 構(gòu)造函數(shù):
var arr = new Array('A','B','C');
當(dāng)new Array函數(shù)只傳入一個數(shù)字時讶凉,則定義一個長度為n的數(shù)組。
數(shù)組的每一項(xiàng)都有下標(biāo)山孔,下標(biāo)從0開始懂讯。
使用 數(shù)組變量 接方括號中寫下標(biāo) 的形式,可訪問數(shù)組項(xiàng)台颠,例如:a[0];
當(dāng)下標(biāo)越界褐望,會返回undefined而不會報(bào)錯。
數(shù)組的length屬性表示長度蓉媳,數(shù)組的最后一項(xiàng)的下標(biāo)時length-1
數(shù)組是可讀可寫的譬挚,如果更改的項(xiàng)下標(biāo)越界,則會創(chuàng)造這項(xiàng)酪呻。
數(shù)組的遍歷:
for (var i=0;i<arr.length; i++){
arr[i];
}
數(shù)組的不停寫入减宣,可用while循環(huán)(數(shù)組自增):
var arr = [];
while( ){
arr[arr.length]=
}
判斷是不是數(shù)組
數(shù)組用typeof 檢測結(jié)果是object,可用 Array.isArray( );
方法檢測玩荠。
數(shù)組相關(guān)遍歷算法題
- 求數(shù)組中每一項(xiàng)的總和漆腌、平均數(shù)贼邓。
- 求數(shù)組項(xiàng)的最大值和最小值。
數(shù)組的頭尾操作方法
方法 | 功能 |
---|---|
push( ) | 在尾部插入新項(xiàng) |
pop( ) | 在尾部刪除 |
unshift( ) | 在頭部插入 |
shift( ) | 在頭部刪除 |
push( ) 方法:推入新項(xiàng)闷尿,如果要推入多項(xiàng)塑径,用逗號隔開。
pop( ) 方法:刪除數(shù)組中的最后一項(xiàng)填具,該方法會返回被刪除的項(xiàng)统舀,可用一個變量接收。
unshift與shift特性與push劳景、pop相似誉简。以上方法均會改變原數(shù)組
數(shù)組的其他方法
會改變數(shù)組的:
方法(會改變原數(shù)組) | 功能 |
---|---|
reverse | 逆轉(zhuǎn)排序 |
splice | 切割 |
sort | 改序 |
reverse( ) 方法
用于將數(shù)組中的全部項(xiàng)順序置反。
splice( ) 方法
用于替換數(shù)組中的指定項(xiàng)盟广。用法:
arr.splice(從下標(biāo)為n的項(xiàng)開始 , 替換多少項(xiàng) , 替換的新項(xiàng)可多項(xiàng))闷串;
當(dāng)?shù)诙€參數(shù)為0時,就會變?yōu)椴迦牍δ堋?br>
當(dāng)?shù)谌齻€參數(shù)不寫時筋量,就會變?yōu)閯h除功能烹吵。
該方法會返回被刪除的項(xiàng)組成的數(shù)組。
sort( ) 方法
arr.sort( );
sort開放了接口桨武,可傳入一個函數(shù) arr.sort(function(){ });
- 必須寫兩形參肋拔!
arr.sort(function(a,b){ });
- 看返回值
1)返回值為正時,后面的數(shù)放前邊玻募。
2)返回值為負(fù)時只损,前面的數(shù)放前邊。
3)返回值為0時七咧,不做操作跃惫。
自己總結(jié)就是,正數(shù)交換位置艾栋,負(fù)數(shù)不換(正交負(fù)不換)爆存,所以:
arr.sort(function(a,b){return a-b;}) //升序
arr.sort(function(a,b){return b-a;}) //降序
arr.sort(function(a,b){return Math.random()-0.5;}) //亂序
不改變數(shù)組的方法:
方法(不改變原數(shù)組) | 作用 |
---|---|
slice( ) | 截取數(shù)組 |
concat( ) | 連接多個數(shù)組 |
數(shù)組的slice方法:
不會改變原數(shù)組,用于得到子數(shù)組蝗砾。
slice(a,b) 截取從下標(biāo)為a開始先较,到下標(biāo)為b(不包括b)結(jié)束。
如果不傳第二個參數(shù)悼粮。就會截取從a開始的后面所有項(xiàng)闲勺。參數(shù)允許為負(fù)數(shù)。
數(shù)組的concat方法: 合并連接多個數(shù)組扣猫,不改變原數(shù)組菜循。
數(shù)組與字符串間轉(zhuǎn)換的方法,以及更多通性
數(shù)組轉(zhuǎn)字符串: join( )方法申尤,將數(shù)組改變?yōu)樽址愋筒⒁詤?shù)作為連接符輸出癌幕,不傳參數(shù)默認(rèn)逗號衙耕。傳遞的參數(shù)要用引號括起來。
字符串轉(zhuǎn)數(shù)組: split( )方法勺远,以什么字符拆分字符串橙喘,參數(shù)為空時將拆為一個字符串。
更多相關(guān)性:
- 可以使用方括號寫下標(biāo)的形式訪問某個字符胶逢,等價于charAt( )方法厅瞎。
- 字符串的一些算法問題可以改為數(shù)組解決。
indexOf( ) 和 includes( )
indexOf( ) 方法:搜索數(shù)組中的元素并返回下標(biāo)數(shù)宪塔,如果不存在返回-1磁奖。
includes( ) 方法:判斷數(shù)組是否包含一個元素囊拜,返回布爾值某筐。
數(shù)組經(jīng)典算法題
冒泡排序:
for(var i=1; i<=arr.length-1;i++){
for(var j=0; j<arr.length-i; j++){
// j多功能擔(dān)任遍歷數(shù)組的下標(biāo)
if (arr[j]>arr[j+1]) {
//因?yàn)閖是訪問不到最后一位的,j<arr.length-i冠跷,j最大只能到每一趟的倒數(shù)第二位南誊。但是因?yàn)樵趇f里面比較的是[j+1]位,所以第一輪剛好能訪問到最后一位
var temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
數(shù)組去重:
思路:準(zhǔn)備一個空數(shù)組蜜托,遍歷原數(shù)組抄囚,如果遍歷到的項(xiàng)新數(shù)組里沒有(用indexOf判斷或includes判斷,后者是ES6)橄务,則push進(jìn)去幔托。
function unique(arr){
var newArr = [];
for(var i=0;i<arr.length;i++){
if(newArr.indexOf(arr[i])===-1){
newArr.push(arr[i]);
}
}
return newArr;
}
隨機(jī)樣本:
思路:準(zhǔn)備一個空數(shù)組,遍歷原數(shù)組蜂挪,隨機(jī)選擇一項(xiàng)重挑,推入新數(shù)組,并刪除這項(xiàng)棠涮。
二維數(shù)組
- 數(shù)組里的項(xiàng)是數(shù)組時谬哀,就形成了二維數(shù)組
- 二維數(shù)組可以看作是矩陣。書寫上最好寫成矩陣严肪。
- 遍歷二維數(shù)組需要2層循環(huán)史煎,n維數(shù)組則需要n層。
數(shù)組高階函數(shù)map() reduce() filter()
map方法接收一個函數(shù)作為參數(shù)驳糯,這個函數(shù)會接收三個參數(shù):參數(shù)一是這個數(shù)組里的每一項(xiàng)篇梭,參數(shù)二是每一項(xiàng)的下標(biāo)索引值,參數(shù)三是調(diào)用map方法的這個數(shù)組本身酝枢,return的是指定的值進(jìn)一個新的數(shù)組恬偷。最后map方法返回這個新的數(shù)組
var arr = [{name:'ming',age:18},{name:'he77',age:20},{name:'qi',age:24}]
var newArr = arr.map(function(item,index,arrSelf){
console.log(item,index,arrSelf)
return item.age
})
console.log(newArr) //[18,20,24]
reduce方法接收一個函數(shù)作為參數(shù)以及一個“開始計(jì)算的初始值”,這個函數(shù)會接收兩個參數(shù):參數(shù)一是上一次return的結(jié)果隧枫,參數(shù)二是這一次參與計(jì)算的數(shù)據(jù)喉磁。不斷的計(jì)算最后return一個值谓苟。最后reduce方法返回這個值
var arr = [{name:'ming',age:18},{name:'he77',age:20},{name:'qi',age:24}]
var newValue = arr.reduce(function(previous,joining){
console.log(previous,joining)
return previous+joining.age
},0)
console.log(newValue) //62
filter方法接收一個函數(shù)作為參數(shù),這個函數(shù)的參數(shù)會接受一個參數(shù)协怒,參數(shù)一是這個數(shù)組的每一項(xiàng)涝焙,return符合判斷為true的數(shù)據(jù)進(jìn)一個新數(shù)組,最后filter方法返回這個新數(shù)組孕暇。
var arr = [{name:'ming',age:18},{name:'he77',age:20},{name:'qi',age:24}]
var newArr = arr.filter((item)=>{return item.name.includes('i')})
console.log(newArr) //[{name:'ming',age:18},{name:'qi',age:24}]
引用類型和基本類型
基本類型:number仑撞、string、boolean妖滔、undefined隧哮、null
引用類型:array、object座舍、function沮翔、regexp...
相等判斷:
- 基本類型進(jìn)行相等判斷,會比較 值 是否相等曲秉。
- 引用類型進(jìn)行相等判斷采蚀,會比較 址 是否相等。
所以淺克隆中如果克隆到數(shù)組承二,并不完全克隆榆鼠,這個時候就需要深克隆。
函數(shù)
函數(shù)就是語句的封裝亥鸠,方便復(fù)用妆够,具有“一次定義,多次調(diào)用”的優(yōu)點(diǎn)负蚊。
函數(shù)的定義
使用function關(guān)鍵字神妹,function是功能的意思。例如:
function fun( ){
}
function表示定義函數(shù)盖桥。
fun 是函數(shù)名灾螃,命名規(guī)則見js標(biāo)識符命名規(guī)則。
圓括號()是形參列表揩徊,即使沒有形參腰鬼,也必須書寫圓括號。
大括號{ }是函數(shù)執(zhí)行的語句體
第二種定義函數(shù)方法是使用函數(shù)表達(dá)式:
var fun = function(){ }
調(diào)用函數(shù)
在函數(shù)名字后面書寫圓括號即可塑荒,也可以稱為函數(shù)執(zhí)行符熄赡。。
函數(shù)聲明提升
只有函數(shù)聲明能提升齿税,函數(shù)表達(dá)式不提升彼硫。提升相關(guān)詳情見GO、AO預(yù)編譯。
例題
fun();
var fun = function(){alert('a');}
function fun(){alert('b');}
fun();
//執(zhí)行這段程序拧篮,會先彈出b词渤,然后彈出a。
//所以函數(shù)只是聲明提升串绩,預(yù)編譯后不再參與變量賦值缺虐。
函數(shù)的參數(shù)
函數(shù)聲明時圓括號內(nèi)定義形參(形式參數(shù))
調(diào)用函數(shù)時傳入實(shí)參(實(shí)際參數(shù))
- 形參數(shù)量 = 實(shí)參數(shù)量 時:一一對應(yīng)。
- 形參數(shù)量 < 實(shí)參數(shù)量 時:多出的實(shí)參不傳入函數(shù)礁凡,但arguments仍可讀到高氮。
- 形參數(shù)量 > 實(shí)參數(shù)量 時:多出的形參值為undefined。
arguments
函數(shù)內(nèi)的 arguments 表示它接收到的實(shí)參列表顷牌,他是一個類數(shù)組對象剪芍。
類數(shù)組對象:
是對象,可以當(dāng)數(shù)組用窟蓝。
和數(shù)組類似可以用方括號訪問對象的屬性值罪裹,但不能調(diào)用數(shù)組的方法,可以自己寫入模擬數(shù)組方法疗锐。構(gòu)成要素:
①屬性要為索引(數(shù)字)屬性
②必須要有l(wèi)ength屬性
return 函數(shù)的返回值
使用return關(guān)鍵字坊谁。
調(diào)用一個有返回值的函數(shù),可以當(dāng)一個普通值來用滑臊。
遇見return語句會立即退出函數(shù)。(結(jié)合if語句箍铲,往往不需要寫else分支了)
return后不接內(nèi)容則函數(shù)返回undefined雇卷,接內(nèi)容則函數(shù)返回內(nèi)容。
函數(shù)算法題
尋找喇叭花數(shù)(喇叭花數(shù):三位數(shù)颠猴,每一位數(shù)字階乘的和等于他本身)
函數(shù)的遞歸
函數(shù)內(nèi)部語句調(diào)用這個函數(shù)自身关划,從而發(fā)起函數(shù)新一輪迭代,在新的迭代中又執(zhí)行調(diào)用函數(shù)自身的語句翘瓮,一直迭代下去贮折,知道函數(shù)執(zhí)行到某一次時不在迭代,然后一層一層返回资盅,則形成函數(shù)遞歸调榄。
遞歸的要素
- 邊界條件:確定遞歸何時終止,也稱遞歸出口呵扛。
①要么找到當(dāng)參數(shù)等于某個值時候函數(shù)有結(jié)果
②要么函數(shù)執(zhí)行次數(shù)有限每庆,當(dāng)循環(huán)到某一次的時候不再調(diào)用函數(shù)自身。 - 遞歸模式:大問題分小問題今穿,遞歸體缤灵。
遞歸常見算法題
斐波那契數(shù)列:每項(xiàng)等于前兩項(xiàng)的和。
function fibonacci(n){
if(n==0) return 0;
else if(n==1) return 1;
return fibonacci(n-1)+fibonacci(n-2);
}
實(shí)現(xiàn)深度克隆數(shù)組:
function arrClone(arr){
var newArr=[];
for(var i=0;i<arr.length;i++){
if(!Array.isArray(arr[i])) newArr[newArr.length]=arr[i];
else newArr[newArr.length] = arrClone(arr[i]);
}
return newArr;
}
變量作用域
JavaScript是函數(shù)及作用域編程語言:變量只在其定義時所在的 function 內(nèi)部有效,function 內(nèi)的變量成為 function 的局部變量腮出。
不見變量定義在任何函數(shù)里面帖鸦,這個變量就是全局變量,或者 function 內(nèi)不聲明變量直接賦值也是全局變量胚嘲。
遮蔽效應(yīng): 如果函數(shù)中也定義了與全局變量同名的變量富蓄,則函數(shù)內(nèi)的變量會將全局變量“遮蔽”。
js運(yùn)行三部曲
- 語法解析
- 預(yù)編譯
- 解釋執(zhí)行
會發(fā)生以下幾種情況:
函數(shù)聲明整體提升
變量聲明提升
imply global 暗示全局變量慢逾,window就是全局
預(yù)編譯發(fā)生在函數(shù)執(zhí)行前一刻立倍。
全局預(yù)編譯創(chuàng)建GO對象。
局部預(yù)編譯先創(chuàng)建AO對象侣滩,再逐步執(zhí)行(部分執(zhí)行)口注。
全局預(yù)編譯三部曲
- 生成GO對象。
- 找變量聲明君珠,將變量名作為GO屬性名寝志,值為undefined。
- 在函數(shù)體里面找函數(shù)聲明。
局部預(yù)編譯四部曲
- 生成AO對象(activation object)
AO{ } - 找形參和變量聲明,將變量和形參名作為AO屬性名疼电,值為undefined谴麦。
AO{
a: undefined;
b: undefined
}
- 將實(shí)參值與形參統(tǒng)一。
AO{
a: 1;
b: undefined
}
- 再函數(shù)體里找函數(shù)聲明膜毁。
AO{
a: function a(){ };
b: undefined;
d: function d(){ }
}
閉包
JavaScript的函數(shù)會產(chǎn)生閉包(closure)。閉包是函數(shù)本身和該函數(shù)聲明時所處的環(huán)境狀態(tài)的組合物臂。
函數(shù)能夠“記憶住”其定義時所處的環(huán)境,即使函數(shù)不在其定義的環(huán)境被調(diào)用产上,也能訪問定義時所處環(huán)境的變量棵磷。
在Javascript中,每次創(chuàng)建函數(shù)時都會創(chuàng)建閉包晋涣。
但是仪媒,閉包特性往往需要將函數(shù)“換一個地方”執(zhí)行,才能被觀察出來谢鹊。
閉包非常實(shí)用算吩,它允許我們將數(shù)據(jù)與操作該數(shù)據(jù)的函數(shù)關(guān)聯(lián)起來。
用途:
- 記憶性:當(dāng)閉包產(chǎn)生時撇贺,函數(shù)所處環(huán)境的狀態(tài)會始終保持在內(nèi)存中赌莺,不會在外層函數(shù)調(diào)用后自動清除。
- 模擬私有變量松嘶。
壞處:
濫用閉包會造成內(nèi)存泄漏艘狭,引發(fā)性能問題。
立即執(zhí)行函數(shù) IIFE
IIFE全稱:Immediately Invoked Function Expression,立即調(diào)用函數(shù)表達(dá)式巢音,一被定義就立即被調(diào)用遵倦。
IIFE形成方法
只有表達(dá)式才能被執(zhí)行符號(圓括號)執(zhí)行。
表達(dá)式:由運(yùn)算元和運(yùn)算符構(gòu)成官撼,并產(chǎn)生運(yùn)算結(jié)果的語句結(jié)構(gòu)
能被執(zhí)行符號執(zhí)行的表達(dá)式會忽略這個函數(shù)的名字梧躺,所以立即執(zhí)行函數(shù)寫函數(shù)名會被忽略。
IIFE作用
- 為變量賦值傲绣,例如一個值需要經(jīng)過一段流程控制語句后才產(chǎn)生掠哥,那么就可以把這堆流程控制語句封裝成函數(shù)并立即執(zhí)行然后返回值。
- 將全局變量變?yōu)榫植孔兞浚ㄗ孖IFE里面的函數(shù)立即形成一個新的閉包)秃诵。
DOM
DOM是 Document Object Model 文檔對下個模型续搀,是Javascript操作HTML文檔的接口。
DOM 節(jié)點(diǎn)樹
節(jié)點(diǎn)的四個屬性
屬性名 | 作用 |
---|---|
nodeName | 元素的標(biāo)簽名菠净,以大寫形式表示禁舷,只讀 |
nodeValue | Text節(jié)點(diǎn)或Comment節(jié)點(diǎn)的文本內(nèi)容,可讀可寫 |
nodeType | 該節(jié)點(diǎn)類型毅往,見下表 |
attributes | Element節(jié)點(diǎn)的屬性集合 |
nodeType 常用屬性值
值 | 屬性 |
---|---|
1 | 元素節(jié)點(diǎn)牵咙,例如<p>和<div> |
3 | 文字節(jié)點(diǎn) |
8 | 注釋節(jié)點(diǎn) |
9 | document節(jié)點(diǎn) |
10 | DTD節(jié)點(diǎn) |
延遲運(yùn)行
- 在測試DOM代碼時,通常JS代碼要寫在HTML節(jié)點(diǎn)后面攀唯,否則JS無法找到相應(yīng)HTML節(jié)點(diǎn)洁桌。
- 可以使用
window.onload = function(){ }
或者document.addEventListener( 'DOMContentloaded',function(){ },false);
使頁面加載完畢后,在執(zhí)行指定的代碼革答,推薦第二種
訪問元素節(jié)點(diǎn)
尋找/遍歷/訪問主要依靠document對象战坤。
幾乎所有DOM的功能都封裝在 document對象中。
document 對象也表示整個HTML文檔残拐,是DOM節(jié)點(diǎn)樹的根
常用方法有:
方法 | 功能 |
---|---|
document.getElementById( ) | 通過ID得到元素 |
document.getElementsByTagName( ) | 通過標(biāo)簽名得到元素?cái)?shù)組 |
document.getElementsByClassName( ) | 通過類名得到元素?cái)?shù)組 |
document.getElementsByName( ) | 只有部分標(biāo)簽name可生效 |
document.querySelector( ) | 通過選擇器得到元素 |
document.querySelectorAll( ) | 通過選擇器得到元素?cái)?shù)組 |
document.getElementById( )
當(dāng)html元素有id屬性的時候,可以用id獲取該元素節(jié)點(diǎn)
注意事項(xiàng):
- 如果頁面上有相同id的元素碟嘴,則只能得到第一個溪食。
- 不管元素藏得多深,都能通過id找到
getElementsByTagName( )
通過標(biāo)簽名得到節(jié)點(diǎn)數(shù)組娜扇。
注意事項(xiàng):
- 數(shù)組方便遍歷错沃,從而可以批量操控元素節(jié)點(diǎn)。
- 即使頁面上只有一個指定標(biāo)簽名的節(jié)點(diǎn)雀瓢,也將得到長度為1的數(shù)組枢析。
- 任何一個節(jié)點(diǎn)元素可以調(diào)用getElementsByTagName方法,比如
box1.getElementsByTagName( 'p');
, 從而得到一個元素內(nèi)部的子元素節(jié)點(diǎn)刃麸。
getElementsByClassName( )
通過類名得到節(jié)點(diǎn)數(shù)組醒叁。
注意事項(xiàng):
- 從IE9開始兼容。
- 其他同上Tag特性
querySelector( )
通過選擇器得到元素。例如:
var the_p = document.querySelector('#box1 .p')
注意事項(xiàng):
- querySelector( )方法只能得到頁面上一個元素把沼,如果有多個元素符合條件啊易,只能得到第一個元素。
- querySelector( ) 方法從IE8開始兼容饮睬,但從IE9開始支持CSS3的選擇器租谈,比如 :nth-child() 、:[src^='seven']等選擇器形式支持良好捆愁。(偽類不行)
querySelectorAll( )
通過選擇器得到元素?cái)?shù)組割去。計(jì)師頁面上只有一個符合選擇器的節(jié)點(diǎn),也將得到長度為1的數(shù)組
querySelector和querySelectorAll注意事項(xiàng): 都不是實(shí)時的昼丑,例如節(jié)點(diǎn)是后期加上的會獲取不到呻逆。
節(jié)點(diǎn)關(guān)系,節(jié)點(diǎn)之間的關(guān)系
關(guān)系 | 考慮所有節(jié)點(diǎn) | 只考慮元素節(jié)點(diǎn) |
---|---|---|
子節(jié)點(diǎn) | childNodes | children |
父節(jié)點(diǎn) | parentNode | parentElement |
第一個子節(jié)點(diǎn) | firstChild | firstElementChild |
最后一個子節(jié)點(diǎn) | lastChild | lastElementChild |
前一個兄弟節(jié)點(diǎn) | previousSibling | previousElementSibling |
后一個兄弟節(jié)點(diǎn) | nextSibling | nextElementSibling |
- DOM中矾克,文本節(jié)點(diǎn)也屬于節(jié)點(diǎn)页慷,在使用節(jié)點(diǎn)關(guān)系時一定要注意。
- 在W3C標(biāo)準(zhǔn)規(guī)范中胁附,空白文本節(jié)點(diǎn)也屬于節(jié)點(diǎn)酒繁,IE8之前不把空文本當(dāng)作節(jié)點(diǎn)。
- 可以用
父節(jié)點(diǎn).hasChildNodes( );
判斷有沒有子節(jié)點(diǎn)
封裝節(jié)點(diǎn)關(guān)系函數(shù)
//兼容IE8以下的獲取所有子元素節(jié)點(diǎn)函數(shù)控妻,類似children屬性
function getChildren(node){
var children = [];
for(var i=0; i<node.childNodes.length; i++){
if(node.childNodes[i].nodeType == 1){
children.push(node.childNodes[i]);
}
}
return children;
}
//兼容IE8以下獲取前一個兄弟元素節(jié)點(diǎn)
function getPreviousElementSibling(node){
while(node.previousSibling != null){
if (node.previousSibling.nodeType == 1) {
return node.previousSibling;
}
node = node.previousSibling;
}
}
//兼容IE8以下獲取后一個兄弟元素節(jié)點(diǎn)
function getNextElementSibling(node){
while(node.nextSibling != null){
if (node.nextSibling.nodeType == 1) {
return node.nextSibling;
}
node=node.nextSibling;
}
}
//獲取所有兄弟元素節(jié)點(diǎn)
function getAllElementSibling(node){
var o =node;
var preES = [];
var nexES = [];
while(o.previousSibling != null){
if (o.previousSibling.nodeType == 1) {
preES.unshift(o.previousSibling);
}
o = o.previousSibling;
}
o = node;
while(o.nextSibling != null){
if (o.nextSibling.nodeType == 1) {
nexES.push(o.nextSibling);
}
o = o.nextSibling;
}
return preES.concat(nexES);
}
節(jié)點(diǎn)操作
改變元素節(jié)點(diǎn)中的內(nèi)容可以使用兩個相關(guān)屬性:
- innerHTML :能以HTML語法設(shè)置節(jié)點(diǎn)中的內(nèi)容結(jié)構(gòu)州袒。
- innerText : 只能以純文本的形式設(shè)置節(jié)點(diǎn)中的內(nèi)容。寫進(jìn)去的標(biāo)簽也會變成字符串弓候。
改變元素節(jié)點(diǎn)的CSS樣式
用 元素.style.要修改的屬性 = ***;的形式郎哭,例如:
div1.style.backgroundColor = 'blue';
div1.style.backgroundImage = 'url(images/1.jpg)';
div1.style.fontSize = '32px';
注意:
- js語句不能用橫杠-書寫標(biāo)識符,所以用小駝峰形式書寫css屬性名菇存。
- css屬性值要設(shè)置成完整形式夸研。
- 注意寫單位,注意寫單位依鸥,注意寫單位亥至。
- 是通過CSS行內(nèi)屬性設(shè)置上的。
- 寫入值必須是字符串贱迟,必須是字符串姐扮,必須是字符串。
腳本化CSS
以上操作稱為腳本化CSS衣吠,讀寫行間樣式茶敏,如果是js保留字,前面應(yīng)該加css缚俏,例如:cssFloat
如何查詢計(jì)算樣式惊搏,可以使用:
window.getComputedStyle(元素名,null);
//第一個值傳的是需要獲取計(jì)算樣式的元素贮乳,第二個值傳入是否獲取的是偽元素。
//IE8以下用ELE.currentStyle胀屿,或者封裝計(jì)算樣式方法
function getStyle(obj, name) {
if(window.getComputedStyle) {
//正常瀏覽器的方式塘揣,具有g(shù)etComputedStyle()方法
return getComputedStyle(obj, null)[name];
} else {
//IE8的方式,沒有g(shù)etComputedStyle()方法
return obj.currentStyle[name];
}
}
改變元素的css還可以用改變類名的寫法
使用 DOMCUMENT.className += 需要樣式的類型
或者使用dom的 classList 屬性宿崭,classList是一個類數(shù)組亲铡,可以通過下標(biāo)方式取得元素的class組,該屬性有多種方法
方法名 | 功能 |
---|---|
DOMCUMENT.classList.add(class1,class2) | 在元素中添加一個或多個類名葡兑。如果指定的類名已存在奖蔓,則不會添加 |
DOMCUMENT.classList.remove(class1, class2, ...) | 移除元素中一個或多個類名。注意: 移除不存在的類名讹堤,不會報(bào)錯吆鹤。 |
DOMCUMENT.classList.toggle(class,布爾值) | 在元素中切換類名。第一個參數(shù)為要在元素中移除的類名洲守,并返回 false疑务。 如果該類名不存在則會在元素中添加類名,并返回 true梗醇。 第二個是可選參數(shù)知允,是個布爾值用于設(shè)置元素是否強(qiáng)制添加或移除類,不管該類名是否存在叙谨。 |
DOMCUMENT.classList.item(index) | 返回元素中索引值對應(yīng)的類名温鸽。索引值從 0 開始。如果索引值在區(qū)間范圍外則返回 null |
DOMCUMENT.classList.contains(class) | 返回布爾值手负,判斷指定的類名是否存在涤垫。可能值:true - 元素包已經(jīng)包含了該類名false - 元素中不存在該類名 |
改變元素節(jié)點(diǎn)的引用地址
比如圖片的引用地址和a標(biāo)簽的跳轉(zhuǎn)地址用 元素.src 和 元素.href
更改元素節(jié)點(diǎn)的HTML屬性 setAttribute( ) 和 getAttribute( )
不符合W3C標(biāo)準(zhǔn)的屬性竟终,例如自定義屬性名的屬性蝠猬,要使用 setAttribute( ) 和 getAttribute( ) 來設(shè)置,讀取统捶。格式是:
元素.setAttribute(屬性名,屬性值);
元素.getAttribute(屬性名); //返回屬性名對應(yīng)的值
例如:
div1.setAttribute('data-n',10);
div1.getAttribute('data-n');
setAttribute() 修改元素的類名用的是 class 而不是 className
removeAttribute() 刪除元素節(jié)點(diǎn)的HTML屬性
removeAttribute('屬性名')
更改元素節(jié)點(diǎn)的自定義屬性data
JavaScript的dataset屬性吱雏。
元素節(jié)點(diǎn).dataset.data后面的字符 = 'data-*的值';
如果后面的字符還是多個減號連接,那么data后面的字符用小駝峰式命名法瘾境。
節(jié)點(diǎn)的創(chuàng)建、插入镰惦、移動迷守、移除、克隆
方法名 | 功能 |
---|---|
document.createElement( ) | 創(chuàng)建一個指定tag name的HTML元素 |
父節(jié)點(diǎn).appendChild(孤兒節(jié)點(diǎn)) | 將新創(chuàng)節(jié)點(diǎn)掛載成最后一個子節(jié)點(diǎn) |
父節(jié)點(diǎn).insertBefore(孤兒節(jié)點(diǎn)旺入,標(biāo)桿節(jié)點(diǎn) ) | 將新創(chuàng)節(jié)點(diǎn)掛載成標(biāo)桿節(jié)點(diǎn)前一個子節(jié)點(diǎn) |
父節(jié)點(diǎn).removeChild( ) | 從DOM父節(jié)點(diǎn)中刪除一個子節(jié)點(diǎn) |
子節(jié)點(diǎn).remove( ) | 從DOM中刪除一個子節(jié)點(diǎn) |
老節(jié)點(diǎn).cloneNode( ) | 克隆出一個新的孤兒節(jié)點(diǎn) |
節(jié)點(diǎn).replaceChild(新節(jié)點(diǎn),舊節(jié)點(diǎn)) | 替換節(jié)點(diǎn) |
節(jié)點(diǎn)創(chuàng)建
document.createElement( )
方法用于創(chuàng)建一個指定標(biāo)簽名的HTML元素兑凿,例如:
var div1 = document.createElement('div');
此時新創(chuàng)建的節(jié)點(diǎn)是“孤兒節(jié)點(diǎn)”凯力,只生成在內(nèi)存中,需要掛在到DOM樹上才能看見他礼华,也就是要“孤兒上樹”咐鹤,此時就需要使用孤兒上樹的兩個插入方法。
其他節(jié)點(diǎn)創(chuàng)建方法
方法名 | 作用 |
---|---|
document.createTextNode( ) | 創(chuàng)建一個文本節(jié)點(diǎn) |
document.createComment( ) | 創(chuàng)建一個注釋節(jié)點(diǎn) |
document.createDocumentFragment( ) | |
創(chuàng)建一個虛擬的節(jié)點(diǎn)對象 |
節(jié)點(diǎn)插入
孤兒就是孤兒圣絮,要掛數(shù)只能找父親祈惶,然后讓一個野生父親使用 appendChild( )
和 insertBefore( )
方法即可。
appendChild( )
任何已經(jīng)在DOM樹上的節(jié)點(diǎn)扮匠,都可以調(diào)用appendChild( ) 方法捧请,它可以將孤兒節(jié)點(diǎn)掛載到它的內(nèi)部,使孤兒節(jié)點(diǎn)成為最后一個子節(jié)點(diǎn)棒搜。
父節(jié)點(diǎn).appendChild(孤兒節(jié)點(diǎn));
insertBefore( )
任何已經(jīng)在DOM樹上的節(jié)點(diǎn)疹蛉,都可以調(diào)用insertBefore( ) 方法,它可以將孤兒節(jié)點(diǎn)掛載到它的內(nèi)部力麸,成為它的“標(biāo)桿子節(jié)點(diǎn)”之前的節(jié)點(diǎn)可款。
父節(jié)點(diǎn).insertBefore(孤兒節(jié)點(diǎn),標(biāo)桿節(jié)點(diǎn));
創(chuàng)建和插入練習(xí):九九乘法表
<body>
<table></table>
<script type="text/javascript">
var table = document.getElementsByTagName('table')[0];
for (var i = 1;i<=9;i++) {
var tbr = document.createElement('tr');
table.appendChild(tbr);
for (var j=1;j<=i;j++) {
var trd = document.createElement('td');
trd.innerText = i+'*'+j+'='+i*j;
tbr.appendChild(trd);
}
}
</script>
</body>
元素的移動
appendChild( ) 和 insertBefore( ) 還可以用作元素的移動,因?yàn)?一個節(jié)點(diǎn)不能同時位于DOM樹的兩個位置
如果將已經(jīng)掛載到DOM樹上的節(jié)點(diǎn)成為appendChild( ) 和insertBefore( ) 的參數(shù)克蚂,這個節(jié)點(diǎn)將會被移動闺鲸,使用方法:
新父節(jié)點(diǎn).appendChild(已經(jīng)有父親的節(jié)點(diǎn));
新父節(jié)點(diǎn).insertBefore(已經(jīng)有父親的節(jié)點(diǎn),標(biāo)桿子節(jié)點(diǎn));
刪除節(jié)點(diǎn)
父節(jié)點(diǎn).removeChild(要刪除的子節(jié)點(diǎn));
子節(jié)點(diǎn).remove(要刪除的節(jié)點(diǎn));
removeChild( ) 方法從DOM中刪除一個子節(jié)點(diǎn)陨舱。
意味著節(jié)點(diǎn)不能主動刪除自己翠拣,必須由父節(jié)點(diǎn)刪除它。
克隆節(jié)點(diǎn)
var 孤兒節(jié)點(diǎn) = 老節(jié)點(diǎn).cloneNode( );
var 孤兒節(jié)點(diǎn) = 老節(jié)點(diǎn).cloneNode(true);
cloneNode( ) 方法可以克隆節(jié)點(diǎn)游盲,克隆出的節(jié)點(diǎn)是孤兒節(jié)點(diǎn)误墓。
參數(shù)可以傳入一個布爾值,默認(rèn)false益缎,false意味著只克隆元素本身不管子節(jié)點(diǎn)谜慌。
如果是true則采用深度克隆,該節(jié)點(diǎn)的所有后代節(jié)點(diǎn)也都會被克隆莺奔。
替換節(jié)點(diǎn)
替換父節(jié)點(diǎn)中的子節(jié)點(diǎn)欣范。用法:
父節(jié)點(diǎn).replaceChild(新的子節(jié)點(diǎn),舊的子節(jié)點(diǎn))
此方法如果用在已經(jīng)上樹的節(jié)點(diǎn)上,會拉下來重新上樹令哟,還是那個道理恼琼,一個dom節(jié)點(diǎn)不能位于樹上兩個位置
事件
事件是實(shí)現(xiàn)交互的核心。用戶與界面做出的交互動作都可以稱為事件屏富。例如“當(dāng)用戶點(diǎn)擊元素時晴竞,當(dāng)鼠標(biāo)移動到元素上時,當(dāng)文本框內(nèi)容被改變時狠半,當(dāng)網(wǎng)頁已加載完畢時噩死〔眩”
事件的三種模型
DOM0級:標(biāo)簽上直接綁定的onXXX事件和js用onXXX綁定的事件
IE:IE特有模型,解決了某三個DOM0級的問題已维。
DOM2事件模型:addEventListener方式添加事件行嗤,可以監(jiān)聽事件冒泡和捕獲階段階段
常見事件
常見的鼠標(biāo)事件
事件名 | 事件描述 |
---|---|
click | 鼠標(biāo)單擊 |
dblclick | 鼠標(biāo)雙擊 |
mousedown | 鼠標(biāo)按鍵按下 |
mouseup | 鼠標(biāo)按鍵松開 |
mousemove | 鼠標(biāo)按鍵移動 |
mouseenter、mouseover | 鼠標(biāo)進(jìn)入 |
mouseleave垛耳、mouseout | 鼠標(biāo)離開 |
contextmenu | 右擊鼠標(biāo)時觸發(fā)并打開上下文菜單 |
mousewheel | 鼠標(biāo)滾輪 |
只有mouseup和mousedown區(qū)分鼠標(biāo)鍵栅屏,button值0、1艾扮、2
如何解決mousedown和click沖突(例如a標(biāo)簽拖拽后會出發(fā)click事件):
利用時間戳和開關(guān)關(guān)閉click事件
mouseenter不冒泡既琴,mouseover冒泡
常見的鍵盤事件
事件名 | 事件描述 |
---|---|
keydown | 鍵盤的鍵被按下(可響應(yīng)所有按鍵,先于press執(zhí)行) |
keypress | 鍵盤的鍵被按下泡嘴,只能識別字符按鍵甫恩,例如方向鍵和功能鍵無法識別 |
keyup | 當(dāng)某個按鍵被松開 |
keypress返回的ASCII碼(例charCode)可轉(zhuǎn)字符
常見的表單事件
事件名 | 事件描述 |
---|---|
input | 當(dāng)用戶改變域的內(nèi)容 |
change | 當(dāng)用戶改變了域的內(nèi)容后 |
focus | 當(dāng)某元素獲得焦點(diǎn)(比如tab鍵跳轉(zhuǎn)到或鼠標(biāo)點(diǎn)擊) |
blur | 當(dāng)某元素失去焦點(diǎn) |
submit | 當(dāng)表單被提交 |
reset | 當(dāng)表單被重置 |
常見的頁面(窗體)事件監(jiān)聽
事件名 | 事件描述 |
---|---|
load | 當(dāng)頁面或圖像完全加載 |
unload | 當(dāng)用戶退出頁面 |
scroll | 滾動滾動條 |
resize | 窗體大小改變時 |
事件監(jiān)聽
DOM允許我們書寫JavaScript代碼以讓HTML元素對事件做出反應(yīng)。
“監(jiān)聽”就是讓計(jì)算機(jī)隨時能夠發(fā)現(xiàn)這個事件發(fā)生了酌予,從而執(zhí)行一些預(yù)先編寫的語句磺箕。主要有兩種方法。
- 元素.onXXX = function(){}
- 元素.addEventListener('',function(){},BOOLEAN);
兩種監(jiān)聽區(qū)別
- onXXX只能監(jiān)聽冒泡階段抛虫,addEventListener可以開啟捕獲階段松靡。
- onXXX只能綁定一個函數(shù),后寫的會覆蓋建椰。addEventListener可多次復(fù)寫雕欺。
事件監(jiān)聽解除
- 元素.onXXX = null;
- 元素.removeEventListener('事件類型',函數(shù),false);
- IE獨(dú)有:元素.detachEvent('onXXX',函數(shù));
事件傳播
當(dāng)元素形成嵌套結(jié)構(gòu)時,事件就會發(fā)生傳播棉姐,傳播分為:
- 事件捕獲:結(jié)構(gòu)上的父子元素屠列,開啟捕獲后,事件執(zhí)行從父元素捕獲到子元素伞矩。
- 事件冒泡:結(jié)構(gòu)上的父子元素關(guān)系笛洛,時間會從子元素冒泡到父元素。
- onXXX監(jiān)聽方法只能監(jiān)聽到冒泡階段
- addEventListener第三個參數(shù)為true時會開啟捕獲監(jiān)聽乃坤。
- 嵌套結(jié)構(gòu)的最內(nèi)部元素不再區(qū)分捕獲和冒泡苛让,冒泡寫在前面先執(zhí)行冒泡,捕獲寫在前面先執(zhí)行捕獲湿诊。
- 冒泡階段的onXXX和addEventListener誰先寫先執(zhí)行哪個函數(shù)狱杰。
阻止事件傳播: event.stopPropagation( ); 方法,或者ie678的event.cancelBubble=true;
事件對象
事件處理函數(shù)提供一個形式參數(shù)厅须,他是一個對象浦旱,封裝了本次事件的細(xì)節(jié)。這個形參通常用字母e或單詞event表示:例如
div.onclick = function(e){ }
div.addEventListener('click',function(event){},false);
誰是實(shí)參呢九杂,實(shí)參由瀏覽器提供颁湖,當(dāng)事件觸發(fā)時,瀏覽器會打包所有事件對象傳入事件處理函數(shù)形參中例隆。
實(shí)際上并不用形參實(shí)參的說法甥捺,實(shí)測有一個event對象就是事件對象。
鼠標(biāo)位置屬性
屬性名 | 屬性描述 |
---|---|
offsetX呕屎、offsetY | 鼠標(biāo)指針相對于事件源元素的X軸脑蠕、Y軸坐標(biāo) |
clientX丹禀、clientY | 鼠標(biāo)指針相對于瀏覽器視口的X軸、Y軸坐標(biāo) |
pageX吴侦、pageY | 鼠標(biāo)指針相對于整張網(wǎng)頁的X軸、Y軸坐標(biāo) |
screenX坞古、screenY | 鼠標(biāo)指針相對于電腦屏幕的X軸备韧、Y軸坐標(biāo) |
鍵盤charCode屬性和keyCode屬性
e.charCode屬性通常用于onkeypress事件中,表示用戶輸入的字符的ASCII碼痪枫。
e.keyCode屬性通常用于onkeydown事件和onkeyup中织堂,表示用戶按下的按鍵的鍵碼。
charcode字符碼
字符 | 字符碼 |
---|---|
數(shù)字0~數(shù)字9 | 48~57 |
大寫字母A~Z | 65~90 |
小寫字母a~z | 97~122 |
keycode鍵碼
按鍵 | 鍵碼 |
---|---|
數(shù)字0~數(shù)字9 | 48~57 |
字母不分大小a~z | 65~90 |
四個方向左上右下 | 37奶陈、38易阳、39、40 |
回車鍵 | 13 |
空格鍵 | 32 |
元素offset系列屬性
- 該系列屬性只讀吃粒,不可寫潦俺,且讀出來的數(shù)值是一個Number類型數(shù)值
- 可以得到元素的偏移位置,返回不帶單位的數(shù)值徐勃。這個數(shù)值以開啟定位的父元素為準(zhǔn)事示。
ELE.offsetTop
ELE.offsetLeft - 可以得到元素的寬度和高度,包含padding和border疏旨,即元素盒子的大小很魂。
ELE.offsetWidth
ELE.offsetHeight - 返回帶有定位的父親,否則返回body
元素的client系列屬性
- clientWidth 和 clientHeight 得到元素盒子除了border以外的尺寸大小檐涝。
- clientLeft 和 clientTop 不常用遏匆,相當(dāng)于左邊框和上邊框的大小
元素的scroll系列屬性
- scroll系列屬性要出現(xiàn)滾動條才更好理解更好用
- scrollWidth 和 scrollHeight 得到元素盒子除了border外的所有內(nèi)容的尺寸大小。
- scrollTop 和 scrollLeft 得到元素盒子被卷去的尺寸長度谁榜。該屬性可用于“滑到底部才可以點(diǎn)擊確定”
獲取元素在頁面上的屬性
- 可以用
window.getComputedStyle(元素名,null);
//第一個值傳的是需要獲取計(jì)算樣式的元素幅聘,第二個值傳入是否獲取的是偽元素 - 可以用
ELE.getBoundingClientRect()
,例如ELE.getBoundingClientRect().left
事件的方法
preventDefault() 方法 阻止默認(rèn)事件
e.preventDefault( ) 方法用來阻止事件產(chǎn)生的“默認(rèn)動作”窃植。
例如鼠標(biāo)滾動的動作帝蒿,表單提交,a標(biāo)簽跳轉(zhuǎn)巷怜,右鍵菜單等葛超。
一些特殊的業(yè)務(wù)需求暴氏,需要阻止事件的“默認(rèn)動作”。
阻止默認(rèn)事件還可以用return false;
stopPropagation( ) 方法 阻止事件傳播
e.stopPropagation( ) 方法用來阻止事件繼續(xù)傳播
在一些場合绣张,非常有必要切斷事件繼續(xù)傳播答渔,否則會造成頁面特效顯示出bug
事件委托
把事件綁定到父元素上,用 event.target 定位到子元素(利用了事件冒泡)
event.target 觸發(fā)此事件的最早元素侥涵,即“事件源元素”
event.currentTarget 事件處理程序附加到的元素
事件委托的使用場景:
- 當(dāng)有大量類似元素需要批量添加事件監(jiān)聽時沼撕,使用事件委托可以減少內(nèi)存開銷。
- 當(dāng)由動態(tài)元素節(jié)點(diǎn)上樹時芜飘,使用事件委托可以讓新上樹的元素具有事件監(jiān)聽
注意事項(xiàng):
- 不能委托不冒泡的事件給祖先元素
- 最內(nèi)層元素不能再有額外的內(nèi)層元素了
移動端事件
- 觸摸事件:touch事件务豺、pointer事件。
- 手勢事件:gesture
- 傳感器事件:sensor
移動端使用 tansform:translate3d();
會開啟GPU加速嗦明,提高性能笼沥。
touch 事件:
touchstart、touchmove招狸、touchend敬拓、touchcancel(比如操作時突然來電話)
touchstart 必須要在綁定事件的元素觸發(fā),觸發(fā)start后裙戏,touchmove 和 touchend 手指移除元素依然可觸發(fā)乘凸。
touch 事件的 TouchEvent 對象
- event.touches
- event.targetTouches
- event.changedTouches
這些對象都是一個 Touchlist,單指操作只需提取一個即可累榜,比如 event.changedTouches[0]
- touches是正在觸摸屏幕的所有手指的列表营勤。
- targetTouches是正在觸摸當(dāng)前DOM元素的手指列表。
- 如果是綁在dom元素的事件以上兩個是一樣的
- changedTouches是手指狀態(tài)發(fā)生了改變的列表壹罚,從無到有 或者 從有到無
touches 和 targetTouches 很多情況下在 touchend 事件里沒有值葛作,所以推薦使用 changedTouches
其他觸摸事件
touch 只是基礎(chǔ)事件,還有其他例如單擊猖凛,長按赂蠢,雙指等事件。
可以自行封裝這些高級事件辨泳,也可使用例如 hammer.js
等別人封裝好的事件庫虱岂。
定時器和延時器
定時器
setInterval( ) 函數(shù)可以重復(fù)調(diào)用一個函數(shù),在每次調(diào)用之間具有固定的時間間隔菠红,寫法:
setInterval(function(){},1000)
第一個參數(shù)是函數(shù)第岖,第二個參數(shù)是間隔時間,函數(shù)里的語句塊將會在每過間隔時間后執(zhí)行一次试溯。
setInterval函數(shù)可以接受第3蔑滓、4、5...個參數(shù),它們將按順序傳入函數(shù)键袱,例如燎窘。
setInterval(function(a,b){
},1000,1,2)
//第三個參數(shù)開始,表示傳入函數(shù)內(nèi)的實(shí)參
清除定時器
clearInterval( ) 函數(shù)杠纵,圓括號內(nèi)傳入要清除的定時器
延時器
setTimeout( ) 函數(shù)可以設(shè)置一個延時器荠耽,當(dāng)指定時間到達(dá)后,會執(zhí)行函數(shù)一次比藻,不再重復(fù)執(zhí)行,寫法:
setTimeout(function(){
},1000)
清除延時器
clearTimeout( ) 函數(shù)可以清除延時器
初識異步語句
定時器和延時器是兩個異步語句倘屹。
異步(asynchronous):不會阻塞CPU繼續(xù)執(zhí)行其他語句银亲,當(dāng)異步完成時,會執(zhí)行“回調(diào)函數(shù)”(callback)
//例子:
setInterval(function(){
console.log('a');
},1000)
console.log('b');
//會先輸出b纽匙,再輸出aaaaaa
異步語句不會阻塞程序的正常執(zhí)行务蝠。
(這里記個記號,異步這部分是我學(xué)前端的第一個大坎烛缔,原因是我看的好多教程都沒有講解異步底層原理馏段,直到去看了pink老師的講解才理解了異步,因?yàn)檫@點(diǎn)導(dǎo)致我后面的promise和ajax學(xué)得一知半解的)
函數(shù)節(jié)流
延時器可以用作函數(shù)節(jié)流践瓷,即加個開關(guān)院喜,定時打開或關(guān)閉開關(guān),需足夠時間才能執(zhí)行下一次函數(shù)晕翠,具體方法:
var lock = true;
function 需要節(jié)流的函數(shù)名(){
if(!lock) return;
lock = false;
setTimeout(function(){
lock =true;
},節(jié)流時間);
}
BOM
Browser Object Model 瀏覽器對象模型喷舀,是JS與瀏覽器窗口交互的接口。
一些與瀏覽器改變尺寸淋肾、滾動滾動條相關(guān)的硫麻,都要借助BOM技術(shù)。
window對象
window對象是當(dāng)前js腳本運(yùn)行所處的窗口樊卓,而這個窗口中包含DOM結(jié)構(gòu)拿愧,window.document屬性就是document對象。
在有標(biāo)簽頁功能的瀏覽器中碌尔,每個標(biāo)簽擁有自己的window對象浇辜,不共用。
全局變量是window的屬性
var a = 10;
//控制臺輸入window.a返回10
這意味著多個js文件之間是共享全局作用域的七扰。
內(nèi)置函數(shù)普遍是window的方法
如setInterva( ) 奢赂、alert( ) 等內(nèi)置函數(shù),普遍是window的方法
window屬性
瀏覽器窗口尺寸相關(guān)屬性
屬性 | 意義 |
---|---|
innerHeight | 瀏覽器窗口的內(nèi)容區(qū)高度颈走,包含滾動條(如果有) |
innerWidth | 瀏覽器窗口的內(nèi)容區(qū)高度膳灶,包含滾動條(如果有) |
outerHeight | 瀏覽器窗口的外部高度 |
outerWidth | 瀏覽器窗口的外部寬度 |
瀏覽器的滾動條是有寬度的,如果想要獲得不包含滾動條的窗口寬度,要用
document.documentElement.clientWidth
窗口改變事件resize見window事件
瀏覽器窗口滾動條相關(guān)屬性
屬性 | 意義 |
---|---|
window.pageYOffset | 獲取當(dāng)前滾動條Y軸已滾動像素值 |
window.pageXOffset | 獲取當(dāng)前滾動條X軸已滾動像素值 |
window.scrollY | |
window.scrollX | |
document.documentElement.scrollTop | |
document.documentElement.scrollLeft |
document.documentElement.scroll可讀可寫轧钓,可用作返回頂部序厉。
滾動條相關(guān)事件scroll見window事件
瀏覽器窗口滾動條相關(guān)方法
方法名 | 作用 |
---|---|
window.scoll( ) | |
window.scollTo( ) | |
window.scrollBy( ) |
傳入(x,y)值滾動到輸入的位置毕箍。
scroll和scrollTo一樣弛房,scrollBy是在現(xiàn)基礎(chǔ)上累加
window方法
事件名 | 事件描述 |
---|---|
load | 當(dāng)頁面或圖像完全加載 |
unload | 當(dāng)用戶退出頁面 |
scroll | 滾動滾動條時 |
resize | 窗體大小改變時 |
navigator對象
屬性 | 意義 |
---|---|
appName | 瀏覽器官方名稱 |
appVersion | 瀏覽器版本 |
userAgent | 瀏覽器的用戶代理(含有內(nèi)核信息和封裝殼信息) |
platform | 用戶操作系統(tǒng) |
history對象
history.back(); //等同于瀏覽器回退按鈕
history.go(-1); //同上
history.go(1); //前進(jìn)一個頁面
history,forward(); //同上
a標(biāo)簽實(shí)現(xiàn)回退功能
<a href="javascript:history.back();">回退</a>
location 對象
location.href 返回當(dāng)前頁面URL
location.reload(true) 傳入true強(qiáng)制從服務(wù)器重新渲染頁面
location.search 當(dāng)前瀏覽器的get請求查詢參數(shù)
面向?qū)ο?/h1>
認(rèn)識對象
Object 是鍵值對的集合。
寫法:鍵和值之間用冒號分割而柑,每組鍵值之間用逗號分隔文捶。
如果對象的屬性鍵名不符合js標(biāo)識符命名規(guī)則,這個鍵名必須用引號包裹媒咳。
//方法一:
var 變量 = {
鍵1 : 值1,
鍵2 : 值2
}
//方法二:
var 變量 = new Object();
屬性的訪問
用 點(diǎn)語法 訪問對象中指定的值粹排,
如果屬性名不符合js標(biāo)識符命名規(guī)則,則必須用方括號里加引號里寫屬性名涩澡。
如果屬性名以變量形式存儲顽耳,也必須用方括號。
可用 hasOwnProperty( )
方法判斷屬性是否是自己的妙同,
或者使用 in
判斷屬性是否是自己和父級的射富。
屬性的更改
直接用賦值運(yùn)算符重新對屬性賦值即可。
屬性的創(chuàng)建
如果對象本身沒有屬性粥帚,直接用 點(diǎn)語法 寫屬性名胰耗,并用賦值運(yùn)算符賦值即可,全局變量原理也是這樣茎辐。
屬性的刪除
用delete操作符宪郊,例如:
delete 對象.屬性;
對象的方法
如果某個屬性值是函數(shù),著它也被稱為對象的方法拖陆。
方法的調(diào)用
使用點(diǎn)語法即可弛槐。
方法和函數(shù)
方法是對象的函數(shù)屬性,需要用對象打點(diǎn)調(diào)用依啰,函數(shù)也可以用window打點(diǎn)乎串,所以二者在js里無差別。
對象的遍歷
用 for(var 循環(huán)變量 in 對象){} 循環(huán)速警,例:
for(var k in obj){
console.log(obj[k]);
}
循環(huán)變量可隨意命名叹誉,一般為k或prop,循環(huán)變量會一次變?yōu)閷ο蟮拿恳粋€鍵闷旧。在for in 遍歷里长豁,一定要寫成 對象[] ,的形式忙灼,因?yàn)檠h(huán)變量是變量匠襟,中括號形式才能沒問題循環(huán)所有形式的變量钝侠。
對象的深淺克隆
慕課網(wǎng)方法:
function deepClone(o){
if (Array.isArray(o)) {
var result = [];
for (var i = 0;i < o.length;i++) {
result.push(deepClone(o[i]));
}
}else if(typeof o == 'object'){
var result = {};
for (var k in o) {
result[k] = deepClone(o[k]);
}
}else{
var result = o;
}
return result;
}
渡一方法
function deepclone(origin,target){
var target = target||{};
for(var prop in origin){
if(origin.hasOwnProperty(prop)){
if(typeof(origin[prop]) == 'object'){
if (Object.prototype.toString.call(origin[prop])=='[object object]') {
target[prop] = {};
} else{
target[prop] = [];
}
deepclone(origin[prop],target[prop]);
}else{
target[prop] = origin[prop];
}
}
}
return target;
}
認(rèn)識函數(shù)的上下文
函數(shù)中可以用 this 關(guān)鍵字,他表示函數(shù)的上下文酸舍。
this 指向必須通過調(diào)用函數(shù)時的“前言后語”來判斷帅韧。
函數(shù)的上下文由調(diào)用方式?jīng)Q定,函數(shù)只有被調(diào)用啃勉,才會產(chǎn)生上下文忽舟。
上下文規(guī)則
- 對象打點(diǎn)調(diào)用他的方法函數(shù),則函數(shù)的上下文是這個打點(diǎn)的對象淮阐。
- 圓括號直接調(diào)用函數(shù)叮阅,則函數(shù)上下文是 window 對象。
- 數(shù)組(或類數(shù)組對象)枚舉出函數(shù)進(jìn)行調(diào)用泣特,則上下文是這個數(shù)組(或類數(shù)組對象)帘饶。
- 在IIFE函數(shù)中,上下文是window對象群扶。
- 定時器、延時器調(diào)用函數(shù)镀裤,上下文是 window 對象竞阐。
- 事件處理函數(shù)的上下文是綁定事件的DOM元素,所以通常需要備份上下文暑劝。
call 和 apply
能指定函數(shù)的上下文骆莹,例:
函數(shù).call(上下文)
函數(shù).apply(上下文)
區(qū)別: 當(dāng)函數(shù)需要參數(shù)時,call 要用逗號羅列參數(shù)担猛; apply 需把參數(shù)寫在數(shù)組中幕垦。
bind
bind 和 call 差不多,不過它只改變this指向傅联,不會調(diào)用函數(shù)先改,執(zhí)行完bind之后會返回一個已經(jīng)修改好this指向的函數(shù),可以用一個變量接收
function fn(){}
var ojj = {}
var bii = fn.bind(o)
用new調(diào)用函數(shù)
用new接函數(shù)調(diào)用蒸走,會從函數(shù)內(nèi)部返回一個對象仇奶。
JS規(guī)定,使用new操作符調(diào)用函數(shù)會進(jìn)行“四步走”用new調(diào)用函數(shù)的四步走:
- 函數(shù)體內(nèi)會自動創(chuàng)建出一個空白對象比驻。
- 函數(shù)的上下文(this)會指向這個空白對象该溯。
- 函數(shù)體內(nèi)的語句會執(zhí)行。
- 函數(shù)會自動返回上下文對象别惦,即使函數(shù)沒有return語句狈茉。
上下文規(guī)則總結(jié)表格
情況 | this指向 |
---|---|
對象.函數(shù)() | 對象 |
函數(shù)直接調(diào)用 | window |
數(shù)組[下標(biāo)] () | 數(shù)組 |
IIFE函數(shù) | window |
定時器、延時器 | window |
DOM事件處理函數(shù) | 綁定DOM元素 |
call和apply | 任意指定 |
用new調(diào)用函數(shù) | 秘密創(chuàng)建出的對象 |
構(gòu)造函數(shù)
function 函數(shù)名(參數(shù)1掸掸,參數(shù)2){
this.參數(shù)1同名 = 參數(shù)1;
this.參數(shù)2同名 = 參數(shù)2;
}
然后用 new 調(diào)用函數(shù)執(zhí)行:
構(gòu)造函數(shù)開發(fā)者約定函數(shù)命名時首字母要大寫氯庆,不用new調(diào)用不能正常工作。
構(gòu)造函數(shù)用來“構(gòu)造新對象”,它內(nèi)部語句會為新對象添加屬性和方法点晴,完成對象初始化感凤。
“類”與實(shí)例
JS中是沒有類這個概念的,因?yàn)镴S的對象與真正的面向?qū)ο笳Z言有差別粒督,叫“基于對象”陪竿。
構(gòu)造函數(shù)可以看為是“類”,構(gòu)造函數(shù)new出來的對象可以看作為“實(shí)例”屠橄。
判斷這個實(shí)力是否是一個“類”構(gòu)造出來的族跛,可以用
A instanceof B
prototype 原型
任何函數(shù)都有prototype屬性。
prototype屬性是個對象锐墙,它默認(rèn)擁有constructor屬性指回函數(shù)礁哄。
普通函數(shù)的prototype屬性沒有任何用處,而構(gòu)造函數(shù)的prototype非常有用溪北,構(gòu)造函數(shù)的prototype是它實(shí)例的原型桐绒。
原型鏈
[圖片上傳失敗...(image-be2be0-1649463907747)]
hasOwnProperty 可以檢查對象是否真正“自己擁有”某屬性或方法。
in 可以檢查對象是否能訪問到這個屬性或方法之拨。
無法直接訪問的意思是茉继,構(gòu)造函數(shù)自身無法直接調(diào)用或訪問原型上的方法或?qū)傩裕鴮?shí)例可以蚀乔,構(gòu)造函數(shù)自身想訪問原型上的方法必須先找原型再調(diào)用
在prototype上添加方法
將方法添加到構(gòu)造函數(shù)上時烁竭,生成的每一個新對象就會多一個新占用內(nèi)存的方法,會造成內(nèi)存浪費(fèi)吉挣。
解決方法就是將方法寫道prototype上派撕,只生成一個堆內(nèi)存就夠了。
重寫constructor
prototype里面自帶有一個constructor方法用于指回是哪個構(gòu)造函數(shù)構(gòu)造出來的睬魂,但通常一個構(gòu)造函數(shù)的原型方法里需要塞下多個方法的時候我們通常需要用對象的形式终吼,例如
function FFnn(){
}
FFnn.prototype = {
say(){}
sing(){}
}
通常會這樣子通過對象的形式往里面添加多個方法,那么這個時候自帶的construtor就沒有了汉买,所以這個時候如果你還想要有一個constructor方法指回構(gòu)造函數(shù)衔峰,記得重新自己把constructor寫上
FFnn.prototype = {
constructor:FFnn
say:function(){}
sing:function(){}
}
繼承
兩個無關(guān)的構(gòu)造函數(shù),但一個構(gòu)造函數(shù)需要的屬性在另一個函數(shù)上也有蛙粘,就可以利用原型鏈原理達(dá)成繼承垫卤。
方法:使子函數(shù)的原型等于另一個函數(shù)的實(shí)例:
Fun2.prototype = new Fun1();
繼承——圣杯模式
function inherit(Target,Origin){
function F(){};
F.prototype = Origin.prototype
Target.prototype = new F();
Targer.prototype.constructor = Targer;
Targer.prototype.uber = Origin.prototype;
}
包裝類
包裝類的目的就是為了讓基本類型值可以從他們的構(gòu)造函數(shù)的prototype上獲得方法。
包裝類構(gòu)造出來的值是一個對象出牧,type of 返回 object 穴肘,可以參與運(yùn)算。
Math 數(shù)學(xué)對象
除了之前介紹的那些 Math 方法以外舔痕,我們還有更多常用的Math方法评抚。
四舍五入 Math.round()
實(shí)現(xiàn)四舍五入到小數(shù)點(diǎn)后某位:
數(shù)字 * 10的n次方 然后四舍五入 再 / 10的n次方豹缀。
得到參數(shù)列表最大最小值
Math.max() 得到參數(shù)列表最大值。
Math.min() 得到參數(shù)列表最小值慨代。
如何求數(shù)組最大最小值:Math.max() 和 Math.min() 結(jié)合apply邢笙,例如:
var arr = [3,2,9];
var max = Math.max.apply(null,arr);
//ES6之后還可以
Math.max(...arr);
Date 日期對象
使用 new Date()
即可得到當(dāng)前時間的日期對象,他是object類型值侍匙。如果什么參數(shù)都不加就是此時此刻的時間氮惯。
使用new Date(2021,6,12)
即可得到指定日期的日期對象,注意第二個參數(shù)是從0開始算的想暗,6表示7月份妇汗。
也可以new Date('2021-7-12')
這樣寫,算時區(qū)说莫。
常見日期方法
方法 | 功能 |
---|---|
getDate() | 得到日期1~31 |
getDay() | 得到星期0~6 |
getMonth() | 得到月份0~11 |
getFullYear() | 得到年份 |
getHours() | 得到小時數(shù)0~23 |
getMinutes() | 得到分鐘數(shù)0~59 |
getSeconds() | 得到秒數(shù)0~59 |
時間戳
表示從1970年1月1日零點(diǎn)整距離某時刻的毫秒數(shù)杨箭。
可以通過 getTime()
方法或 Date.parse()
函數(shù)可將日期對象改為時間戳枝哄。
或者直接在date對象前面加個加號 + 即可误阻,例如 var chuo = + new Date()
通過 new Date(時間戳)
可將時間戳改為日期對象
正則表達(dá)式
regular expression 描述了字符串的“構(gòu)成模式”,經(jīng)常被用于檢查字符串是否符合預(yù)定的格式要求叭披。
正則表達(dá)式“按位”描述規(guī)則辽狈,是指它是一位一位的描述子字符串的構(gòu)成形式擒悬。
正則表達(dá)式的創(chuàng)建
使用 /內(nèi)容/ 的語法形式,可以快速創(chuàng)建正則表達(dá)式
也可以使用 new RegExp('內(nèi)容') 這種方法使用一些字符可能要用轉(zhuǎn)義稻艰。
type of 檢查正則表達(dá)式返回object。
元字符
元字符 | 功能 |
---|---|
\d | 匹配一個數(shù)字 |
\D | 匹配一個非數(shù)字字符 |
\w | 匹配一個單字字符 |
\W | 匹配一個非單字字符 |
\s | 匹配一個空白字符侈净,包含空格制表符換行符 |
\S | 匹配一個非空白字符 |
. | 任意字符 |
^ | 匹配開頭 |
# | 匹配結(jié)尾 |
量詞
量詞 | 意義 |
---|---|
* | 匹配前一個表達(dá)式0次或多次尊勿,等價于{0,} |
+ | 匹配前一個表達(dá)式1次或多次,等價于{1,} |
? | 匹配前一個表達(dá)式0次或1次 |
{n} | n是一個正整數(shù)畜侦,匹配了前面一個字符剛好出現(xiàn)了n次 |
{n,} | n是一個正整數(shù)元扔,匹配前一個字符至少出現(xiàn)了n次 |
{n,m} | n和m都是正整數(shù),匹配前面的字符至少出現(xiàn)n次旋膳,最多m次 |
方括號表示法
- 使用方括號澎语,比如[xyz]可以創(chuàng)建一個字符集合,表示匹配方括號中的任意字符验懊,一個方括號代表一位擅羞。
- 可以用短橫 - 來指定一個字符范圍,^ 表示否定
例如[0-9] [a-z] [A-Z] [0-9a-zA-Z_] [0-68-9]
修飾符
i | 不區(qū)分大小寫搜索 |
g | 全局搜索 |
正則表達(dá)式的方法
test() 測試某字符串是否匹配正則表達(dá)式义图,返回布爾值
exec() 根據(jù)正則表達(dá)式减俏,在字符串中進(jìn)行查找,返回結(jié)果數(shù)組或者null碱工。exec方法開啟全局搜索后可逐條遍歷(ES6迭代器概念)娃承。
字符串的相關(guān)正則方法
方法 | 簡介 |
---|---|
search() | 在字符串中根據(jù)正則表達(dá)式及逆行查找匹配奏夫,返回首次匹配到的位置索引,測試不到則返回 -1 |
match() | 在在字符串中根據(jù)正則表達(dá)式進(jìn)行查找匹配历筝,返回一個數(shù)組酗昼,找不到則返回null |
replace() | 使用替換字符串替換掉匹配到的子字符串,可以使用正則表達(dá)式 |
split() | 分割字符串為數(shù)組梳猪,可以使用正則表達(dá)式 |
本地存儲
- 本地存儲不會發(fā)送到服務(wù)器端麻削,且二者大小有所區(qū)別,sessionStorage能存儲5m左右舔示,localstorage可以儲存10m左右碟婆。(單個域名下)
- 二者都可以在瀏覽器F12中,Application-Storage 中找到惕稻,分為 key 和 value竖共。
- 使用方法為
sessionStorage.setItem(key,value)
和localStorage.getItem(key,value)
- 二者存儲的鍵和值只能是字符串類型,如果不是字符串類型俺祠,也會先轉(zhuǎn)成字符串再存進(jìn)去公给。或者存入JSON類型值
- 不同域名不能共用 sessionStorage 和 localStorage
- IE7及以下不支持
sessionStorage
sessionStorage 是一種瀏覽器本地存儲數(shù)據(jù)的方式蜘渣,只存儲在本地淌铐,不發(fā)送到服務(wù)器端。當(dāng)會話結(jié)束(例如關(guān)閉瀏覽器時)蔫缸,sessionStorage 中的數(shù)據(jù)會清空腿准。基本用法:
- 增加數(shù)據(jù)setItem方法:
sessionStorage.setItem(key,value);
- 查詢數(shù)據(jù)getItem方法:
sessionStorage.getItem(key);
- 刪除數(shù)據(jù)removeItem方法:
sessionStorage.removeItem(key);
全部清空clear方法:sessionStorage.clear();
- 改更數(shù)據(jù)setItem方法:同key屬性覆蓋
其他屬性:
- length 屬性:
sessionStroage.length()
獲取長度 - key方法拾碌,參數(shù)時數(shù)據(jù)吐葱,代表key的索引,根據(jù)索引獲取key值校翔。
sessionStorage.key(0)
localStorage
localStorage 時持久化的本地存儲弟跑,除非手動清楚或者滿了自動清除,否則數(shù)據(jù)永遠(yuǎn)不會過期防症。
- 增加數(shù)據(jù)setItem方法:
localStorage.setItem(key,value);
- 查詢數(shù)據(jù)getItem方法:
localStorage.getItem(key);
- 刪除數(shù)據(jù)removeItem方法:
localStorage.removeItem(key);
全部清空clear方法:localStorage.clear();
- 改更數(shù)據(jù)setItem方法:同key屬性覆蓋
- length 屬性:
localStroage.length()
獲取長度 - key方法孟辑,參數(shù)時數(shù)據(jù),代表key的索引蔫敲,根據(jù)索引獲取key值饲嗽。
loacalStorage.key(0)
ES6簡介
ECMAScript 第六代標(biāo)準(zhǔn)
let 和 const
用于聲明變量或聲明常量
變量和常量
var 和 let 聲明的就是變量,變量初始化后還可以重新賦值奈嘿。
const 聲明的是常量喝噪,常量一旦初始化后就不能重新賦值,否則報(bào)錯指么。常量可以防止不經(jīng)意間改變了不能改變的量酝惧。如果常量值的類型是引用類型榴鼎,例如對象,可以修改對象屬性的值晚唇。
const 聲明常量一旦聲明巫财,就必須完成初始化,否則報(bào)錯
let哩陕、const 與 var 的區(qū)別
- 重復(fù)聲明:var 支持重復(fù)聲明平项,let 與 const 不支持。
- 變量提升:let 與 const 不存在變量提升悍及。
- 暫時性死區(qū):只要作用域內(nèi)存在 let 和 const 闽瓢,他們聲明的量就會綁定作用域,該量不再受外部影響心赶。
- window對象的屬性和方法:let 和 const 聲明的量不會變成 window 對象的屬性或方法扣讼。
- 塊級作用域: let 與 const 存在塊級作用域。
模板字符串
一般字符串:單引號和雙引號缨叫。
模板字符串:反引號椭符。
特征:
- 模板字符串中所有空格、換行耻姥、縮進(jìn)都被保留在輸出中销钝。
- 同樣可以使用轉(zhuǎn)義字符輸出反引號、反斜杠等特殊字符琐簇。
- 可以直接在模板字符串中使用
${}
注入內(nèi)容(變量蒸健,屬性值,函數(shù)值婉商,計(jì)算值等)
標(biāo)簽?zāi)0?/h2>
是函數(shù)調(diào)用的一種特殊形式纵装。模板字符串可以緊跟在一個函數(shù)后面,該函數(shù)將被調(diào)用來處理這個模板字符串据某,這被成為“標(biāo)簽?zāi)0濉惫δ埽纾?/p>
alert('hello')
//等同于
alert`hello`
"標(biāo)簽"指的就是函數(shù)诗箍,緊跟在后面的模板字符串就是他的參數(shù)癣籽。
如果模板字符串中有變量,就不是簡單的調(diào)用了滤祖,而是會將模板字符串先處理成多個參數(shù)筷狼,再調(diào)用函數(shù)。
let a = 5;
let b = 10;
function tag(tpldata,...values){
console.log(tpldata);
console.log(values);
console.log(arguments);
}
tag`hello ${a+b} world ${a*b}`
//等同于
tag(['hello',' world ',''],15,50)
“標(biāo)簽?zāi)0濉钡囊粋€重要應(yīng)用匠童,就是過濾HTML字符串埂材,防止用戶注入代碼
let message =
SaferHTML`<p>${sender} has sent you a message.</p>`;
function SaferHTML(templateData) {
let s = templateData[0];
for (let i = 1; i < arguments.length; i++) {
let arg = String(arguments[i]);
// Escape special characters in the substitution.
s += arg.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">");
// Don't escape special characters in the template.
s += templateData[i];
}
return s;}
箭頭函數(shù)
寫法: ()=>{}
小括號內(nèi)參數(shù),等號大于號汤求,中括號內(nèi)函數(shù)體俏险。
通常需要用一個變量或常量接收严拒。
注意事項(xiàng)
- 單個參數(shù)可省略小括號,0個或多個不可省略竖独。
- 單行函數(shù)體可同時省略大括號和 return 裤唠,必須同時。
- 單行對象如果要省略大括號莹痢,需要在對象外加小括號:例如
const add = (x+y)=>({value:x+y})
箭頭函數(shù)沒有自己的this
非箭頭函數(shù)執(zhí)行一定會產(chǎn)生屬于這個函數(shù)的this种蘸,箭頭函數(shù)沒有自己的this,只會從自己的作用域鏈的上一層繼承 this.
箭頭函數(shù)使用注意
- 不能作為構(gòu)造函數(shù)竞膳。
- 需要 this 指向調(diào)用對象的時候箭頭函數(shù)不適用航瞭。
- 需要 arguments 的時候,箭頭函數(shù)沒有 arguments 坦辟】睿可以用剩余參數(shù)替代。
Iterator 迭代器/遍歷器
找到 iterator
先創(chuàng)建一個數(shù)組 const arr = [1,2]
用控制臺查看长窄,深挖其屬性會有個 Symbol.iterator 滔吠,執(zhí)行該方法 arr[Symbol.iterator]()
執(zhí)行后會返回一個 Array Iterator{}
可以用一個量接收。
使用Iterator
iterator調(diào)用 next() 方法挠日,會返回 {value: xxx , done: xxx}
可迭代對象
只要有 Symbol.iterator 方法疮绷,且這個方法調(diào)用后會產(chǎn)生一個 iterator 。
例如:數(shù)組嚣潜、字符串冬骚、arguments、NodeList懂算、Set只冻、Map、剩余參數(shù) 等计技。
一般對象不是可迭代對象喜德,可以給一般對象強(qiáng)行添加 Symbol.iterator 方法。
obj[Symbol.iterator] = ()=>{
let index = ;
return(
next(){
index++;
……
}
)
}
//類數(shù)組對象可以直接偷數(shù)組原型上的
LEISHUZU[Symbol.iterator] = Array[Symbol.iterator]
for of
想要遍歷一些東西的時候垮媒,五花八門舍悯,對象用 for(...in...) ,數(shù)組用 for 循環(huán)睡雇、forEach 方法萌衬。而 iterator 只有一種遍歷方式,就是“下一個”它抱,一般用系統(tǒng)封裝好的 for(...of...)
for(let item of arr){
}
- for(...of...) 循環(huán)只會遍歷出那些 done 為false時對應(yīng)的 value 值秕豫。(如果改寫了對象的Symbol.iterator()之后比如把done改為false則會瘋狂輸出)
- for(...of...) 可以和 break 、 continue 一起使用观蓄。
可迭代對象的方法
forEach()
forEach() 方法可遍歷 可迭代對象 混移。
forEach() 傳入的第一個參數(shù) 是一個回調(diào)函數(shù)祠墅。回調(diào)函數(shù)可以使用三個參數(shù)沫屡,按順序分別是 (1)可遍歷對象鍵值對的值 (2)可遍歷對線鍵值對的鍵 (3)可遍歷對像本身饵隙。
forEach() 傳入的第二個參數(shù) 是 this 指向(非箭頭函數(shù)時才可用)。例如:
let arr = [11,22,33];
arr.forEach((value,key,self)=>{
console.log(value,key,self)
},arr)
keys()
一些可迭代對象可以執(zhí)行 keys() 方法沮脖,遍歷此方法得到的對象金矛,可以取得鍵名(例如數(shù)組的索引值,可迭代對象的鍵名)勺届。例如:
let arr = [1,2,3]
for(let k of arr.keys()){
console.log(k)
}
values()
可迭代對象的 values() 方法驶俊,遍歷此方法返回的對象可以取得鍵值對的值(低版本瀏覽器不支持)
let arr = [1,2,3]
for(let k of arr.values()){
console.log(k)
}
entries()
可迭代對象的 entries() 方法,遍歷此方法返回的對象可以取得鍵值對(索引+值組成的數(shù)組)
let arr = [1,2,3]
for(let k of arr.entries()){
console.log(k)
}
生成器函數(shù)
生成器函數(shù)免姿,在舊函數(shù)聲明方法 function fc(){}
中饼酿,在function關(guān)鍵字和函數(shù)名中間插入一個*號
function* (){}
普通函數(shù)執(zhí)行時沒有停止功能 Generator函數(shù)可以暫停
Generator 生成器 返回的是iterator接口
CO庫就是不停的調(diào)用next方法將最后結(jié)果返回
Generator 中 yield 后面只能跟 Thunk 函數(shù)或 Promise 對象
function * gen(){
console.log(arg);
let one = yield 111;
console.log(one)
}
let iterator = gen('AAA')
console.log(iterator.next());
console.log(iterator.next('BBB'))
next方法里面可以傳入實(shí)參,傳入的實(shí)參將會作為上一個yield整體返回的結(jié)果
展開運(yùn)算符
... 可用于 可迭代對象 的展開胚膊。
例如故俐,可以用于數(shù)組展開,把數(shù)組拆成一個一個數(shù)字紊婉。例如:Math.min 和Math.max 只能計(jì)算一串參數(shù)的最大最小值不能傳入數(shù)組药版,這時就能傳入數(shù)組同時用展開運(yùn)算符展開。
let arr = [1,2,3];
//直接Math.min(arr)則不計(jì)算喻犁,可以
Math.min(...arr);
展開運(yùn)算符可用于數(shù)組淺復(fù)制(淺克虏燮),例如
let arr1 = [1,2,3];
let arr2 = [...arr1]
所以展開 可迭代對象 外直接套一個中括號可以快速轉(zhuǎn)變?yōu)橐粋€數(shù)組肢础。
展開運(yùn)算符可以用于 對象 展開
但不能直接展開还栓,只能在 {} 大括號中展開。
所以還可以用于對象復(fù)制传轰,也可以用于合并對象剩盒,用于合并對象時,后展開的與前展開的對象同名的屬性會覆蓋慨蛙。
展開空對象沒有效果
let obj1 = {name:'mingzi',age:18}
let obj2 = {...obj1}
展開運(yùn)算符只能“淺展開”
即只能展開一層
展開運(yùn)算符特殊用法:剩余參數(shù)
當(dāng)函數(shù)執(zhí)行傳入 比形參數(shù)量更多的 實(shí)參時辽聊,可以用剩余參數(shù)接受,寫法 ...xxx 股淡,本質(zhì)是個數(shù)組,即使沒有值廷区,也是個控股數(shù)組唯灵,讀取時不用 ... 直接讀 xxx 即可。例如
function func(a,b,...sycs){console.log(sycs)}
func(1,2,3,4,5,6,7,8)
//返回?cái)?shù)組[3,4,5,6,7,8]
箭頭函數(shù)中的剩余參數(shù)
箭頭函數(shù)中隙轻,因?yàn)榧^函數(shù)只有一個參數(shù)的時候可以省略小括號埠帕,但即使只有一個剩余參數(shù)垢揩,也不能省略小括號。
箭頭函數(shù)沒有arguments敛瓷,所以可以用剩余參數(shù)替代叁巨,且剩余參數(shù)可以用數(shù)組的方法。
剩余參數(shù)必須呐籽、只能是最后一個參數(shù)锋勺,之后不能有其他參數(shù),否則報(bào)錯
剩余參數(shù)可以與解構(gòu)賦值結(jié)合使用狡蝶。
剩余參數(shù)與對象解構(gòu)賦值結(jié)合使用會成為剩余元素庶橱。
解構(gòu)賦值
- 將 可迭代對象 的值 賦給一個 可迭代對象 書寫形式的結(jié)構(gòu),例如:
const [a,b] = [1,2]
- 對象也可以使用解構(gòu)賦值贪惹,但必須滿足 1.模式(結(jié)構(gòu))匹配 2.屬性名相同的完成匹配苏章。
- 其他數(shù)值類型也可以使用解構(gòu)賦值,例如number和boolean奏瞬,會先將等號右邊的值先轉(zhuǎn)為對象枫绅。但無法解構(gòu)其內(nèi)容,只能提取繼承的屬性硼端。
- undefined 和 null 無法進(jìn)行解構(gòu)賦值并淋。
可迭代對象全部都可以使用數(shù)組形式完成結(jié)構(gòu)賦值,字符串還可以使用對象的結(jié)構(gòu)完成解構(gòu)賦值显蝌,例如: let {0:a} = 'bilibili'
预伺,此時 a 為下標(biāo)為 0 的字母b。
解構(gòu)賦值的默認(rèn)值
可以給解構(gòu)賦值的常量變量賦一個默認(rèn)值曼尊,例如 let[a=1,b=2]=[]
注意:只有右邊與左邊解構(gòu)賦值嚴(yán)格等于 undefined 時酬诀,默認(rèn)值才會生效。默認(rèn)值擁有惰性求值的特性骆撇,即用得到才執(zhí)行求值式求值瞒御,用不到則不執(zhí)行。
解構(gòu)賦值的應(yīng)用用途
解構(gòu)賦值可以用于快捷交換變量值神郊,例如
let x=1,y=2;
[x,y]=[y,x]
//此時x和y就快速交換了值肴裙。
Set
Set是一些列無序、沒有重復(fù)值的數(shù)據(jù)集合涌乳。
無序: Set沒有下標(biāo)去標(biāo)識每一個值蜻懦,所以set是無序的,不能像數(shù)組一樣通過下標(biāo)去訪問 set 的成員夕晓,但遍歷 set 的時候宛乃,是根據(jù)成員添加進(jìn) set 的順序進(jìn)行遍歷的。
沒有重復(fù)值: Set會自動去重,Set重復(fù)值的判斷遵循全等原則征炼,但NaN除外析既,在Set中NaN也不可重復(fù)。
創(chuàng)建一個 Set
使用 Set 構(gòu)造函數(shù) const se = new Set()
即可創(chuàng)建一個set谆奥,創(chuàng)建 Set 時可以傳入一個可迭代對象作為參數(shù)眼坏,構(gòu)造出來的Set就會擁有對象里的成員,例如:
let arr = [1,2,3]
const se = new Set(arr)
Set 的屬性
size:可以訪問Set里面的成員個數(shù)酸些。new Set().size
會返回一個0.
Set 的常用方法
方法 | 作用 |
---|---|
add() | 添加成員宰译,可連續(xù)使用 |
has() | 查看是否有某個成員,返回布爾值 |
delete() | 刪除某個成員 |
clear() | 清除所有成員 |
forEach() | 遍歷 |
add
可以連續(xù)添加擂仍,例如:
const se = new Set()
se.add(1).add(2).add(3)
delete
如果刪除不存在的成員囤屹,則什么都不會發(fā)生,也不會報(bào)錯
forEach
Set 的 forEach 是按照成員添加進(jìn)Set的順序遍歷的
Set 用途
Set 可以用于 可迭代對象 去重逢渔,例如數(shù)組去重肋坚,字符串去重∷嗬或者需要使用Set方法的地方也可以轉(zhuǎn)換成Set
Map
Map 和對象都是鍵值對的集合智厌。
Map 和對象的區(qū)別:
對象一般用字符串當(dāng)作鍵,Map 可以用所有數(shù)據(jù)類型的值當(dāng)鍵盲赊,包括引用類型铣鹏。
創(chuàng)建一個 Map
使用 Map 構(gòu)造函數(shù) const ma = new Map()
即可創(chuàng)建一個 Map ,創(chuàng)建 Map 時可以傳入一個 entry object (例如二維數(shù)組哀蘑,二維set對象诚卸,map對象),例如:
let arr2d = [
[1,2],
[3,4],
[5,6]
]
const ma = new Map(arr2d);
Map 屬性
size:獲取有幾個鍵值對绘迁,上面的代碼然后 ma.size
會返回3.
Map 的方法
方法 | 作用 |
---|---|
set() | 添加新成員 |
get() | 獲取成員 |
has() | 判斷是否有這個成員返回布爾值 |
delete() | 刪除成員合溺,如果沒有則無事發(fā)生也不報(bào)錯 |
clear() | 清除所有成員 |
forEach() | 遍歷成員 |
set
可連續(xù)使用,例如 new Map().set(9,8).set(7,6)
缀台,當(dāng)后添加的成員與前添加的鍵名一樣時棠赛,后添加的會覆蓋前添加的。
get
獲取成員膛腐,當(dāng)獲取不存在的成員時返回 undefined
Map 其他注意事項(xiàng)
Map 重復(fù)鍵名的判斷方式遵循全等原則睛约,NaN例外。
Map 用途
當(dāng)你只需要鍵值對結(jié)構(gòu)時哲身,或者需要Map的方法時辩涝,或者使用字符串以外的值做鍵時。
ES6其他新增技巧
對象字面量增強(qiáng)
- 屬性的簡潔表示法:已定義的變量或常量勘天,可以直接寫進(jìn)對象里當(dāng)其屬性怔揩,例如:
let name = 'mingzi';
let obj = {name}; //等同于let obj = {name:name}
obj.name //直接返回 'mingzi'
- 方法的簡潔表示法:對象的方法可以省略冒號和 function 關(guān)鍵字棍丐,例如:
//const obj = { func : function(){} }
const obj = { func(){} }
- 方括號語法可以寫在對象字面量里,方括號可以注入變量值沧踏,運(yùn)算值等产禾,例如:
let bianliang = 'x'
const obj = {
[bianliang] : 18;
}
obj.x //返回18
函數(shù)參數(shù)的默認(rèn)值
可以給函數(shù)的參數(shù)設(shè)置一個默認(rèn)值泣崩,例如:
function xjiay(x=1,y=2){
return x+y
}
xjiay()
//直接執(zhí)行不傳參數(shù)則使用默認(rèn)值
- 生效條件:不傳參或者傳的是undefined的時候闰歪,默認(rèn)值才會生效护糖。
- 同樣擁有惰性求值特性货裹。
ES6 其他新增方法
ES6字符串新增方法
includes() 方法
用于判斷字符串是否有某些字符沉噩。
用法:第一個參數(shù)傳入的是一個值谚咬,返回布爾值判斷字符串內(nèi)是否有這個值横殴。第二個參數(shù)表示開始搜索的位置赚导。
startsWith() 和 endsWith
用于判斷參數(shù)是否在字符串的頭部和尾部茬缩,返回布爾值。
例如 abcd.startsWith('ab') 返回true吼旧,abcd.endsWith('cd')返回true
repeat()
repeat() 方法返回一個新的字符串凰锡,表示將源字符串重復(fù)n次。例如:
'rero'.repeat(4);
//輸出rerorerorerorero
參數(shù)如果不是整數(shù)會自動向下取整圈暗,為0次則不輸出內(nèi)容掂为,為負(fù)數(shù)則報(bào)錯
padStart() 和 padEnd()
pad是填充的意思,用于補(bǔ)全字符串長度员串,無法改變原字符勇哗。
用法:
- 第一個參數(shù)表示“需要補(bǔ)到的長度”是多少,通常是一個整數(shù)寸齐。
- 第二個參數(shù)表示“補(bǔ)入的值”欲诺,如果不傳參數(shù)2,默認(rèn)使用空格代替渺鹦。
- 如果第一個參數(shù)小于或等于原字符串長度扰法,則補(bǔ)全不生效,返回原字符串海铆。
- 如果第二個參數(shù)補(bǔ)入的值長度迹恐,補(bǔ)入后總長度不滿足第一個參數(shù),則循環(huán)再補(bǔ)卧斟,補(bǔ)到滿足長度殴边。
- 如果第二個參數(shù)補(bǔ)入的值長度,補(bǔ)入后總長度超過第一個參數(shù)珍语,則只補(bǔ)需要補(bǔ)的長度锤岸,后面的截去。
padStart() 是從頭部開始補(bǔ)板乙, padEnd() 是從尾部開始補(bǔ)是偷。例如:
'x'.padStart(5,'ab') //返回 'ababx'
'y'.padEnd(5,'6688') //返回 'y6688'
trimStart() 和 trimEnd()
trim是去掉不必要部分的意思拳氢,用于清除字符串的首或尾的空格,中間的空格不會清除蛋铆。
trimStart() 等同于 trimLeft() 馋评,trimEnd() 等同于 trimRight()。
同時去除頭尾空格的方法為 trim()刺啦。
matchAll()
matchAll() 方法返回一個正則表達(dá)式在當(dāng)前字符串的所有匹配
返回的是?個遍歷器(Iterator)留特,?不是數(shù)組。
ES6數(shù)組新增方法
includes()
數(shù)組的 includes() 方法玛瘸,可以判斷數(shù)組中是否含有某個成員蜕青,判斷基于全等原則,NaN除外糊渊。第一個參數(shù)傳入的是一個值右核,返回布爾值判斷數(shù)組內(nèi)是否有這個值。第二個參數(shù)表示開始搜索的位置渺绒。
Array.from()
Array.from() 可以將 可迭代對象 和 類數(shù)組對象 轉(zhuǎn)換成數(shù)組贺喝。
- 第一個參數(shù)表示的是要轉(zhuǎn)換的對象。本來是什么類型的值宗兼,如果沒發(fā)生顯式或隱式類型轉(zhuǎn)換搜变,轉(zhuǎn)換后數(shù)組的每個成員還是原來的類型。
- 第二個參數(shù)是一個回調(diào)函數(shù)针炉,用于將轉(zhuǎn)換后的數(shù)組內(nèi)的每一個成員進(jìn)行處理然后返回新數(shù)組挠他。例如
Array.from('01',(count)=>{return Boolean(count)})
將成員轉(zhuǎn)成布爾類型。例如Array.from('12',(count)=>{return count*2})
將成員每個乘以2篡帕。 - 第三個參數(shù)指定/修改this指向
Array.of()
Array.of()方法用于將一組值轉(zhuǎn)化為數(shù)組殖侵,即新建數(shù)組,而不考慮參數(shù)的數(shù)量或類型镰烧。
//使?Array.of()創(chuàng)建數(shù)組
console.log(Array.of()); //[] 創(chuàng)建?個空數(shù)組
console.log(Array.of(8)); //[8] 創(chuàng)建只有?個元素值為8的數(shù)組 console.log(Array.of(1, 2, 3)); //[1,2,3] 創(chuàng)建?個值為1拢军,2,3的數(shù)組
//以前直接使?Array創(chuàng)建數(shù)組
console.log(Array()); //[] 創(chuàng)建?個空數(shù)組
console.log(Array(4)); // [ , , , ] 創(chuàng)建擁有4個元素空值的數(shù)組
console.log(Array(1, 2, 3)); //[1,2,3] 創(chuàng)建?個值為1怔鳖,2茉唉,3的數(shù)組
find() 和 findIndex()
find() 方法找到滿足條件的第一個立即返回這個值。
findIndex() 方法找到滿足條件的第一個立即返回其索引结执。
- 第一個參數(shù)是一個回調(diào)函數(shù)度陆,回調(diào)函數(shù)的參數(shù)分別為 (1)可遍歷對象鍵值對的值 (2)可遍歷對像鍵值對的鍵 (3)可遍歷對像本身∠揍#可以在這個函數(shù)里指定規(guī)則懂傀。
- 第二個參數(shù)是回調(diào)函數(shù)里面的 this 指向
some() 和 every()
ARR.every() 和 ARR.every() 目的:確定數(shù)組的所有成員是否滿足指定的測試
- some() 方法:只要其中一個為true 就會返回true。
- every() 方法:必須所有都返回true才會返回true蜡感,哪怕有一個false蹬蚁,就會返回false.
const data =[
{name:'zhangsan',age:22,sex:'man'},
{name:'lisi',age:25,sex:'woman'},
{name:'wangwu',age:23,sex:'man'},
];
//使?some判斷data中是否含有?條name以"wang"開頭的
let s1 = data.some(v => v['name'].startsWith("wang"));
console.log(s1); //true
//使?every判斷data信息中是否都是age?于20的信息恃泪。
let s2 = data.every(v => v['age']>20);
console.log(s2); //true
若有?個不符合則返回false
fill()
ARR.fill() 函數(shù),使用指定的元素替換原數(shù)組內(nèi)容犀斋,會改變原來的數(shù)組贝乎。
參數(shù)一:要改變成的內(nèi)容;參數(shù)二:要改變的開始位置叽粹;參數(shù)三:要改變的結(jié)束位置糕非。
//空數(shù)組則沒有替換
console.log([].fill(6)); //[]
//將數(shù)組中的值都替換成指定值6
console.log([1,2,3].fill(6));//(3) [6, 6, 6]
//從數(shù)組索引位置2開始替換成指定值6,替換到數(shù)組結(jié)束位置球榆。
console.log([1,2,3,4,5].fill(6,2)); //(5) [1, 2, 6, 6, 6]
//從數(shù)組索引位置2開始替換到索引位置4前結(jié)束。
console.log([1,2,3,4,5].fill(6,2,4)); //(5) [1, 2, 6, 6, 5]
ES6對象新增方法
Object.assign()
Object.assign() 作用是合并對象
傳入的參數(shù)為多個對象禁筏。本質(zhì)是將后面參數(shù)的對象合并到第一個參數(shù)中持钉,會改變第一個參數(shù)自身。如果不想改變?nèi)魏螀?shù)篱昔,可以在第一個參數(shù)寫一個空對象每强,例如: Object.assign({},obj1,obj2)
注意事項(xiàng):基本數(shù)據(jù)類型作為源對象時,會先轉(zhuǎn)換成對象州刽,再合并空执。合并時如果出現(xiàn)同名屬性,后面的會把前面的覆蓋穗椅。
Object.keys() 辨绊、Object.values() 、 Object.entries()
這三個方法都是Object構(gòu)造函數(shù)上的匹表, 傳入的參數(shù)是一個對象门坷,執(zhí)行后分別返回鍵名組成的數(shù)組、值組成的數(shù)組袍镀、鍵值對組成的數(shù)組默蚌。
為什么返回的不是 可迭代對象 ?因?yàn)?keys 是ES5的方法苇羡,ES5 中沒有 Iterator 的概念绸吸,所以為了統(tǒng)一,Object 的這三個方法返回的都是數(shù)組设江。
Object.fromEntries()
是 Object.entries() 的逆操作锦茁,將可迭代對象作參數(shù)傳入Object.fromEntries()中,會返回一個對象叉存。
Object.is()
- ES5 ?較兩個值是否相等蜻势,只有兩個運(yùn)算符:相等運(yùn)算符(==)和嚴(yán)格相等運(yùn)算符(===)。 它們都有缺點(diǎn)鹉胖,前者會?動轉(zhuǎn)換數(shù)據(jù)類型握玛,后者的NaN不等于?身够傍,以及+0等于-0。 JavaScript 缺乏?種運(yùn)算挠铲,在所有環(huán)境中冕屯,只要兩個值是?樣的,它們就應(yīng)該相等拂苹。
- ES6 提出“Same-value equality”(同值相等)算法安聘,?來解決這個問題。 Object.is就是部署這個算法的新?法瓢棒。它?來?較兩個值是否嚴(yán)格相等浴韭,與嚴(yán)格?較運(yùn)算符 (===)的?為基本?致。
Object.is('foo', 'foo') // true
Object.is({}, {}) //false
+0 === -0 //true
NaN === NaN // false
Object.is(+0, -0) // false
Object.is(NaN, NaN) // true
Object.getOwnPropertyDescriptors()
ES5 的Object.getOwnPropertyDescriptor()?法會返回某個對象屬性的描述對象 (descriptor)脯宿。 ES2017 引?了Object.getOwnPropertyDescriptors()?法念颈,返回指定對象所有?身屬性(?繼承 屬性)的描述對象
const obj = { foo: 123, get bar() { return 'abc' } };
Object.getOwnPropertyDescriptors(obj);
// { foo:
// { value: 123,
// writable: true,
// enumerable: true,
// configurable: true },
// bar:
// { get: [Function: get bar],
// set: undefined,
// enumerable: true,
// configurable: true } }
、proto屬性连霉,Object.setPrototypeOf()和Object.getPrototypeOf()
JavaScript 語?的對象繼承是通過原型鏈實(shí)現(xiàn)的榴芳。ES6 提供了更多原型對象的操作?法。 具體詳??檔
Object.defineProperty
參數(shù)一:給誰添加屬性
參數(shù)二:添加屬性的屬性名
參數(shù)三:配置項(xiàng)跺撼,是一個對象窟感,其中包括value。
此方法定義的屬性默認(rèn)是不可枚舉/遍歷的歉井,可在配置項(xiàng)里修改enumerable:true
開啟遍歷柿祈。
定于的屬性默認(rèn)是不可以被修改的,可在配置項(xiàng)修改 writable:true
開啟修改
定義的屬性默認(rèn)是不可以被刪除的哩至,可在配置項(xiàng)修改 configurable:true
開啟刪除
類與對象
class (類)
- Javascript 的類谍夭,寫法為
class 類名{ }
注意沒有圓括號和分號。
- 類也可以是匿名的憨募,所以可以用表達(dá)式形式定義類
const 類名 =class{ }
-
type of 類
返回的也是一個 function 紧索,類里的方法本質(zhì)上也是相當(dāng)于寫在這個 function 上的 prototype 上,所以 class 是構(gòu)造函數(shù)的語法糖菜谣。
所以衍生出了“立即執(zhí)行類”珠漂,例如:
//加new因?yàn)閏onstructor必須要有new才能執(zhí)行。
(new class {
constructor(){
執(zhí)行語句;
}
})
constructor
class里的構(gòu)造方法 constructor 用法尾膊,如下:
class 類名{
constructor(參數(shù)1,參數(shù)2...參數(shù)n){
this.屬性名1 = 參數(shù)1;
this.屬性名2 = 參數(shù)2
}
}
- 構(gòu)造方法 constructor 里面的 this 直接指向?qū)嵗鰜淼膶ο蟆?/li>
- 構(gòu)造方法 constructor 里面一般不定義方法媳危,只定義屬性,因?yàn)?constructor 里的方法會使每個實(shí)例都新生成一個自己的方法冈敛,占用新內(nèi)存待笑。
- 所以共享的方法直接寫在類里即可,不用寫在 constructor 里面抓谴,注意寫法暮蹂,方法與方法之間沒有逗號寞缝,直接寫
方法名(){ }
即可,不用加function關(guān)鍵字仰泻,例如:
class 類名{
constructor(參數(shù)1,參數(shù)2...參數(shù)n){
this.屬性名1 = 參數(shù)1;
this.屬性名2 = 參數(shù)2
}
方法1 (){ }
方法2 (){ }
}
類的方法(靜態(tài)方法)
使用關(guān)鍵字 static 荆陆,寫在聲明里,是只有類可以訪問的集侯,實(shí)例無法訪問被啼,例如:
//static 靜態(tài)方法名(){}
class Lei{
static func(){
console.log('靜態(tài)方法')
}
}
Lei.func()
類的屬性(靜態(tài)屬性)
有三種方法:
- 類名.屬性名 = 值
- 聲明里寫 static 靜態(tài)方法(){return 值;}
- 聲明里直接寫 static 靜態(tài)屬性 = 值
方法3存在兼容性問題,低版本瀏覽器不支持棠枉。
實(shí)例對象
如何創(chuàng)建一個實(shí)例:
new 類名();
即可生成一個實(shí)例對象浓体,這個實(shí)例對象會擁有 class 里面的 constructor 的屬性。例如
class Person{
constructor(a,b){
this.name = a;
this.age = b;
}
}
const student = new Person('ming',24);
這個 student 就會擁有 name 和 age 屬性辈讶,屬性值是什么取決于你寫的是定值還是參數(shù)命浴。
也可以給屬性值添加默認(rèn)值(截至2021年7月默認(rèn)值已失效)
JS 類與對象 的私有屬性和方法
想要實(shí)現(xiàn)私有,可以使用閉包實(shí)現(xiàn)荞估,或者利用模塊化。
class 繼承
使用關(guān)鍵字 extends 和關(guān)鍵字 super 稚新,例如:
class Person{
constructor(a,b){
this.name = a;
this.age = b;
}
func(){console.log(1)}
}
class Student extends Person{
}
此時 Student 這個類就會擁有 Person 的所有構(gòu)造方法和共享方法勘伺。
子類如果想要擁有自己的構(gòu)造方法,則必須配合 super 關(guān)鍵字使用褂删,否則會報(bào)錯飞醉;
super 前面不能放任何this操作,否則報(bào)錯屯阀。例如
class Person{
constructor(a,b){
this.name = a;
this.age = b;
}
func(){console.log(this.name)}
}
class Student extends Person{
constructor(x,y,c){
super(x,y)
//這里super接收的參數(shù)會扔到父類的constructor中執(zhí)行缅帘,this指向子類實(shí)例
this.newProp = c
}
}
子類想要使用父類的方法,子類調(diào)用的父類方法里的this指向的是父類难衰,所以要在之類的構(gòu)造方法里使用super
class 中的 super 關(guān)鍵字
- 在構(gòu)造方法和一般方法中使用钦无,super 代表的都是父類的原型 SUPERCLASS.prototype
- 在靜態(tài)方法 static FUNCTION(){} 中使用,代表的是父類自身盖袭,this 指向子類失暂。
- super 要么接點(diǎn)要么接括號,否則瀏覽器會報(bào)錯鳄虱。
class中的get和set
當(dāng)實(shí)例調(diào)用讀取父類方法時會觸發(fā)get方法弟塞,get方法里面返回的值就是觸發(fā)后返回的值
當(dāng)實(shí)例修改父類方法時會觸發(fā)set方法,set方法必須帶有一個形參
class Phone{
get price(){
console.log('價格屬性被讀取了')
return 'iloveyou'
}
set price(newVal){
console.log('價格被修改了')
}
}
let s = new Phone()
console.log(s.price); //這里會觸發(fā)get price并得到里面的返回值
s.price = 'free'; //這里會觸發(fā)set
Module 模塊系統(tǒng)
模塊系統(tǒng)解決的主要問題:
- 模塊化的問題拙已。
- 消除全局變量决记。
- 管理加載順序。
import倍踪、export系宫、export default 和 script type='module'
- 只要你會用到 import 或 export 索昂,在使用 script 標(biāo)簽加載的時候,就要使用
<script type='module'></script>
- 一個模塊如果沒有導(dǎo)出笙瑟,也可以直接將其導(dǎo)入楼镐,被導(dǎo)入的代碼都會執(zhí)行一遍,多次導(dǎo)入同一個模塊也只執(zhí)行一遍往枷,但無法使用模塊的東西框产。
export default
export default 可以直接接模塊里的定變量名,類或類名错洁,方法或方法名等秉宿。
- 注意一個模塊只能有一個 export default
- 注意 export default 導(dǎo)出的東西是按語句順序執(zhí)行的,沒有提升屯碴。
export default 的 import 直接寫導(dǎo)出的東西然后命名即可描睦,名字可以隨便取。
export
export 導(dǎo)出可以有兩種形式导而。
- 接聲明或語句忱叭,例如
export let a = 'cosin'
- 接大括號,例如
export {導(dǎo)出1,導(dǎo)出2}
export 的 import 只能用大括號接收今艺,例如import{導(dǎo)出1,導(dǎo)出2}
如果導(dǎo)出或?qū)氲臇|西想改名稱韵丑,可以使用 as
關(guān)鍵字,例如:
export {name as newName} //此時import 接收的是 newName
import{newName as newnew}
import
import三種形式導(dǎo)入
- 通用形式導(dǎo)入虚缎,用as后接一個名字當(dāng)作接受的對象
import * as m1 from './js/m1.js'
console.log(m1.name)
m1.fn()
- 解構(gòu)賦值形式導(dǎo)入
import {name,fn} from './js/m1.js'
import {name as mingzi,fn as fangfa} from './js/m2/js'
import {default as mod} from './js/m3.js'
- 簡便形式 僅針對 export deafault 默認(rèn)暴露
import m3 from './js/m3.js'
同時導(dǎo)入
因?yàn)?export 和 export default 的導(dǎo)入方式不同撵彻,所以想一次導(dǎo)入這兩種導(dǎo)出,可以使用:
import default導(dǎo)出的,{非default導(dǎo)出} from '路徑'
- 采用整體導(dǎo)入实牡,使用通配符 * 星號然后接 as 然后接一個名字陌僵,就代表導(dǎo)入所有導(dǎo)出的,包括 export 和 export default 的创坞,例如:
import * as obj from './module.js'
導(dǎo)入的內(nèi)如是一個 Module 對象碗短,導(dǎo)出的東西都會變成這個 Module 對象的屬性,default 的內(nèi)容會變成 default 屬性
Module 注意事項(xiàng)
- 導(dǎo)入的變量是只讀的题涨,導(dǎo)入的對象的屬性值可以修改豪椿。
- 一個模塊可以直接寫export,即導(dǎo)入后直接導(dǎo)出携栋,此時這個模塊不可以使用導(dǎo)入的任何東西搭盾,相當(dāng)于一個中轉(zhuǎn)站。
- import 和 export 命令具有提升效果婉支,會提升到整個模塊的頭部并率先執(zhí)行鸯隅。所以 import 和 export 別寫在代碼塊中,想要按條件導(dǎo)入,可以使用 import() 函數(shù)蝌以。
- 模塊頂層的 this 指向 undefined 炕舵,可以利用這點(diǎn)提示使用模塊加載,例如:
if(type of this !== 'undefined'){
throw new Error('請使用模塊加載')
}
ES6 數(shù)值拓展
Number.EPSILON
Number.EPSILON是 Javascript表示的最小進(jìn)度跟畅,可以用來做浮點(diǎn)運(yùn)算判斷 咽筋、
fuction equal(a,b){
if(Math.abs(a-b)<Number.EPSILON){
return true;
}else{
return false;
}
}
console.log(equal(0.1+0.2,0.3))
Number.isFinite 檢測一個數(shù)值是否為有限數(shù)
console.log(Number.isFinite(100))
Number.isNaN
isNaN舊方法扔進(jìn)Number中
Math.trunc()
將數(shù)字(參數(shù))的小數(shù)部分抹掉
Math.sign()
判斷參數(shù)是正數(shù)、負(fù)數(shù)徊件、還是0
直接書寫N進(jìn)制數(shù)字
let b = 0b1010
let o = 0o777
ES7 新特性
includes
可以檢測數(shù)組是否擁有該組員
兩個星號(乘號)
兩個星號后面接的數(shù)字代表幾次方奸攻,2 ** 10 類似于 Math.pow(2,10)
ES8
async 函數(shù)
在函數(shù)前面加上 async 關(guān)鍵字
async function fn(){
}
async函數(shù)返回結(jié)果是一個promise,返回的promise狀態(tài)由內(nèi)容決定
- 如果返回的東西是一個Promise對象虱痕,則由該promise決定成功還是失敗
- 如果返回結(jié)果是拋出一個錯誤睹耐,則狀態(tài)為失敗reject,例如 throw new Error('err')
- 其他返回結(jié)果大多為成功resolve/fulfilled
await
- await 要放在 async 函數(shù)中
- await 右側(cè)的表達(dá)式一般為 promise 對象
- await 返回的是 promise 成功的值
- await 的 promise 失敗了部翘,就會拋出異常硝训,需要使用 try{}catch{} 捕獲
ES9
正則捕獲分組
?<>
方向斷言
?<=
dotAll 拓展
結(jié)尾加上s
ES10
數(shù)組拓展 flat
將多維數(shù)組轉(zhuǎn)化為低維數(shù)組
ARR.flat()
參數(shù)是數(shù)字,意義為展開深度為幾層新思,例如三維轉(zhuǎn)一維窖梁,深度就是3-1=2
數(shù)組拓展 flatMap
如果數(shù)組使用map之后返回一個多元數(shù)組,flatMap則是把多元數(shù)組變回一維數(shù)組夹囚,
ARR.flatMap() 就是數(shù)組的map方法和flat方法結(jié)合
Symbol.prototype.description
let sb = Symbol('HQM')
sb.description
ES11
對象的私有屬性
在屬性前面加上井號
class Person{
name;
#age;
#weight;
constructor(name,age,weght){
this.name = name;
this.#age = age;
this.#weight = weight;
}
}
const girl = new Person('hong',18,'45kg')
console.log(girl.#age) //此時會報(bào)錯纵刘,私有屬性不能在外部直接訪問,可以在類定義一個內(nèi)部方法通過內(nèi)部方法訪問
Promise.allSettled
- Promise.all 是有一個失敗則直接返回失敗崔兴。
- 而 Promise.allSettled 是無論成功還是失敗都會把所有參數(shù)里的Promise全部執(zhí)行完再返回結(jié)果彰导。結(jié)果都是成功
- Promise.allSettled() 和 Promise.all() 的參數(shù)都是一個可迭代對象(通常為數(shù)組)
可選鏈操作符
?.
當(dāng)一個函數(shù)的參數(shù) 是一個對象的時候蛔翅,如果要找傳入的對象是否有這個值敲茄,一般需要層層判斷,有了可選鏈操作符山析,直接使用 ?. 即可堰燎,不會報(bào)錯
const fn = (config) => {
console.log(config.db.a1);
}
fn({
db: {
a1: '111',
a2: '222'
}
})
//如果有這個參數(shù)則不會報(bào)錯
const fn = (config) => {
console.log(config.db.a1);
}
fn()
//如果沒有這個參數(shù)則報(bào)錯,只能使用 config&&config.db&&config.db.a1
有了可選鏈操作符笋轨,只需要這樣即可
console.log(config?.db?.a1)
動態(tài)import
主要用來提升性能秆剪,動態(tài)import就是不在文件頭部使用import導(dǎo)入模塊,而是使用import()這個函數(shù)在使用的時候才導(dǎo)入爵政,函數(shù)的參數(shù)就是導(dǎo)入這個模塊的路徑仅讽。
導(dǎo)入執(zhí)行之后返回的是一個Promise,用then后的回調(diào)函數(shù)的參數(shù)接收此模塊
BigInt() 大整數(shù)
在整數(shù)后面加一個字母n钾挟,就是大整型數(shù)據(jù)類型
let bi = 521n
console.log(bi,typeof bi)
使用 BigInt() 方法洁灵,往里面穿一個整型數(shù)字,就會轉(zhuǎn)變?yōu)榇笳蛿?shù)字
let norm = 123
console.log(BigInt(norm))
運(yùn)用場景是大數(shù)值運(yùn)算掺出,BigInt不能和普通Int做運(yùn)算
let max = Number.MAX_SAFE_INTEGER
console.log(max)
console.log(max+1)
console.log(max+2)
//此時就會計(jì)算丟失精度
console.log(BigInt(max))
console.log(BigInt(max)+BigInt(1))
console.log(BigInt(max)+BigInt(2))
//使用BigInt之后就沒有問題