一、javascript簡介
輕量級 弱類型 腳本語言
js就是通過固定的語法來操作 瀏覽器和 頁面結(jié)構(gòu) 來實現(xiàn)網(wǎng)頁中的各種效果
1.1 javascript組成部分
ECMAScript:定義了 javascript 的語法規(guī)范
BOM:(browser object model)瀏覽器對象模型
瀏覽器有一套成熟的 API 方法粪狼,通過 BOM 來操作瀏覽DOM(document objectmodel)文檔對象模型
簡介有一套成熟的可以操作頁面元素的 API 方法退腥,通過 DOM 可以操作頁面元素
1.2 javascript書寫位置
1.2.1 行內(nèi)式 (一般不使用)
在 a 標(biāo)簽的 href 屬性中書寫代碼
javascript:js代碼;
或者在標(biāo)簽里書寫 onclick 然后書寫 JS 代碼
<!-此處的js寫法常用于a標(biāo)簽的阻止瀏覽器默認(rèn)跳轉(zhuǎn) -->
<a href="javascript:;">點一下但是不跳轉(zhuǎn)</a>
<div onclick='alert("點擊")'></div>
1.2.2 內(nèi)嵌式
js代碼書寫在 script 標(biāo)簽內(nèi)
瀏覽器打開的頁面的時候,會立即執(zhí)行script標(biāo)簽中的js代碼
script標(biāo)簽中的 type="text/javascript" 屬性可以省略
一個頁面中可以書寫多對script標(biāo)簽,但是script不能嵌套使用
<script>
alert('內(nèi)嵌')
</script>
1.2.3 外鏈?zhǔn)?/h3>
script標(biāo)簽的src屬性中 書寫js文件的路徑地址
利于 HTML 頁面代碼結(jié)構(gòu)化再榄,把大段 JS 代碼獨立到 HTML 頁面之外狡刘,既美觀,也方便文件級別復(fù)用
引用外部 JS 文件的 srcipt 標(biāo)簽中間不可寫代碼
適用 JS 代碼量比較大的情況困鸥,開發(fā)常用
<script src="./test.js"></script>
二嗅蔬、javascript基礎(chǔ)語法
2.1 JS 注釋
在 JS 中有兩種注釋方式
注釋就是不會執(zhí)行的內(nèi)容,注釋是給程序員看的
2.1.1 單行注釋
// 編輯器快捷方式 Ctrl+/
// alert('666')
2.1.2多行注釋
/*
編輯器中默認(rèn)的是shift+Ctrl+a
alert('666')
alert('666')
alert('666')
alert('666')
*/
2.2 JS中常見的頁面輸出方式
2.2.1 彈窗輸出
alert(內(nèi)容) 提示彈窗輸出內(nèi)容
confirm(內(nèi)容) 確認(rèn)彈窗
返回值: 返回值就是 點擊確定為true 取消為false
prompt(輸入問題) 提問彈窗
返回值: 輸入啥內(nèi)容點擊確定時候返回值就是什么內(nèi)容,如果點擊取消則返回null
2.2.2 控制臺輸出
console.log(內(nèi)容) 在瀏覽器的控制臺中輸出內(nèi)容
2.2.3 頁面輸出
document.write(內(nèi)容) 在瀏覽器頁面中輸出內(nèi)容,會將內(nèi)容寫到頁面的body標(biāo)簽中
注意: 此方法會將內(nèi)容寫到body標(biāo)簽中,如果寫入的內(nèi)容有html標(biāo)簽,則頁面可以識別對應(yīng)的標(biāo)簽內(nèi)容
2.3 變量
在 js 程序中,變量是用來幫我們存儲中間值
注意: 在 js 中 一個等號表示賦值 將等號右邊的值 賦值給左邊
2.2.1 如何定義變量
定義變量:通過關(guān)鍵字 var 變量名
注意:一個變量中只能存儲一個值
var age // 表示定義了一個變量,名字為 age
var age = 100 // 表示定義了一個 age 變量并且賦值為 100
var age,username,gender // 一次定義多個變量
age = 100 // 給已經(jīng)定義的變量賦值
var age = 17,username='小斌',gender='男' // 定義多個變量并賦值
// 使用定義的變量來接收 提問彈窗的返回值
var age = prompt('你多大?');
// 在控制臺中將變量中的值輸出
console.log( age );
// ! 注意 一個變量中只能存儲一個值
var age = 100 // 定義 age 變量并賦值 100
age = 666 // 此時將 666 賦值給變量 age 中,則 age 中原來的值被覆蓋了
console.log( age )
2.2.2 變量名命名規(guī)則和規(guī)范
規(guī)則:死的無條件遵守疾就,服從命令為準(zhǔn)則
規(guī)范:如同道德品行澜术,盡量遵守
(1) 變量名的命名規(guī)則(必須遵守)
變量名只能由:數(shù)字 字母 下劃線 $ 組成
變量名不能以數(shù)字開頭
不能使用關(guān)鍵字和保留字為變量名
變量名不能有空格,不要使用中文
嚴(yán)格區(qū)分大小寫
(2) 變量名的規(guī)范(大家默認(rèn)遵守)
變量名盡量語義化
如果變量名由多個字母組成則盡量使用小駝峰命名(第一個單詞首字母小寫猬腰,后續(xù)單詞首字母大寫)
2.4 數(shù)據(jù)類型
基本數(shù)據(jù)類型:number string boolean undefined null
復(fù)雜數(shù)據(jù)類型(引用數(shù)據(jù)類型):object array function...(不展開講)
2.4.1 基本數(shù)據(jù)類型
(1) number 數(shù)值類型
取值: 數(shù)字 小數(shù),NaN...等等
NaN 表示這個數(shù)據(jù) 不是一個數(shù),但 NaN 是 number 數(shù)據(jù)類型
(2) string 字符串類型
取值:string
在 js 中所有使用單引號或雙引號包裹的都是字符串類型
(3) boolean 布爾類型
取值: true(真)鸟废,false(假)
(4) undefined 未定義,未賦值
取值: undefined
當(dāng)定義了一個變量,但是沒有賦值,此時變量的值就是 undefined
(5) null 空
取值: null
2.4.2 判斷數(shù)據(jù)類型
(1) 語法1: typeof 變量
// 定義了一個變量res來接收 typeof 變量 執(zhí)行的結(jié)果(返回值)
var res = typeof num
console.log( res ) // 'number'
(2) 語法2: typeof(變量)
var res = NaN
console.log( typeof res ) // 'number'
返回值: 通過字符串表示變量中數(shù)據(jù)的類型
注意: typeof 語法只能獲取基本數(shù)據(jù)類型,而且null類型獲取不到
var num = 100
var str = '小斌'
var flag = true
var und = undefined
var nul = null
console.log( typeof(num) ) // 'number 字符類型'
console.log( typeof(str) ) // 'string 字符串類型'
console.log( typeof(flag) ) // 'boolean 布爾類型'
console.log( typeof(und) ) // 'undefined 未定義類型'
console.log( typeof(nul) ) // 'object 空'
(3) 判斷一個值,是否是NaN
語法: isNaN(變量)
作用: 判斷這個變量的值,是否是一個非數(shù)字
返回值: 布爾類型
如果變量是一個數(shù),則返回 false
如果變量不是一個數(shù),則返回 true
注意: 此語法默認(rèn)會將變量中的值進行一次 隱式轉(zhuǎn)換(轉(zhuǎn)為數(shù)值)
var num = 100
console.log(isNaN(num)) // false
var num = 'xiaobin'
console.log(isNaN(num)) // true
2.4.3 數(shù)據(jù)類型的轉(zhuǎn)換(轉(zhuǎn)為數(shù)值類型)
(1) Number()
語法: Number(變量)
作用:將變量中的值轉(zhuǎn)為數(shù)值類型(無論是整數(shù)還是小數(shù)都可以轉(zhuǎn)換)
返回值: 轉(zhuǎn)換后的數(shù)字,或者NaN
注意: 將變量中的值轉(zhuǎn)為數(shù)值,只能轉(zhuǎn)數(shù)字,或小數(shù)數(shù)字
var str = '1234'
var res = Number(str)
console.log( res ) // 1234
console.log( typeof res ) // number
(2) parseInt()
語法: parseInt(變量) 將變量中的值轉(zhuǎn)為整數(shù)
返回值: 轉(zhuǎn)換后的整數(shù),或則NaN
轉(zhuǎn)換的時候,從數(shù)據(jù)的第一位開始轉(zhuǎn)換,直到遇見非數(shù)字,則停止轉(zhuǎn)換
(3) parseFloat()
語法: parseFloat(變量) 將變量轉(zhuǎn)為數(shù)值,可以轉(zhuǎn)小數(shù)
返回值: 數(shù)字,或 NaN
和parseInt一樣的轉(zhuǎn)換規(guī)則,只不過parseFolat可以識別一個小數(shù)點
(4) 隱式轉(zhuǎn)換
除了加號之外的 數(shù)學(xué)運算符(-,*,/,%) 會將變量中的值轉(zhuǎn)為數(shù)值類型,然后再運算
運算中的隱式轉(zhuǎn)換,就是在與那算之前會偷偷的將變量中的值 通過Number()方法轉(zhuǎn)為數(shù)值然后再進行運算
var num = '1000';
var res = num 0;
// 在運算之前,會隱式的將num中的值轉(zhuǎn)為數(shù)值類型,然后在運算
console.log( res ) //1000
console.log( typeof res ) // 'number'
2.4.4 數(shù)據(jù)類型的轉(zhuǎn)換(轉(zhuǎn)為字符串)
(1) String
語法: String(變量) 將變量中的值轉(zhuǎn)為字符串類型的值
返回值: 轉(zhuǎn)換后的字符串
var flag = true
console.log( String(flag) )// 'true'
(2) toString()
語法: 變量.toString() 將變量的值 轉(zhuǎn)為字符串類型 然后返回
返回值: 轉(zhuǎn)換后的字符串
注意: undefined 和 null 數(shù)據(jù)類型的變量不可以使用 toStirng 方法
(3) 加號
加號作用:1. 數(shù)學(xué)運算 2.字符串拼接
2.4.5 數(shù)據(jù)類型的轉(zhuǎn)換(轉(zhuǎn)為布爾類型)
(1) Boolean()
語法:Boolean(變量) 將變量中的值轉(zhuǎn)為布爾值然后返回
返回值: 轉(zhuǎn)換后的布爾值
在js中只有 1.空字符串 2.數(shù)值0 2.數(shù)值NaN 4.undefined 5.null 的值為false,其他別的數(shù)據(jù)轉(zhuǎn)換都是true
以后遇見任何 其他數(shù)據(jù)類型隱式轉(zhuǎn)為布爾值 都是隱式的調(diào)用了Boolean()方法類型轉(zhuǎn)換
var num1 = 0
var num2 = NaN
var str = ''
var und
var nul = null
console.log( Boolean(num1) ) // false
console.log( Boolean(num2) ) // false
console.log( Boolean(str) ) // false
console.log( Boolean(und) ) // false
console.log( Boolean(nul) ) // false
2.5 運算符
2.5.1 算術(shù)運算符
(1) 運算符
加 +
減 -
乘 *
除 /
取余(取模) %
注意:遵循先乘除后加減有括號要先算的數(shù)學(xué)運算法則
(2) + 特殊運算符
注意: 在 js 中 + 兩邊都是數(shù)值的時候,才是算術(shù)運算
如果 + 兩邊有一邊是字符串,則加號就是 字符串拼接的作用
如果 + 兩邊都是數(shù)值的之后,才進行加法運算
var res = 10 + 20
console.log( res ) // 30
var res1 = 10 + '20'
console.log( res1 ) // 1020
注意: 在js運算中,小數(shù)運算會有精度問題,在js中盡量避免小數(shù)運算
處理方式: 放大倍數(shù)的方式計算,然后縮小倍數(shù)得到結(jié)果
var res2 = (0.3*100 + 0.03*100)/100
console.log( res2 ) // 0.33
2.5.2 賦值運算符
(1) = 賦值
將等號右邊的值 賦值 給左邊的變量
var num = 100
(2) += 加等賦值
var n = 20
n += 20 // 等價于 n = n + 20
console.log( n )//40
var str = 'hello'
str += ' wolrd' // 拼接 str = str + ' wolrd'
console.log( str ) // hello wolrd
(3) -= 減等 *= 乘等 /=除等 %=取余等
var num = 100;
num -= 10; // 等價于 num = num 10
num *= 10; // 等價于 num = num * 10
num /= 10; // 等價于 num = num / 10
num %= 3; // 等價于 num = num % 3
2.5.2 比較運算符
(1) 大小比較
大于 >
小于 <
大于或者等于 >=
小于或者等于 <=
// 比較運算符,組成的表達式,返回值是布爾值
console.log(20 > 10)// true
console.log(20 < 10)// false
console.log(20 >= 20)// true
console.log(20 <= 20)// true
(2) == 等等比較
等等比較的時候,如果兩邊的數(shù)據(jù)類型不一致,則會發(fā)生隱式轉(zhuǎn)換
只會比較兩邊的值(如果兩邊的值都一樣的話則返回true)
undefined和null 等等比較結(jié)果為true,其他任何數(shù)據(jù)和undefined或null比較都是false
數(shù)值NaN和任何數(shù)值比較都為false
如果是布爾值,則會先將布爾值轉(zhuǎn)為數(shù)值,然后比較
布爾值true 轉(zhuǎn)為數(shù)值為1; 布爾值false 轉(zhuǎn)為數(shù)值為0如果一邊是數(shù)值,則另一邊的值 隱式轉(zhuǎn)會為數(shù)值然后比較
console.log( 'leon' == 'leon' )// true
console.log( 10 == 10 ) // true
console.log( '10' == 10 ) // true
console.log( '10leon' == 10 ) // false
console.log( null == undefined ) // true
console.log( null == 0 ) // false
console.log( undefined == 0 ) // false
console.log( 1 == true ) // true
console.log( 0 == false )// true
console.log( '10leon' == true ) // false
console.log( NaN == NaN ) // false
(3) === 全等比較
只有兩邊的數(shù)據(jù)類型和值都相等的時候才為true
console.log( 10 === '10' ) // false
console.log( '10' === '10' ) // true
(4) != 不等比較
只有兩邊的值不相等,結(jié)果才為true
console.log( 10 != '10' ) // false
console.log( 100 != '10' ) // true
(5) !== 全不等比較
只要兩邊的數(shù)據(jù)類型和值有一個不相等,結(jié)果就是true
console.log( 10 !== '10' ) // true
console.log( '10' !== '101' ) // true
console.log( '10' !== '10' ) // false
2.5.3 邏輯運算符
(1) && 邏輯與
作為條件判斷的時候: && 符號兩邊都為true的時候,最終結(jié)果才為true,只要一邊為false,最終結(jié)果就是false
var res1 = true && true;
var res2 = true && false;
console.log( res1 )// true
console.log( res2 )// false
作為表達式的時候:
&& 符號如果左邊轉(zhuǎn)為布爾值 為false,則左邊的內(nèi)容就是表達式的結(jié)果
&& 符號如果左邊轉(zhuǎn)為布爾值 為true,則右邊的內(nèi)容就是表達式的結(jié)果
var res1 = 0 && 100;
var res2 = undefined && NaN;
var res3 = 100 && null;
var res4 = 100 && 200;
var res5 = (100 < 20) && 200;
console.log(res1) // 0
console.log(res2) // undefined
console.log(res3) // null
console.log(res4) // 200
console.log(res5) // false
(2) || 邏輯或
作為條件判斷的時候: || 符號兩邊都為false的時候,最終結(jié)果才為false,只要又一邊為true,最終結(jié)果就是true
var res1 = false || false;
var res2 = true || false;
console.log( res1 )// false
console.log( res2 )// true
作為表達式的時候:
|| 符號如果左邊轉(zhuǎn)為布爾值 為true,則左邊的內(nèi)容就是表達式的結(jié)果
|| 符號如果左邊轉(zhuǎn)為布爾值 為false,則右邊的內(nèi)容就是表達式的結(jié)果
var r1 = 1000 || 666;
var r2 = 1000 || 0;
var r3 = 0 || NaN;
var r4 = 0 || 888;
console.log(r1) // 1000
console.log(r2) // 1000
console.log(r3) // NaN
console.log(r4) // 888
(3) !變量 取反 邏輯非
返回值: 布爾值
隱式的將變量的值轉(zhuǎn)為布爾值,然后取反
console.log( !0 ) // true
console.log( !NaN )// true
console.log( !'' )// true
console.log( !undefined ) // true
console.log( !null ) // true
console.log( !'0' )// false
2.5.4 自操作運算符
(1) 自增 ++
++變量 前自增
先進行運算,然后才是別的操作
變量++ 后自增
先進行別的操作姑荷,然后才是別的運算
(2) 自減 --
--變量 前自減
先進行運算盒延,然后才是別的操作
變量 后自減
先進行別的操作,然后才是別的運算
var k = 10
var res = k++ + ++k + k++ + k--
// k = 10
// k++ + ++k + k++ + k-===> 10 + ++k + k++ + k-此時k=11
// 10 + ++k + k++ + k===> 10 + 12 + k++ + k此時k=12
// 10 + 12 + k++ + k ===> 10 + 12 + 12 + k 此時k=13
// 10 + 12 + 12 + k ===> 10 + 12 + 12 + 13 此時k=12
// 47
console.log( res ) // 47
console.log( k )//12
2.6 分支結(jié)構(gòu)
流程控制: 代碼的執(zhí)行順序
順序結(jié)構(gòu)和分支結(jié)構(gòu)
分會結(jié)構(gòu): 條件分支 循環(huán)分支
2.6.1 條件分支
(1) if 單分支
單分支,有可能不執(zhí)行對應(yīng)的代碼
語法: if (條件) {條件為 true 執(zhí)行的代碼}
var money = 3000;
if(money < 8000){
console.log( '上班通勤時間為2小時' )
}
(2) if-else 雙分支
雙分支,一定為執(zhí)行一個分支代碼
語法: if (條件) {條件為 true 執(zhí)行的代碼} else {條件為 false 執(zhí)行的代碼}
var age = 27;
if(age >= 18){
console.log( '成年了' )
}else{
console.log( '未成年' )
}
(3) if-else if 多分支
多分支,有可能不執(zhí)行對應(yīng)的代碼
語法: if (條件1) {代碼1} else if (條件2) {代碼2} ......
條件1為true,執(zhí)行代碼1
條件1為false,條件2為true 執(zhí)行代碼2
如果前面的條件為true,則執(zhí)行對應(yīng)的代碼塊,但是不會再判斷后面的條件
判斷輸入的年份是否是普通閏年 還是世紀(jì)閏年 還是平年
var year = prompt('請輸入年份:')
if (year % 4 === 0 && year % 100 != 0) {
console.log(year + '是普通閏年')
} else if (year % 400 === 0) {
console.log(year + '是世紀(jì)閏年')
} else if (!(year % 4 === 0 && year % 100 != 0) && year % 400 != 0) {
console.log( year + '是平年' )
}
(4) if-else if-...else 多分支
多分支,一定為執(zhí)行一個分支代碼
語法: if (條件1) {代碼1} else if (條件2) {代碼2} ......else {代碼n}
條件1為 true,執(zhí)行代碼1
條件1為 false,條件2為 true 執(zhí)行代碼2
如果前面的條件為 false,則執(zhí)行代碼 n
輸入一個1~7,輸出對應(yīng)是星期幾
var num = prompt('請輸入1~7的數(shù)字')
if (num == 1) {
console.log('星期一')
} else if (num == 2) {
console.log('星期二')
} else if (num == 3) {
console.log('星期三')
} else if (num == 4) {
console.log('星期四')
} else if (num == 5) {
console.log('星期五')
} else if (num == 6) {
console.log('星期六')
} else if (num == 7) {
console.log('星期天')
} else {
console.log( '請輸入1~7的數(shù)字' )
}
(5) switch-case 多分支
多分支,有可能不執(zhí)行對應(yīng)的代碼
注意: 1. 變量和 case 后面的值比較,是全等比較(需要比較數(shù)據(jù)類型和值)
注意: 2. break 關(guān)鍵值在 switch 語句中可以不寫,但是如果不寫的話,則代碼會繼續(xù)往下執(zhí)行,知道遇見break,或執(zhí)行結(jié)果,省略 break 的寫法叫做switch 穿透
switch(變量){
case 值1:
// 當(dāng)變量 和 值1 全等的情況執(zhí)行代碼;
break;
case 值2:
// 當(dāng)變量 和 值2 全等的情況執(zhí)行代碼;
break; // break的作用結(jié)束switch語句的執(zhí)行
// ...
default:
// 當(dāng)變量和 上面的值都不相等的時候,執(zhí)行的代碼
}
// 案列
var num = 11;
switch(num){
case 10:
console.log( '第一個case' );
break;
case 11:
console.log( '第二個case' );
// break;
// 如果不寫這個break鼠冕,條件判斷執(zhí)行到此處添寺,switch語句不會結(jié)束,而是繼續(xù)往下執(zhí)行代碼(也不會進行判斷比較),直到遇見break才會結(jié)束
case 12:
console.log( '第三個case' );
break;
case 13:
console.log( '第四個case' );
break;
}
(6) 三元表達式
當(dāng)我們書寫雙分支的時候,可以使用三元表達式
雙分支: if(條件){代碼1}else{代碼2}
三元表達式: 條件?代碼1:代碼2
條件為true則執(zhí)行代碼1,否則執(zhí)行代碼2
// 雙分支案列
var num = 19
if (num >= 18){
console.log( '成年了可以考駕照' );
} else {
console.log( '未成年回家寫作業(yè)' );
}
// 使用三元表達式
var num = 17
num >= 18 ? console.log( '成年了可以考駕照' ) : console.log( '未成年回家寫作業(yè)' );
// 使用三元表達式判斷奇偶數(shù)
var n = Number(prompt('輸入一個數(shù)字判斷奇偶數(shù)'))
if (isNaN(n)) {
console.log('請輸入一個數(shù)字')
} else {
if (n === 0) {
var res = '輸入的是0'
} else {
var res = n % 2 == 0 ? '偶數(shù)' : '奇數(shù)';
}
console.log(res)
}
2.6.2 循環(huán)分支
(1) while 循環(huán)
語法: while (條件) {循環(huán)代碼}
先條件判斷,如條件為 true,則執(zhí)行循環(huán)代碼
在執(zhí)行條執(zhí)行判斷,如果為 true,繼續(xù)執(zhí)行循環(huán)代碼....
直到條件判斷為 false 的時候,則循環(huán)結(jié)束
注意: 如果條件判斷一致為 true,就會形成 死循環(huán)懈费。所以一般會設(shè)置初始值,并且在循環(huán)體中改變初始值,而條件判斷也是根據(jù)變量值判斷的
// 案列1:和女朋友說 10次 對不起
// 1.設(shè)置初始值
var n = 0;
// 2.設(shè)置條件
while (n < 10){
// 2.書寫循環(huán)體
console.log( '對不起' )
// 4.在循環(huán)體內(nèi), 改變值
n++;
}
console.log( n+'循環(huán)結(jié)束' )
// 案例2:第一次彈窗的結(jié)果 str是循環(huán)的初始值
var str = prompt('你愛不愛我?(yes/no)');
while(str != 'yes'){ // 條件成立則執(zhí)行循環(huán)體
// 循環(huán)體中代碼就是 彈出提問彈窗,并修改str的值
str = prompt('你愛不愛我?(yes/no)')
}
// 當(dāng)輸入yes的時候循環(huán)結(jié)束
alert('我也愛你');
(2) do-while循環(huán)
執(zhí)行: 先執(zhí)行一次大括號中的循環(huán)代碼,然后條件判斷
條件判斷為true,則繼續(xù)執(zhí)行循環(huán)代碼,然后再條件判斷
條件判斷為true,則繼續(xù)執(zhí)行循環(huán)代碼,然后再條件判斷
....直到 條件判斷為false,則循環(huán)結(jié)束
特點: do-while語句 至少會執(zhí)行一次循環(huán)代碼
while循環(huán)有可能一次都不執(zhí)行循環(huán)代碼
do{
循環(huán)代碼
} while (條件)
// 需求: 和女朋友說 我錯了 5次
var n = 5;
do{
console.log('我錯了');
n--;
}while(n>0)
(3) for語句循環(huán)
/*
語法:
for(初始值1; 條件2; 值改變3){
循環(huán)代碼4
}
執(zhí)行: 1243-->243-->243-->.....繼續(xù)循環(huán)執(zhí)行,直到 條件2 判斷為false的時候,循環(huán)結(jié)束
*/
// 簡單的for循環(huán) 輸出1~5
for (var i = 1; i <= 5; i++) {
console.log(i)
}
// for循環(huán)的變換寫法1
// 可以將for循環(huán)小括號中的初始值放到外面,但是小括號的分號不能省略
var i = 1;
for (;i<=5;i++) {
console.log( i )
}
// for循環(huán)的變化寫法2
// 也可以將for選混中的值改變 在循環(huán)體內(nèi)書寫
var i = 1;
for (; i <= 5;) {
console.log(i)
i++
}
// 不要寫死循環(huán) 條件判斷一定要有
for(;;){
console.log( 666 )
}
2.6.3 循環(huán)控制關(guān)鍵字
(1) break
// break 可以在循環(huán)中使用,表示結(jié)束循環(huán)
// 吃十個包子, 發(fā)現(xiàn)吃到第6個的時候,就飽了,就不吃了
for(var i = 1; i <= 10; i++){
document.write('吃第' + i + '個包子<br>')
if(i === 6){
document.write('吃飽了')
break// 結(jié)束循環(huán)
}
}
(2) continue
// continue 結(jié)束本次循環(huán)代碼的執(zhí)行,直接跳到下一次的循環(huán)
// 吃十個包子, 發(fā)現(xiàn)吃到第6個的時候,第6個包子壞了,第6個包子不吃了,繼吃后面四個包子
for(var i = 1; i <= 10; i++){
if(i === 6){
console.log('第6個包子壞了,不吃')
continue // 結(jié)束本次循環(huán)代碼的執(zhí)行,繼續(xù)下一次循環(huán)
}
document.write('吃第' + i + '個包子<br>')
}
(2) 循環(huán)小結(jié)
while循環(huán)和for循環(huán)中的循環(huán)體,可能一次都不執(zhí)行,do-while循環(huán)至少會執(zhí)行一次循環(huán)體
如果知道循環(huán)次數(shù) 更多的時候使用 for循環(huán),如果不知道循環(huán)次數(shù),則使用while或do-while循環(huán)
循環(huán)控制關(guān)鍵字 break 和 continue 使用在循環(huán)體中的,無論是for循環(huán)還是while , do-while循環(huán)都可以使用
2.6.3 循環(huán)嵌套
循環(huán)嵌套: 循環(huán)體內(nèi) 寫循環(huán)
(1) 循環(huán)嵌套寫法
// 需要記錄多個跑圈,4個人,每人跑5圈
// 記錄一個人跑步,每跑一圈記錄一下
for (var i = 1; i <= 5; i++) {
console.log('跑第' + i + '圈');
}
for (var j = 1; j <= 4; j++) {
// 外層循環(huán),記錄的是第j個人的跑圈
console.log('這是第' + j + '個人的跑圈記錄');
for (var i = 1; i <= 5; i++) {
// 內(nèi)層循環(huán),記錄 第j個人 跑的圈數(shù)
console.log('這是第' + j + '個人跑第' + i + '圈');
}
}
// 使用循環(huán)嵌套,在頁面中打印表格4*5的表格
// 奇數(shù)行和偶數(shù)行的背景顏色不一樣
document.write('<table border="1">')
// 使用循環(huán)嵌套 輸出tr-td
for (var i = 1; i <= 4; i++) {
// 外層循環(huán)控制輸出的行數(shù)
if (i % 2 == 0) {
document.write('<tr style="background:red">')
} else {
document.write('<tr style="background:skyblue">')
}
for (var j = 1; j <= 5; j++) {
// 循環(huán)輸出td;內(nèi)層循環(huán)控制一行輸出多個td
document.write('<td> </td>')
}
document.write('</tr>')
}
document.write('</table>')
(1) 循環(huán)嵌套案列
// 在頁面中打印九九乘法表
/*
1*1=1
2*1=1 2*2=4
3*1=1 3*2=6 3*3=9
4*1=1 4*2=8 4*3=12 4*4=16
...
特點: 每一行輸出的等式個數(shù) 就是行數(shù)
*/
for (var i = 1; i <= 9; i++) { // i就是第幾行
// 外層循環(huán)控制行數(shù) ,9行
for (var j = 1; j <= i; j++) {
// 內(nèi)層循環(huán) 控制 每一行輸出 等式 個數(shù)
document.write(i + '*' + j + '=' + i * j+' ');
}
// 通過在頁面中輸出換行標(biāo)簽來實現(xiàn) 換行
document.write('<br>');
}
2.7 函數(shù)
函數(shù)特點: 封裝, 復(fù)用, 即用
2.7.1 函數(shù)定義及調(diào)用
函數(shù)定義
使用關(guān)鍵字 function 來告訴瀏覽器, 要準(zhǔn)備一個 盒子
這個 盒子
要有一個名字,這個盒子的名字也就是函數(shù)的名字---函數(shù)名稱,和之前講過的變量名的命名規(guī)則和規(guī)范一樣
定義函數(shù)的過程 就是 將要執(zhí)行的代碼 放到 盒子
中的過程
(1) 聲明式定義函數(shù)
語法: function 函數(shù)名(){ 函數(shù)代碼 }
+ function 關(guān)鍵字和 函數(shù)名 之間的空格不能省略
+ 函數(shù)名后面的小闊號不能省略: 小括號中是寫 形參
聲明式定義的函數(shù),可以在定義之前或者定義之后調(diào)用該函數(shù)
賦值式定義的函數(shù),只能在定義之后調(diào)用該函數(shù)
// 聲明式定義函數(shù)
function fn() {
console.log('這是fn函數(shù)')
}
fn() // 調(diào)用函數(shù)
(2) 賦值式定義函數(shù)----和之前講的定義變量并賦值是一樣
語法: var 變量名 = function (){ 函數(shù)代碼 }
+ 賦值給變量的是一個沒有名字的函數(shù)(匿名函數(shù))
fn(); // 報錯 ff is not a function
// 賦值式定義函數(shù)
var fn = function () {
console.log('賦值式定義函數(shù)')
}
fn() // 調(diào)用函數(shù)
// 注意: 在js中代碼執(zhí)行報錯,會終止主程序的執(zhí)行(報錯之后的代碼不會執(zhí)行)
(3) 函數(shù)定義階段:
在內(nèi)存中開辟一個空間(創(chuàng)建了一個盒子)
將函數(shù)中的代碼一模一樣的放到這個中間中,此時不會解析函數(shù)中的變量
(相當(dāng)于將函數(shù)中的代碼,當(dāng)做字符串一樣放到開辟的空間中)將開辟的空間的 地址賦值給 函數(shù)名(變量)
函數(shù)調(diào)用階段:
先根據(jù) 函數(shù)名(變量)中存儲的地址,找到 函數(shù)代碼的存儲空間
將函數(shù)存儲空間中的代碼拿出來執(zhí)行,此時才會解析函數(shù)中的變量
函數(shù)調(diào)用的時候才會解析函數(shù)中的變量
2.7.2 函數(shù)的參數(shù)
(1) 形參:
在函數(shù)定義的時候 寫到小括號中的變量----形式參數(shù)
形參 也是 在函數(shù)中使用的變量
如果有多個形參,使用逗號分隔
形參個數(shù) 比 函數(shù)調(diào)用時候的實參要多這個形參的值就是undefined(相當(dāng)于在函數(shù)內(nèi)部定義了一個變量,但是調(diào)用的時候沒有賦值)
(2) 實參:
在函數(shù)調(diào)用的時候,寫在小括號中的具體的數(shù)據(jù),如果有多個也是用逗號分隔
實參 就是 在函數(shù)調(diào)用的時候,給對應(yīng)的形參賦的值
實參沒有賦值給對應(yīng)的形參,則在函數(shù)內(nèi)部不能通過形參得到這個實參的值
// 形參n 在函數(shù)內(nèi)使用的變量
function fn(n, m, x, y) {
console.log(n, m, x, y)
}
// 函數(shù)調(diào)用,100就是實參
fn(100, 200); // 100 200 undefined undefined
(3) arguments 關(guān)鍵字
function ff(n1, n2) {
// 1. arguments 會接收所有函數(shù)調(diào)用傳遞的實參
console.log(arguments)
// 2. 在函數(shù)內(nèi)部,可以通過 arguments[下標(biāo)] 獲取對應(yīng)的實參
console.log(arguments[0])
console.log(arguments[1])
console.log(arguments[2])
// 3. 可以通過arguments.length 獲取實參的個數(shù)
console.log(arguments.length)
}
// ff(10,20,30,40,50);
ff(10, 20, 30, 40, 50, 60);
2.7.3 函數(shù)的返回值
(1) 函數(shù)內(nèi)的關(guān)鍵字 return
- return 會終止函數(shù)內(nèi)代碼的執(zhí)行(return 關(guān)鍵字,下一行的代碼不會執(zhí)行)
- return 可以給函數(shù)創(chuàng)造一個返回值
return 關(guān)鍵字后面跟的是什么內(nèi)容,函數(shù)調(diào)用返回的結(jié)果就是什么
注意: return 關(guān)鍵字后如果什么都沒寫,則函數(shù)的返回值就是 undefined
如果函數(shù)內(nèi)沒有return,則函數(shù)調(diào)用的返回值也是undefined
// return 會終止函數(shù)的執(zhí)行
function ff() {
console.log( 1 )
console.log( 2 )
return; // 函數(shù)內(nèi)的代碼執(zhí)行到此處的時候,后面的代碼就不會執(zhí)行了
console.log( 3 )
console.log( 4 )
}
ff();
// return 返回的值
function fn(n) {
var i = n + 10
return i// 返回值return
}
// 函數(shù)調(diào)用也是一個表達式,執(zhí)行后會有結(jié)果
// 將函數(shù)調(diào)用的結(jié)果 賦值給變量res
var res = fn(10);
console.log(res) // 將 res 的值輸出 i 的值 20
(2) 函數(shù)練習(xí)
// 編寫一個函數(shù),計算兩個數(shù)值的和,差,積,商 并返回, 要求:使用傳參的方式
function getRes(n1, n2, opt) {
// 校驗傳入的是n1,n2的值,是否是數(shù)值
if (isNaN(n1) || isNaN(n2)) {
alert('請輸入數(shù)字');
return '輸入數(shù)字有誤'; // 終止函數(shù)代碼的執(zhí)行
}
var result; // 結(jié)果計算的結(jié)果
// 使用switch-case多分支判斷,輸入的運算符,計算結(jié)果
switch (opt) {
case '+': result = n1 + n2; break;
case '-': result = n1 n2; break;
case '*': result = n1 * n2; break;
case '/': result = n1 / n2; break;
default:
alert('請輸入正確的運算符');
return '輸入的運算符有誤';
}
return result;
}
var a = parseInt(prompt('輸入第一個數(shù)字'))
var b = parseInt(prompt('輸入第二個數(shù)字'))
var f = prompt('請輸入計算方式:+,-,*,/')
// 函數(shù)調(diào)用
var res = getRes(a, b, f);
console.log(res)
2.7.4 函數(shù)的預(yù)解析
預(yù)解析: 在瀏覽器解析js代碼之前,會解析的內(nèi)容
(1) 預(yù)解析的內(nèi)容
var 關(guān)鍵字定義的變量
變量提升: 在瀏覽器解析js中的代碼之前,會將var 聲明的變量提升(提升到代碼的最前面)聲明式定義函數(shù)
函數(shù)提升: 在瀏覽器解析js代碼之前,會將 聲明式定義的函數(shù)提升到代碼的最前面
注意: 函數(shù)調(diào)用,執(zhí)行函數(shù)內(nèi)部代碼之前,也會在函數(shù)內(nèi)部進行預(yù)解析,但是變量和函數(shù),只會提升到函數(shù)內(nèi)的最前面
(2) 預(yù)解析分析
console.log( num ); // undefined
var num = 100;
console.log( num ); // 100
/*
預(yù)解析分析:
代碼執(zhí)行之前,只要發(fā)現(xiàn)代碼中有var 申明變量,會將var 聲明變量提升到最前面
var num;
console.log( num ) // undefined,聲明變量沒有賦值,變量就是undefined
num = 100
console.log( num ) // 100
*/
/******************************************/
fn();
function fn() {
console.log('fn')
}
fn();
/*
預(yù)解析分析:
在代碼執(zhí)行之前,會將聲明式定義的函數(shù)提升到最前面
function fn() {
console.log( 'fn' )
}
fn();
fn();
*/
/**************************************************/
fn();
var fn = function () {
console.log('fn')
}
fn();
/*
預(yù)解析分析:
代碼執(zhí)行之前,發(fā)現(xiàn)有var 聲明變量,會將變量聲明提升到最前面
var fn;
fn(); // 此時變量fn中的值undefined,所以此處函數(shù)調(diào)用報錯
fn = function () {
console.log('fn')
}
fn();
*/
/**************************************************/
function fn() {
console.log(num)
var num = 100;
console.log(num)
}
fn();
/*
預(yù)解析分析:
fn函數(shù)調(diào)用,fn函數(shù)內(nèi)部代碼預(yù)解析
function fn(){
// 預(yù)解析
var num;
console.log(num) // undefined
num = 100;
console.log(num)// 100
}
*/
(3) 預(yù)解析小結(jié):
- 只有var 聲明變量和聲明式定義的函數(shù)才會預(yù)解析
- 賦值式定義的函數(shù)不會函數(shù)提升預(yù)解析,只有可能會變量提升預(yù)解析
- 函數(shù)調(diào)動的時候,函數(shù)內(nèi)也會預(yù)解析,但是會先進行形參賦值,然后預(yù)解析
- 函數(shù)內(nèi)的return 不會影響函數(shù)內(nèi)的預(yù)解析
- 分支結(jié)構(gòu)中的條件和大括號也不會影響預(yù)解析(變量提升)
2.7.5 作用域
作用域: 就是變量的使用范圍
作用域分為全局作用域和局部作用域(私有作用域)
(1) 全局作用域: 一個頁面就是一個全局作用域
全局作用域中定義的變量,在全局中都可以使用
全局作用域的生命周期: 從頁面打開到頁面關(guān)閉
// 全局中定義的變量在全局中都能使用
var num =100;
function fn() {
console.log( num );
}
fn();
console.log( num )
(2) 局部作用域:
也叫做私有作用域,在js中只有函數(shù)的大括號才能確定一個局部作用域(if和for的大括號不行)
在局部作用域中定義的變量,只能在這個局部作用域中使用,在別的地方不能使用
// 局部作用域
function ff() {
// 此處就是ff的局部作用域
}
function ff2() {
// 此處就是ff2的局部作用域
}
(3) 作用域中的反問規(guī)則
- 變量的方式就是獲取這個變量的值
常見訪問變量值的方式:
- 輸出變量,
- 變量參與運算,
- 在函數(shù)中返回變量的值,
- 將變量當(dāng)中的值賦值給別的變量
- 函數(shù)調(diào)用變量作為實參
...
- 會先在當(dāng)前自己作用域中查找,是否有定義這個變量,如果有則拿來使用
- 如果當(dāng)前作用域中沒有這個變量,則去上一級作用域中查找,找到了則使用
- 如果找不到,則再繼續(xù)去上一級作用域中查找這個變量,找到了則使用
- 如果還是找不到,則再繼續(xù)去上一級作用域中查找這個變量,找到了則使用
- 一直往上的作用域中查找,直到全局作用域查找,找到則使用
- 如果在全局作用有中還是找到不到,則報錯(變量 is not defined)
- 注意: 變量的訪問,找不到的時候只會去上一級作用域查找,不會往下的作用域中查找
function fn() {
// fn的局部作用域
var num = 200;
function ff() {
// ff局部作用域
// console.log(username) // 報錯
// 當(dāng)前作用域沒有username,則去上一級fn作用域中查找,沒有找到,則繼續(xù)去上一級作用域全局中查找,沒有找到則報錯 username is not defined
function f1() {
// f1的局部作用域
var username = 'leon';
// num變量運算和num變量賦值都是屬于 num變量訪問
console.log(num + 100) // 300
var n = num
}
f1();
}
ff();
}
fn();
// f1作用域的上一級是ff作用域
// ff作用域的上一級是fn作用域
// fn作用域的上一級是全局作用域
(4) 作用域中變量的賦值規(guī)則:
- 當(dāng)作用域中有 給變量賦值的時候,
- 會現(xiàn)在當(dāng)前作用域中找,是否有聲明這個變量,如果有聲明則賦值
- 如果沒有,則去上一級作用域中查找,在上一級作用域中是否有聲明這個變量,如果有則賦值
- 如果還是沒有,則繼續(xù)往上一級作用域中找,如果還是沒有,則繼續(xù)往上的作用域中找
- 如果直到全局作用域找,還是沒有找到,則會將這個變量定義為 全局變量 ,并且賦值
- 這中定義的變量 我們稱之為 隱式全局變量
function fn() {
function ff() {
var num = 200;
function f1() {
num = 100;
}
f1()
// f1函數(shù)調(diào)用 執(zhí)行給變量num賦值, 在f1作用域中沒有聲明變量num,則去上一級作用域中找 是否有聲明變量num
// ff作用域中 有聲明變量num, 則將100賦值給ff作用域中的num變量,f1函數(shù)執(zhí)行結(jié)束
console.log( num )//100 此處代碼執(zhí)行的時候,num變量中的值 已經(jīng)是100了
}
ff();
}
fn();
(5) 作用域鏈
作用域鏈: 在變量的訪問和賦值的時候,先當(dāng)前作用域往上一級作用域,一直到到全局作用域,這樣形成的一個鏈?zhǔn)椒Q之為作用域鏈
作用域鏈的作用: 就是讓js代碼在執(zhí)行的時候,變量的訪問和賦值是有序的
2.7.6 事件
事件就是用戶在頁面的動作行為, 比如:鼠標(biāo)點擊,鼠標(biāo)移動,鍵盤按下等等
在js中可以通過頁面標(biāo)簽的id屬性值,直接獲取到頁面元素
console.log( box )
事件組成三要素:
- 事件源: 綁定事件的頁面元素
- 事件類型: 觸發(fā)的什么事件(鼠標(biāo)事件,鍵盤事件,表單事件....)
- 事件處理程序(函數(shù)): 事件觸發(fā)后要執(zhí)行的函數(shù)
1. 鼠標(biāo)事件
- click 鼠標(biāo)左鍵單擊事件
- dblclick 鼠標(biāo)左鍵雙擊事件
- mouseover 鼠標(biāo)移入事件
- mouseout 鼠標(biāo)移出事件
- mousemove 鼠標(biāo)移動事件
2. 鍵盤事件
- keydown 鍵盤按下事件(鍵盤按下不松開則會一直觸發(fā)此事件)
- keyup 鍵盤彈起事件(鍵盤按下松開,只會觸發(fā)一次keyup)
- 一般鍵盤事件綁定給頁面,js中docuemnt表示瀏覽器文本,文檔包含瀏覽器中整個顯示頁面
3. 表單事件
- blur 表單輸入框的失去焦點(光標(biāo))事件
- focus 表單輸入框的獲取焦點(光標(biāo))事件
- input 表單輸入框的輸入事件
4. 瀏覽器事件
- load 瀏覽器頁面加載事件(一般給綁定給window)
- scroll 瀏覽器滾動事件
語法: 頁面元素.on+事件類型 = 函數(shù)
// box就是事件源
// click就是事件類型(click 是鼠標(biāo)左鍵單擊事件)
box.onclick = function () {
console.log(666);
}
/*
此處我們可以理解為: 定義了一個匿名函數(shù),并且賦值給了box元素的點擊事件
當(dāng)鼠標(biāo)點擊box元素的時候,就會觸發(fā)box的點擊事件,并執(zhí)行對應(yīng)的事件處理函數(shù)
*/
2.7.7 對象
對象: 是 js 中的一種數(shù)據(jù)類型,是復(fù)雜數(shù)據(jù)類型
對象是一個數(shù)據(jù)的集合,無序數(shù)據(jù)集合
對象也叫做 鍵值對集合, 對象可以存儲數(shù)據(jù), 對象存儲數(shù)據(jù)的形式----鍵值對形式存儲
(1) 對象語法
(1) 對象
語法:{}表示一個空對象
var o = {};
console.log( o )
(2) 有數(shù)據(jù)的對象
語法:{鍵名:鍵值,鍵名:鍵值,鍵名:鍵值....}
var per = {
name: 'zs',
name: 'lisi', // 對象中的鍵名唯一的不能重復(fù),所有后面的會將前面的覆蓋
'age': 17,
'flag': true,
eat:function(){
console.log( '西紅柿炒番茄' )
}
}
console.log(per)
對象中的鍵名: 也叫做對象的屬性名,屬性名必須是字符串?dāng)?shù)據(jù)類型,屬性名可以可以加引號,也可以不加引號書寫,對象中屬性名是唯一的(不能重復(fù))
對象中的鍵值: 可以是任意數(shù)據(jù)類型的值 一組鍵值對組成了對象中的一個數(shù)據(jù)成員 對象中如果有多個數(shù)據(jù)成員(鍵值對),則使用逗號分隔
(2) 創(chuàng)建對象
1. 字面量創(chuàng)建對象
語法: 變量 = 對象
// 1. 字面量創(chuàng)建
// 字面量就是直接賦值的形式
var obj = {name:'zs',age:10};
console.log( obj )
2. 使用內(nèi)置構(gòu)造函數(shù)創(chuàng)建對象
Object是內(nèi)置的構(gòu)造函數(shù),通過new 的方式調(diào)用該函數(shù),可以創(chuàng)建對象
語法: 變量 = new Object()
// 2. 使用內(nèi)置構(gòu)造函數(shù)創(chuàng)建對象
var obj = new Object();
console.log( obj ) // 空對象
(3) 操作對象的成員:
- 添加對象成員
- 點語法: 對象.屬性名 = 值
- 數(shù)組關(guān)聯(lián)法: 對象['屬性名'] = 值
- 使用數(shù)組關(guān)聯(lián)法,中括號里面的屬性名必須加引號
- 修改對象對應(yīng)的成員的值
- 點語法: 對象.屬性名 = 值
- 數(shù)組關(guān)聯(lián)法: 對象['屬性名'] = 值
- 訪問對象成
- 點語法: 對象.屬性名
- 數(shù)組關(guān)聯(lián)法: 對象['屬性名']
- 刪除對象成員
- 點語法: delete 對象.屬性名
- 數(shù)組關(guān)聯(lián)法: delete 對象['屬性名']
// 點語法操作
var obj = new Object();
// 添加
obj.name = 'zs';
obj.age = 17;
// 修改
obj.name = 'lisi'
// 刪除
delete obj.age;
// 訪問
console.log( obj.name ) // 'lisi'
// 訪問對象成員的時候,如果沒有這個屬性名,則值為undefined
console.log( obj.abcd ) // undefined
console.log( obj ) // {name: 'lisi'}
// 數(shù)組關(guān)聯(lián)法
var per = {};
// 添加
per['name'] = 'zs';
per['age'] = 20;
// 修改
per['name'] = 'lisi';
// 刪除
delete per['age']
// 訪問
console.log( per['name'] ) // lisi
console.log( per['xyz'] ) // undefined 對象沒有xyz這個屬性名
console.log( per ) // {name: 'lisi'}
三计露、javascript數(shù)據(jù)操作
3.1 遞歸函數(shù)
在函數(shù)內(nèi)部調(diào)用函數(shù)本身
// 使用遞歸函數(shù),計算1+2+3+4+5的和
function ff(n) {
// 結(jié)束條件
if(n===1){
return 1;
}
return n + ff(n - 1)
}
var res = ff(5);
console.log( res ) // 15
// 斐波那契數(shù)列
// 該數(shù)列的特點: 第一個和第二個的數(shù)值是1,從第三個開始,每一個數(shù)的值是前兩個數(shù)的和
// 1 1 2 3 5 8 13 21 34 55..
// 請使用遞歸函數(shù) 求第10個斐波那契數(shù)列的值
function getFeiBo(n) {
// 結(jié)束條件,第一個和第二個的數(shù)值是1
if (n === 1 || n === 2) {
return 1
}
return getFeiBo(n - 1) + getFeiBo(n - 2)
}
console.log( getFeiBo(10) ) // 55
3.2 數(shù)組
數(shù)據(jù)類型: 基本數(shù)據(jù)類型和復(fù)雜數(shù)據(jù)類型
基本數(shù)據(jù)類型: string boolean number undefined null
復(fù)雜數(shù)據(jù)類型: object array
數(shù)組 是js的復(fù)雜數(shù)據(jù)類型
數(shù)組就是一組有序的數(shù)據(jù)集合
因為數(shù)組中的每一個成員都有一個索引,這個索引就是成員在數(shù)組中的排序
數(shù)組: 使用中括號包裹,多個成員之間通過逗號分隔,數(shù)組中的數(shù)據(jù)成員可以是任意數(shù)據(jù)類型
數(shù)組的兩種創(chuàng)建方式
3.2.1 字面量創(chuàng)建數(shù)組
語法:var arr = []
// 1. 字面量創(chuàng)建數(shù)組
var arr = [];
console.log( arr ) // 空數(shù)組 沒有任何數(shù)據(jù)的數(shù)組
var arr1 = [1,2,3,4,'a','b','c',true,undefined,{}]
console.log( arr1 ) // [1, 2, 3, 4, 'a', 'b', 'c', true, undefined, {…}]
3.2.2 內(nèi)置構(gòu)造函數(shù)創(chuàng)建數(shù)組
- var arr = new Array() // 得到一個空數(shù)組
- var arr = new Array(一個數(shù)字) // 傳入的數(shù)字必須是大于0的整數(shù),得到一個有成員的數(shù)組,但是每一個成員的內(nèi)容都是(empty)
- var arr = new Array(多個參數(shù)) // 多個參數(shù)可以是任意數(shù)據(jù)類型,得到一個有成員的數(shù)組,而且傳入的參數(shù)就是數(shù)組成員
// 2. 通過內(nèi)置構(gòu)造函數(shù)創(chuàng)建數(shù)組
var arr = new Array();
console.log( arr ) // []
var arr = new Array(5);
console.log( arr ) // [empty × 5]
var arr = new Array('a','b',1,2);
console.log( arr ) // ['a', 'b', 1, 2]
var arr = new Array('10');
console.log( arr ) // ['10']
3.2.3 數(shù)組的長度和索引
(1) 數(shù)組長度
- 數(shù)組中的數(shù)組,我們也叫做數(shù)組的成員
- 數(shù)組成員的個數(shù) 就是數(shù)組的長度
- 數(shù)組長度獲取
- 數(shù)組.length
- 返回數(shù)組成員的個數(shù)
(2) 數(shù)組的索引
- 數(shù)組的每一個成員都有一個索引,表示成員在數(shù)組中序號
- 數(shù)組的索引永遠(yuǎn)都是從0開始的連續(xù)自然數(shù)
- 可以通過數(shù)組的索引,獲取修改數(shù)組對應(yīng)的成員數(shù)據(jù)
- 語法: 數(shù)組[索引] // 獲取
(3) 數(shù)組索引和數(shù)組長度的關(guān)系
- 數(shù)組索引的最大值 就是 數(shù)組長度減1
- 數(shù)組長度 就是數(shù)組索引最大值加1
(4) 添加數(shù)組成員
- 語法: 數(shù)組[索引] = 值
- 注意: 如果數(shù)組中對應(yīng)的索引有值了,通過這個方式只能修改數(shù)組中索引對應(yīng)的值
(5) 數(shù)組的長度是可變的(可修改)
- 隨著數(shù)組成員數(shù)的編,數(shù)組的長度也會變化
- 而知可以通過改變數(shù)組的長度,修改數(shù)組成員個數(shù)
- 注意: 因為數(shù)組的索引是連續(xù)的自然數(shù),如果跳過數(shù)組索引最大值添加成員,則長度以 最新的數(shù)組最大索引加1 為準(zhǔn)
(6) 遍歷數(shù)組: 循環(huán)的獲取數(shù)組中的每一個成員
// for循環(huán)來遍歷數(shù)組
for(var i = 0;i<數(shù)組.lengthl;i++){ // i 就是數(shù)組的索引
數(shù)組[i]
}
var arr = ['a','b','c','d'];
console.log( arr.length ) // 4
console.log( arr ) // ['a','b','c','d']
console.log( arr[0] ) // ['a']
arr[3] = 4; // 修改
console.log( arr ) [4]
arr[4] = 'e'; // 添加
console.log( arr ) // ['a','b','c','d','e']
// 數(shù)組長度
var arr = ['a', 'b', 'c', 'd'];
// 直接修改數(shù)組長度 改變數(shù)組個數(shù)
arr.length = 2
console.log(arr) // ["a", "b"]
arr.length = 0;
console.log(arr) // []
// 通過索引 添加數(shù)組成員,數(shù)組長度變化
arr[6] = 'f';
console.log(arr) // ['a', 'b', 'c', 'd', empty × 2, 'f']
console.log( arr.length ) // 7
// for 循環(huán)遍歷數(shù)組
var arr = ['a', 'b', 'c', 'd'];
// 利用了數(shù)組索引和數(shù)組長度的關(guān)系特點 使用for循環(huán)遍歷
// 數(shù)組的索引最大值 為 數(shù)組長度減1
for (var i = 0; i < arr.length; i++) {
// i 就是數(shù)組的索引
console.log( arr[i] ) // a b c d
}
3.2.4 數(shù)組常用方法
語法: 數(shù)組.數(shù)組方法()
數(shù)組方法 | 作用 |
---|---|
push() | 可以接收任意數(shù)量的參數(shù),把它們逐個添加到數(shù)組末尾憎乙,并返回修改后數(shù)組的長度薄坏。 |
pop() | 從數(shù)組末尾移除最后一項,減少數(shù)組的length值寨闹,然后返回移除的項。 |
unshift() | 方法能夠在數(shù)組前面添加任意個項并返回新數(shù)組的長度君账。 |
shift() | 方法能夠移除數(shù)組中的第一個項并返回該項繁堡,同時將數(shù)組長度減 1。 |
reverse() | 方法會反轉(zhuǎn)數(shù)組項的順序。 |
sort() | 方法按字母表升序排列數(shù)組項椭蹄。 |
concat() | 方法可以基于當(dāng)前數(shù)組中的所有項創(chuàng)建一個新數(shù)組闻牡,參數(shù)可以是數(shù)組項或者數(shù)組。 |
slice() | 方法它能夠基于當(dāng)前數(shù)組中的一或多個項創(chuàng)建一個新數(shù)組绳矩≌秩螅可以接受一或兩個參數(shù)。 |
splice() | 方法翼馆,對數(shù)組進行刪除割以、插入、替換应媚,是最強大的數(shù)組方法严沥,返回值是數(shù)組,改變原數(shù)組中姜。 |
join() | 方法消玄,將數(shù)組轉(zhuǎn)換成對應(yīng)的字符串。參數(shù)就是連接符丢胚。 |
indexOf | 根據(jù)傳入的參數(shù),去數(shù)組中從前往后查找,如果找到一樣的則返回索引,并停止查找翩瓜,如果數(shù)組中沒有一樣的元素, 則返回-1 |
// 1. pop()
// 語法: 數(shù)組.pop();
// 作用: 刪除數(shù)組的最后一個成員
// 返回值: 被刪除的數(shù)組成員
// 會改變原數(shù)組
var arr = ['a', 'b', 'c'];
var res = arr.pop();
console.log(res) // 'c' 刪除的元素作為返回值
console.log(arr) // ["a", "b"]
/***************************************/
// 2. unshift()
// 語法: 數(shù)組.unshift(參數(shù));
// 作用: 將參數(shù)作為數(shù)組的成員,添加到數(shù)組里面的最前面
// 返回值: 返回添加之后的數(shù)組長度
// 會改變原數(shù)組
var arr = ['a', 'b', 'c'];
var res = arr.unshift(1);
console.log(res) // 4
console.log(arr) // [1, "a", "b", "c"]
/***************************************/
// 3. splice
// 語法1: 數(shù)組.spice(起始索引,刪除幾個元素)
// 作用: 從指定的索引開始刪除數(shù)組元素
// 如果沒有傳入刪除的個數(shù),則默認(rèn)從起始索引開始刪除元素一直到最后一個元素
// 返回值: 以數(shù)組的形式返回刪除的元素
// 會改變原數(shù)組
var arr = ['a', 'b', 'c', 'd', 'e'];
var resArr = arr.splice(2, 2);
console.log( '返回值:',resArr ) // ["c", "d"]
console.log( '原數(shù)組:',arr ) // ["a", "b", "e"]
// 語法2: 數(shù)組.spice(起始索引,刪除幾個元素,將這個東西替換刪除的內(nèi)容...)
// 作用: 從指定的索引開始刪除數(shù)組元素,并替換為傳入的內(nèi)容
// 返回值: 以數(shù)組的形式返回刪除的元素
var arr = ['a', 'b', 'c', 'd', 'e'];
var resArr = arr.splice(2, 2, 1, 2);
console.log('返回值:', resArr) // ["c", "d"]
console.log('原數(shù)組:', arr) // ["a", "b", 1, 2, "e"]
/**********************************************************/
// 4. sort
// 語法1: 數(shù)組.sort()
// 作用: 按照數(shù)組的元素的逐位數(shù)值排序
// 返回值: 排序后的數(shù)組
// 會改變原數(shù)組
var arr = [11,31,4,2];
var resArr = arr.sort();
console.log('返回值:', resArr) // [11, 2, 31, 4]
console.log('原數(shù)組:', arr) // [11, 2, 31, 4]
// 語法2: 數(shù)組.sort(參數(shù))
// 參數(shù)必須是一個函數(shù),函數(shù)要有兩個形參 函數(shù)內(nèi)返回兩個形參的差值
// 作用: 按照數(shù)組的元素的數(shù)值排序
// 返回值: 排序后的數(shù)組
// 會改變原數(shù)組
var arr = [11, 31, 4, 2];
var resArr = arr.sort(function (a, b) {
return a - b
});
console.log('返回值:', resArr) // [2, 4, 11, 31]
console.log('原數(shù)組:', arr) // [2, 4, 11, 31]
var arr = [11, 31, 4, 2];
var resArr = arr.sort(function (a, b) {
return b - a
});
console.log('返回值:', resArr) // [31, 11, 4, 2]
console.log('原數(shù)組:', arr) // [31, 11, 4, 2]
3.2.5 遍歷對象
因為數(shù)組是有序(索引)的數(shù)據(jù)集合
所以很容易使用for循環(huán)遍歷數(shù)組
但是對象是一個無序的數(shù)據(jù)(鍵值對)集合
使用for循環(huán)則無法遍歷對象,需要使用for-in語法遍歷
// for-in語法:
// 對象有多少個成員就會循環(huán)多少次
for(var 變量 in 對象){
// 變量就是對象的鍵名
}
var obj = {
name: 'xiaobin',
age: 18,
yyds: '牛逼'
}
for (var key in obj) {
// key就是對象的所有鍵名
// console.log(key)
// 此處的key是變量,通過對象獲取鍵值,不能使用點語法
console.log(key, obj[key])
}
3.2.6 二維數(shù)組
數(shù)組中存儲數(shù)組,我們把大數(shù)組稱之為多維數(shù)組
如果數(shù)組外面只嵌套了一層數(shù)組,那么就是二維數(shù)組
// 二維數(shù)組
var friends = [ // 模擬qq分組數(shù)據(jù)
['zs1','lisi1','ww1'], // 好友
['zs2','lisi2','ww2'], // 黑名單
['zs3','lisi3','ww3'], // 陌生人
]
// 獲取二維數(shù)組中所有的數(shù)據(jù)
console.log( friends[0][0] )
console.log( friends[0][1] )
console.log( friends[0][2] )
console.log( '--------------' )
console.log( friends[1][0] )
console.log( friends[1][1] )
console.log( friends[1][2] )
console.log( '--------------' )
console.log( friends[2][0] )
console.log( friends[2][1] )
console.log( friends[2][2] )
/********************************************/
var friends = [ // 模擬qq分組數(shù)據(jù)
['zs1', 'lisi1', 'ww1'], // 好友
['zs2', 'lisi2', 'ww2'], // 黑名單
['zs3', 'lisi3', 'ww3'], // 陌生人
]
// 使用循環(huán)遍歷二維數(shù)組
for (var i = 0; i < friends.length; i++) {
// 外層循環(huán) 大數(shù)組中的小數(shù)組
console.log(friends[i])
// console.log( '------' )
for (var j = 0; j < friends[i].length; j++) {
// 內(nèi)層循環(huán)遍歷小數(shù)組的每一個數(shù)據(jù)
console.log(friends[i][j])
// i表示小數(shù)組在大數(shù)組中的索引,j表示具體數(shù)據(jù)在小數(shù)組中的索引
}
}
3.3 數(shù)據(jù)類型
3.3.1 數(shù)據(jù)類型的存儲區(qū)別
存儲內(nèi)存分為:
- 棧內(nèi)存
- 堆內(nèi)存
js 中的數(shù)據(jù)類型 分為基本數(shù)據(jù)類型和復(fù)雜數(shù)據(jù)類型(引用數(shù)據(jù)類型)
基本數(shù)據(jù)類型的數(shù)據(jù) 存儲在棧內(nèi)存 中 棧內(nèi)存中的標(biāo)識對應(yīng)的變量
復(fù)雜數(shù)據(jù)類型數(shù)據(jù)存儲在 堆內(nèi)存 中 而地址存儲在棧內(nèi)存中
小結(jié): 給變量賦值一個基本數(shù)據(jù)類型,則在這個變量的 棧內(nèi)存 中直接存儲數(shù)據(jù)
給變量賦值一個復(fù)雜數(shù)據(jù)類型,則就是將 數(shù)據(jù) 存儲在堆內(nèi)存,然后將存儲空間的地址 直接存儲在變量的 棧內(nèi)存中
3.3.2 不同數(shù)據(jù)類型之間變量賦值區(qū)別
基本數(shù)據(jù)類型之間的變量賦值, 賦值之后,變量之間互不影響
-
復(fù)雜數(shù)據(jù)類型之間的變量賦值,其實就是地址的賦值
- 賦值后兩個變量的地址指向同一個 存儲空間,操作的也是同一個存儲空間
- 注意: 函數(shù)調(diào)用的實參賦值給形參,形參賦值也遵守上面兩條 數(shù)據(jù)類型變量的賦值
// 基本數(shù)據(jù)類型之間的變量賦值
var n1 = 100;
var n2 = n1;
n2 = 200;
console.log(n1) // 100
console.log(n2) // 200
// 復(fù)雜數(shù)據(jù)類型之間的變量賦值
var arr = ['a', 'b', 'c'];
var arr2 = arr;
arr2[0] = 666;
console.log( arr ) // [666, "b", "c"]
console.log( arr[0] ) // 666
// 形參賦值1
function fn(n) {
n = 200;
}
var num = 100
fn(num);
console.log(num) // 100
3.3.3 數(shù)據(jù)類型之間變量的比較
基本數(shù)據(jù)類型的變量比較 其實就是值的比較
復(fù)雜數(shù)據(jù)類型的變量比較 其實就是地址的比較
// 基本數(shù)據(jù)類型
var num1 = 100;
var num2 = 100;
console.log( num1 == num2 )//true
// 復(fù)雜數(shù)據(jù)類型
var arr1 = [1, 2, 3];
var arr2 = [1, 2, 3];
console.log(arr1 == arr2) // false
3.3.4 數(shù)組排序
(1) 冒泡排序
遍歷數(shù)組,在循環(huán)中用前一個數(shù)組元素和后一個數(shù)組元素來兩兩比較
如果前一個值比后一個更大,則交換位置,如果沒有更大,則不交換位置
遍歷結(jié)束后保證了數(shù)組中的最大值在最后面
進行多次的循環(huán)比較交換位置后,數(shù)組排序就完成了
var arr = [3, 5, 6, 4, 9, 7, 8, 2, 1];
for (var j = 0; j < arr.length - 1; j++) {
for (var i = 0; i < arr.length - 1 - j; i++) {
// 前一個和后一個比較,如果前一個更大,則交換位置
if (arr[i] > arr[i + 1]) { // 交換位置
var tmp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = tmp;
}
}
}
console.log(arr) // [1, 2, 3, 4, 5, 6, 7, 8, 9]
(2) 選擇排序
第一次假設(shè)數(shù)組下標(biāo)為0是最小值
從數(shù)組下標(biāo)1開始遍歷數(shù)組,拿數(shù)組中的每一個元素逐個和假設(shè)的值比較
如果某一個值比假設(shè)的更小,則記錄下索引
然后用記錄索引的值和后面的數(shù)組元素繼續(xù)比較,如果更小則替換索引
遍歷結(jié)束之后,將記錄的索引的值和下標(biāo)為0 的值交換位置
第二次假設(shè)數(shù)組下標(biāo)為1是最小值
從數(shù)組下標(biāo)2開始遍歷數(shù)組,拿數(shù)組中的每一個元素逐個和假設(shè)的值比較
如果某一個值比假設(shè)的更小,則記錄下索引
然后用記錄索引的值和后面的數(shù)組元素繼續(xù)比較,如果更小則替換索引
遍歷結(jié)束之后,將記錄的索引的值和下標(biāo)為1 的值交換位置
在進行多次選擇比較(交換位置)后,數(shù)組排序完成
// 進行j次假設(shè)遍歷后,數(shù)組排序完成
for (var j = 0; j < arr.length - 1; j++) {
// 假設(shè)數(shù)組索引 j 就是最小值
var minIndex = j; // 定義遍歷記錄最小值索引
// 從數(shù)組索引 j+1 遍歷
for (var i = j + 1; i < arr.length; i++) {
// 數(shù)組元素和索引為minIndex的值比較
if (arr[i] < arr[minIndex]) { // 如果某一個值比minIndex的值更小則將索引記錄在minIndex中
minIndex = i;
}
}
// 遍歷結(jié)束,將索引為minIndex中的值和索引為j的值交換位置
// 如果minIndex就是我們一開始假設(shè)的最小值的索引 j ,則不需要交換位置
if (minIndex != j) {
var tmp = arr[j];
arr[j] = arr[minIndex]
arr[minIndex] = tmp;
}
}
console.log(arr) // [1, 2, 3, 4, 5, 6, 7, 8, 9]
3.4 字符串
3.4.1 嚴(yán)格模式
因為一開始的時候,js語法設(shè)計不是很嚴(yán)謹(jǐn)
js嚴(yán)格模式,主要是消除一些語法不合理的地方
也是為了未來新版本語法鋪墊
開啟嚴(yán)格模式,在代碼的最前面直接書寫 字符串 'use strict'
// 1. 嚴(yán)格模式下,沒有var 聲明的變量會報錯
num = 200; // 報錯
console.log( num )
// 2. 在嚴(yán)格模式下,定義的函數(shù)不能使用同名形參
function fn(num,num,num) {} //報錯
// 3. 在嚴(yán)格模式下,全局函數(shù)中的this沒有任何指向
function ff() {
console.log( this ) // undefined
}
ff(); // 函數(shù)中的this關(guān)鍵字,在函數(shù)普通調(diào)用方式的時候,this指向window
// 4. 在嚴(yán)格模式下,函數(shù)中不能使用arguments.callee
function f2() {
console.log( arguments )
// console.log( arguments.callee ) // 報錯
}
f2(1,2,3,4)
// 5. 在嚴(yán)格模式下,不能書寫0開頭的八進制寫法
var n = 012;// 報錯
var n1 = 0o12; // 標(biāo)準(zhǔn)的0o開頭八進制數(shù)寫法可以使用
var n2 = 0b11; // 0b開頭的數(shù)字就是二進制數(shù)
var n3 = 0x11; // 0x開頭的數(shù)字就是十六進制數(shù)
console.log( n1,n2,n3 )
3.4.2 ES5中的數(shù)組常用方法
語法 | 作用 |
---|---|
indexOf() | 從前往后查找數(shù)組元素,返回索引或-1 |
lastIndexOf() | 從后往前查找數(shù)組元素,返回索引或-1 |
forEach() | 數(shù)組遍歷方法 沒有返回值 |
map() | 數(shù)組映射方法 返回一個新數(shù)組 |
filter() | 數(shù)組過濾方法 返回一個新數(shù)組 |
every() | 數(shù)組判斷方法 返回布爾值 |
some() | 數(shù)組判斷方法 返回布爾值 |
(1) indexOf
語法: 數(shù)組.indexOf(參數(shù))
根據(jù)傳入的參數(shù),去數(shù)組中從前往后查找,如果找到一樣的則返回索引,并停止查找
如果數(shù)組中沒有一樣的元素, 則返回-1
作用: 查找數(shù)組元素
返回值: 索引 或 -1 不會改變原數(shù)組
var arr = [1,2,3,4,5,2];
var res1 = arr.indexOf(2)
console.log('返回值:', res1) // 1
(2) lastIndexOf
語法: 數(shù)組.lastIndexOf(參數(shù))
作用: 從數(shù)組元素的后面開始查找,參數(shù)在數(shù)組中是否存在,存在則返回索引,否則返回-1
返回值: 索引或 -1
var arr = [1, 2, 6, 4, 5, 6];
console.log( arr.lastIndexOf(6) ) // 5
console.log( arr.lastIndexOf(7) ) // -1
(3) forEach 數(shù)組遍歷方法
語法: 數(shù)組.forEach(參數(shù))
參數(shù)是一個函數(shù),函數(shù)有三個形參
作用: 遍歷數(shù)組, 數(shù)組有多少個元素,則執(zhí)行forEach中的函數(shù)多少次
這個方法沒有返回值
var arr = ['a', 'b', 'c', 'd'];
var res = arr.forEach(function (item,index,ar) {
// item 每次函數(shù)執(zhí)行 表示數(shù)組的元素
// index 每次函數(shù)執(zhí)行 表示數(shù)組元素的索引
// ar 每次函數(shù)執(zhí)行 表示調(diào)用forEach的數(shù)組(原數(shù)組)
console.log( item,index,ar )
})
console.log( res ) // undefined
(4) map 數(shù)組映射方法
語法: 數(shù)組.map(參數(shù))
參數(shù)是一個函數(shù),函數(shù)有三個形參
作用: 按照既定的條件操作數(shù)組的每一個元素, 數(shù)組有多少個元素,則執(zhí)行map中的函數(shù)多少次
這個map方法有返回值: 一個新數(shù)組
函數(shù)中return的結(jié)果就是組成新數(shù)組的元素,所以此函數(shù)要有return
此方法不會改變原數(shù)組
var arr = [10, 20, 30, 40];
var res = arr.map(function (item, index, ar) {
// item 每次函數(shù)執(zhí)行 表示數(shù)組的元素
// index 每次函數(shù)執(zhí)行 表示數(shù)組元素的索引
// ar 每次函數(shù)執(zhí)行 表示原數(shù)組
// console.log(item, index, ar)
return item+5;
})
console.log( res ) // [15, 25, 35, 45]
console.log( arr ) // [10, 20, 30, 40]
(5) filter 數(shù)組過濾方法
語法: 數(shù)組.filter(參數(shù))
參數(shù)是一個函數(shù),函數(shù)有三個形參
作用: 數(shù)組有多少個元素,則執(zhí)行filter中的函數(shù)多少次
這個filter方法有返回值: 一個新數(shù)組
函數(shù)中return的結(jié)果,如果為true,則對應(yīng)的這個數(shù)組元素作為新數(shù)組的元素骨宠,如果為false,則對應(yīng)的這個數(shù)組元素不會作為新數(shù)組的元素此方法不會改變原數(shù)組
var arr = [10, 20, 30, 40];
var res = arr.filter(function (item, index, ar) {
// item 每次函數(shù)執(zhí)行 表示數(shù)組的元素
// index 每次函數(shù)執(zhí)行 表示數(shù)組元素的索引
// ar 每次函數(shù)執(zhí)行 表示原數(shù)組
// console.log(item, index, ar)
return item>=30;
})
console.log( res ) // [30, 40]
console.log( arr ) // [10, 20, 30, 40]
(6) every 數(shù)組判斷方法
語法: 數(shù)組.every(參數(shù))
參數(shù)是一個函數(shù),函數(shù)有三個形參
作用: 如果 函數(shù)return false ,則不再執(zhí)行繼續(xù)執(zhí)行函數(shù),不再遍歷數(shù)組,every方法的返回值就是false, 如果數(shù)組遍歷到結(jié)束 每次函數(shù)返回 都是true,則every方法的返回
為true
返回值: 布爾值
此方法不會改變原數(shù)組
var arr = [10, 20, 30, 40, 50];
var res = arr.every(function (item, index, ar) {
// item 每次函數(shù)執(zhí)行 表示數(shù)組的元素
// index 每次函數(shù)執(zhí)行 表示數(shù)組元素的索引
// ar 每次函數(shù)執(zhí)行 表示原數(shù)組
// console.log(item, index, ar)
// return item <= 30;
return item>5;
})
console.log(res) // true
console.log( arr ) // [10, 20, 30, 40]
(7) some 數(shù)組判斷方法
語法: 數(shù)組.some(參數(shù))
參數(shù)是一個函數(shù),函數(shù)有三個形參
作用: 如果 函數(shù)返回 true ,則不再執(zhí)行繼續(xù)執(zhí)行函數(shù),不再遍歷數(shù)組,some方法的返回值就是true, 如果數(shù)組遍歷到結(jié)束 每次函數(shù)返回 都是false,則some方法的返回值為false
返回值: 布爾值
此方法不會改變原數(shù)組
var arr = [10, 20, 30, 40, 50];
var res = arr.some(function (item, index, ar) {
// item 每次函數(shù)執(zhí)行 表示數(shù)組的元素
// index 每次函數(shù)執(zhí)行 表示數(shù)組元素的索引
// ar 每次函數(shù)執(zhí)行 表示原數(shù)組
console.log(item, index, ar)
// return item>5;
// return item >= 30;
return item>100
})
console.log(res) // false
console.log( arr ) // [10, 20, 30, 40]
3.4.3 字符串常用方法
(1) 字符串.charAt(索引)
根據(jù)索引查找字符串中對應(yīng)的字符并返回,如果查找不到,則返回空字符串
var str = 'hello';
console.log( str.charAt(0) ); // 'h'
console.log( str.charAt(5) ); // ''
console.log( typeof str.charAt(5) ); // string
(2) 字符串.charCodeAt(索引)
根據(jù)索引查找字符串中對應(yīng)的字符的編碼值并返回,如果查找不到,則返回NaN
var str = 'hello';
console.log( str.charCodeAt(0) ); // 104 'h'的阿斯克編碼是104
console.log( str.charCodeAt(5) ); // NaN
(3) 字符串.indexOf(參數(shù)) 參數(shù)也是一個字符串
查找參數(shù)在字符串中是否存在,從前往后查找,找到了則停止,存在則返回對應(yīng)的索引,不存在則返回-1
var str = 'hel--lo';
console.log( str.indexOf('h') ); // 0
console.log( str.indexOf('l') ); // 2
// indexOf(參數(shù),起始索引) 從起始索引開始 查找
console.log( str.indexOf('l',3) ); // 5
(4) 字符串.lastIndexOf(參數(shù)) 參數(shù)也是一個字符串
查找參數(shù)在字符串中是否存在,從后往前查找,找到了則停止,存在則返回對應(yīng)的索引,不存在則返回-1
var str = 'hel--lo';
console.log( str.lastIndexOf('h') ); // 0
console.log( str.lastIndexOf('z') ); // -1
console.log( str.lastIndexOf('l') ); // 2
// lastIndexOf(參數(shù),起始索引) 從起始索引開始往前 查找
console.log( str.lastIndexOf('l',3) ); // 2
(5) 字符串.substring(起始索引,結(jié)束索引)
起始索引和結(jié)束索引 是按照傳入的索引 從小到大截取
從起始索引開始截取字符串中的內(nèi)容到結(jié)束索引為止(不包含結(jié)束索引)
var str = 'abcdefg';
console.log(str.substring(2, 5)); // 'cde'
console.log(str.substring(5, 2)); // 'cde'
(6) 字符串.substr(起始索引,截取個數(shù))
從起始索引開始截取字符串中的內(nèi)容
var str = 'abcdefg';
console.log(str.substr(2, 5)); // 'cdefg'
console.log(str.substr(5, 2)); // 'fg'
(7) 字符串.slice(起始索引,結(jié)束索引)
從起始索引開始截取字符串中的內(nèi)容 到結(jié)束索引為止 (不包含結(jié)束索引)
結(jié)束索引可以是負(fù)數(shù) -1表示最后一個字符,-2表示倒數(shù)第二個字符....
var str = 'abcdefg';
// console.log(str.slice(2, 5)); // 'cde'
console.log(str.slice(2, -1)); // 'cdef'
console.log(str.slice(0, 0)); // ''
(8) 字符串.split(參數(shù)) 參數(shù)也是字符串
根據(jù)傳入的內(nèi)容,將字符串打斷(分割),組成一個數(shù)組返回
如果不傳入?yún)?shù),或傳入的參數(shù)在字符串中不存在,則整個字符串就當(dāng)做一個數(shù)組的元素,返回此數(shù)組
如果傳入的是空字符串,則將字符串中的每一個字符,當(dāng)做數(shù)組元素,返回數(shù)組
var str = '2022-6-30';
console.log(str.split('-')); // ["2022", "6", "30"]
console.log(str.split()); // ["2022-6-30"]
console.log(str.split('+')); // ["2022-6-30"]
console.log(str.split('')); //["2", "0", "2", "2", "-", "6", "-", "3", "0"]
(9) 字符串.toLowerCase() 將字符串全轉(zhuǎn)為小寫
var str = 'He-L-lo';
console.log(str.toLowerCase()); // he-l-lo
(10) 字符串.toUpperCase() 將字符串全轉(zhuǎn)為大寫
var str = 'He-L-lo123';
console.log(str.toUpperCase()); // HE-L-LO
(11) 字符串.replace(要替換的內(nèi)容,替換為什么)
var str = 'He-L-lo';
// 替換字符串內(nèi)容,只會替換第一部分內(nèi)容
console.log(str.replace('-','+')); // He+L-lo
(12) 練習(xí)
// 需求: 假設(shè)上傳商品圖片的應(yīng)用場景,需要判斷上傳文件后綴是圖片
var allow = ['jpg', 'png'];
// 給btn一個點擊事件
btn.onclick = function () {
// 獲取選擇的完整文件名
// input標(biāo)簽的值: 元素.value
var fileName = img.value;
// console.log( fileName )
// 獲取上傳文件的后綴
var arr = fileName.split('.');
// arr數(shù)組的最后一個元素就是文件后綴
var ext = arr[arr.length - 1];
// 判斷上傳的文件是否是允許的圖片類型
if(allow.indexOf(ext) === -1){
alert('不是圖片')
}else{
alert('上傳中');
}
}
3.4.4 進制轉(zhuǎn)換
(1) 數(shù)值變量.toString(參數(shù))
參數(shù)就是我們要將數(shù)值轉(zhuǎn)換為多少進制的數(shù)字字符串顯示
默認(rèn)不傳參數(shù)就是十進制
參數(shù)的取值范圍: 2~36
返回值: 進制轉(zhuǎn)化后的字符串
// var num = 20;
console.log( num.toString() ); // '20'
console.log( num.toString(2) ); // '10100'
console.log( num.toString(8) ); // '24'
console.log( num.toString(16) ); // '14'
console.log( num.toString(3) ); // '202'
(2) parseInt(數(shù)字或字符串)
數(shù)字或字符串,將第一個參數(shù)當(dāng)做幾進制計算
如果第二個參數(shù)不寫,就是當(dāng)做十進制數(shù)轉(zhuǎn)給十進制整數(shù)
返回值: 十進制的整數(shù)或者NaN
var str = '1010';
console.log( parseInt(str) ) // 1010
console.log( parseInt(str,2) ) // 10
console.log( parseInt('a1',2) ) // NaN
console.log( parseInt('a1',16) ) // 161
3.5 Math和Date
3.5.1 Math
Math是js中的內(nèi)置一個對象,這個對象中有很多操作數(shù)值的方法
(1) random() 獲取0~1的隨機數(shù)
console.log( Math.random() )
(2) round(數(shù)值) 四舍五入取整
console.log( Math.round(5.1) ) // 5
console.log( Math.round(5.5) ) // 6
console.log( Math.round(5.9) ) // 6
(3) abs(數(shù)值) 求數(shù)值的絕對值
console.log( Math.abs(100) ) // 100
console.log( Math.abs(-100) ) // 100
(4) floor(數(shù)值) 對數(shù)值向下取整
console.log(Math.floor(5.1)) // 5
console.log(Math.floor(5.5)) // 5
console.log(Math.floor(5.9)) // 5
(5) ceil(數(shù)值) 對數(shù)值向上取整
console.log(Math.ceil(5.1)) // 6
console.log(Math.ceil(5.5)) // 6
console.log(Math.ceil(5.9)) // 6
(6) max(多個數(shù)值) 求多個數(shù)值中的最大值
console.log( Math.max(1,2,32,4,1000) ); // 1000
(7) min(多個數(shù)值) 求多個數(shù)值中的最小值
console.log(Math.min(1, 2, 32, 4, 1000)); //1
(8) sqrt(數(shù)值) 求數(shù)值的平方根
console.log( Math.sqrt(4) ); // 2
console.log( Math.sqrt(16) );// 4
console.log( Math.sqrt(25) ); // 5
(9) pow(數(shù)值,多少次方) 求數(shù)值的多次冪
console.log(Math.pow(2, 2)); // 4
console.log(Math.pow(2, 3)); // 8
console.log(Math.pow(2, 4)); // 16
console.log(Math.pow(5, 5)); // 3125
(10) PI 求圓周率
console.log( Math.PI ); // 3.141592653589793
(11) 練習(xí)
// 數(shù)字字母混合驗證碼
// 獲取一個四位的驗證碼
var str = '1234567890qwertyuiopasdfghjklmnbvcxz';
var code = ''; //四位驗證碼變量
// str字符串的索引范圍 0~str.length-1
// 四次獲取str隨機的索引,并根據(jù)索引獲取對應(yīng)的字符然后拼接
for (var i = 0; i < 4; i++) {
var index = getNum(0, str.length - 1); // 獲取隨機索引
code += str.charAt(index); // 根據(jù)索引獲取對應(yīng)的字符,然后拼接在code中
}
console.log( code )
// 獲取n~m的范圍隨機整數(shù)
function getNum(n, m) {
var max = Math.max(n, m);
var min = Math.min(n, m);
return Math.floor(Math.random() * (max - min + 1)) + min;
}
3.5.2 date
Date是js的系統(tǒng)內(nèi)置構(gòu)造函數(shù)
可以通過 new Date() 創(chuàng)建一個時間對象
(1) new Date() 創(chuàng)建時間對象
在new Date() 創(chuàng)建時間對象的時候
- 不傳參數(shù),則返回當(dāng)前的時間對象
- 傳遞參數(shù),如果單獨傳遞的是年月日時分秒?yún)?shù),則至少要傳遞兩個
- 如果傳遞的月份,日期,小時,分鐘,秒超過了范圍,則往上一級時間累計
參數(shù) | 表示 |
---|---|
YYYY | 年份 |
MM | 月份(0~11 0表示1月方灾,11表示12月) |
DD | 日期(月份中的第幾天) |
hh | 小時(0~23) |
mm | 分鐘(0~59) |
ss | 秒(0~59) |
// 不傳參數(shù)得到當(dāng)前時間
// 在控制臺輸出的時候,會讓時間對象調(diào)用toString()方法,轉(zhuǎn)為時間字符串
console.log( new Date() ) // Mon Jul 04 2022 21:13:34 GMT+0800 (中國標(biāo)準(zhǔn)時間)
console.dir(數(shù)據(jù)) 可以查看到數(shù)據(jù)的結(jié)構(gòu)
console.dir( new Date() ) // Object
console.log( new Date() == new Date() ) // false 說明是復(fù)雜數(shù)據(jù)結(jié)構(gòu)
// 傳遞參數(shù)
// 星期 月份 日期 年份 時間
console.log( new Date('2022','6') ) // Fri Jul 01 2022 00:00:00 GMT+0800 (中國標(biāo)準(zhǔn)時間)
// 如果月份傳遞的超過11,則年份+1進行計算
console.log( new Date('2022','12') ) // Sun Jan 01 2023 00:00:00 GMT+0800 (中國標(biāo)準(zhǔn)時間)
console.log( new Date('2022','6','4','21','25','30') ) //Mon Jul 04 2022 21:25:30 GMT+0800 (中國標(biāo)準(zhǔn)時間)
(2) 時間字符串
如果傳遞的是時間字符串,則1就是表示1月份
'YYYY-MM-DD hh:mm:ss'
'YYYY/MM/DD hh:mm:ss'
'YYYY.MM.DD hh:mm:ss'
console.log( new Date('2022-07-05 00:00:00') ) // Tue Jul 05 2022 00:00:00 GMT+0800 (中國標(biāo)準(zhǔn)時間)
console.log( new Date('2022/07/05 00:00:00') ) // Tue Jul 05 2022 00:00:00 GMT+0800 (中國標(biāo)準(zhǔn)時間)
console.log( new Date('2022.07.05 00:00:00') ) // Tue Jul 05 2022 00:00:00 GMT+0800 (中國標(biāo)準(zhǔn)時間)
(3) 時間方法
js給我們共了很多操作時間的方法
主要分為兩套操作時間的方法
- get一套 是獲取時間的方法
- set一套 設(shè)置時間的方法
- 注意:get和set方法一致
獲取時間方法 | 描述 |
---|---|
getFullYear() | 獲取年份 |
getMonth() | 獲取月份 0~11 |
getDate() | 獲取日期 1~31 |
getHours() | 獲取小時數(shù) 0~23 |
getMinutes() | 獲取分鐘數(shù) 0~59 |
getSeconds() | 獲取秒 0~1000 |
getMilliseconds() | 獲取毫秒數(shù) |
getDay() | 獲取星期幾 0~6 |
getTime() | 獲取時間戳 |
var time = new Date();
console.log( time )
// get一套
// 1. getFullyear() 獲取年份
console.log( time.getFullYear() ) // 2022
// 2. getMonth() 獲取月份 0~11
// 0表示1月份 11表示12月份
console.log( time.getMonth() ) // 6
// 3. getDate() 獲取日期 1~31
console.log( time.getDate() ) // 4
// 4. getHours() 獲取小時數(shù) 0~23
console.log( time.getHours() ) // 21
// 5. getMinutes() 獲取分鐘數(shù) 0~59
console.log( time.getMinutes() ) //35
// 6. getSeconds() 獲取秒 0~1000
console.log( time.getSeconds() )
// 7. getMilliseconds() 獲取毫秒數(shù)
console.log( time.getMilliseconds() )
// 8. getDay() 獲取星期幾 0~6
// 0 就是星期天 6就是星期六
console.log( time.getDay() ) // 1
// 9. getTime() 獲取時間戳
// 時間戳: 就是從格林威治時間到 這個時間對象 經(jīng)歷過的時間毫秒數(shù)
// 格林威治時間: 1970-01-01 00:00:00
console.log( time.getTime() )
// set一套 用于設(shè)置時間對象的方法
// 1. setFullYear()
time.setFullYear(2023)
console.log( time ) // Tue Jul 04 2023 21:42:02 GMT+0800 (中國標(biāo)準(zhǔn)時間
// 2. setMonth() 設(shè)置月份 0~11
// 0表示1月份 11表示12月份
time.setMonth(0);
console.log( time ) // Tue Jan 04 2022 21:43:01 GMT+0800 (中國標(biāo)準(zhǔn)時間)
(4) 練習(xí)
// 求兩個時間的 時間差,返回相差 多少天 多少小時 多少分 多少秒
// 定義一個獲取兩個時間的時間差函數(shù),返回相差的 多少天 多少小時 多少分 多少秒
function getDiff(t1, t2) {
// // 1. 將傳入的兩個時間對象轉(zhuǎn)為時間戳(毫秒數(shù))
// t1 = t1.getTime()
// t2 = t2.getTime()
// console.log( t1,t2 )
// // 2. 時間戳相減,得到個相差的毫秒數(shù),除1000 然后取整 得到相差的秒數(shù)
// var diff = Math.round((t2-t1)/1000);
// console.log( diff )
// 獲取兩個時間對象 相差的毫秒數(shù)可以直接將兩個時間對象相減
// 因為在相減的時候,會將兩個時間對象轉(zhuǎn)為 對應(yīng)的時間戳然后相減
// console.log( Math.round((t2-t1)/1000) )
var diff = Math.round((t2 - t1) / 1000);
// 根據(jù)diff計算出 相差的整 天數(shù)
// diff/一天的秒數(shù) 然后取整
var days = parseInt(diff / (24 * 60 * 60));
// 根據(jù)diff計算出 相差的小時數(shù)(不足一天的小時數(shù))
// diff/60/60%24 取整
var hours = parseInt(diff / 60 / 60 % 24);
// console.log( hours )
// 根據(jù)diff計算出 相差的分鐘(不足一小時的分鐘數(shù))
// diff/60%60 取整
var minutes = parseInt(diff / 60 % 60);
// console.log( minutes );
// 根據(jù)diff計算出 相差的秒數(shù)(不足一分鐘的秒數(shù))
// diff%60
var seconds = diff % 60;
// 拼接字符串并返回
return days + '天' + hours + '小時' + minutes + '分鐘' + seconds + '秒';
}
// // 獲取兩個時間對象
// var time1 = new Date();
// var time2 = new Date('2023-01-22 00:00:00');
// // var time2 = new Date('2022-07-06 00:00:00');
// var str = getDiff(time1,time2);
// console.log( str )
// 在頁面中顯示距離春節(jié)的倒計時
// document.write(str)
// 可以使用定時器完成倒計時
// 語法: setInterval(函數(shù),時間)
// 每過一段時間會執(zhí)行一次函數(shù)
// 時間單位是毫秒
setInterval(function () {
// 獲取兩個時間對象
var time1 = new Date(); // 當(dāng)前時間
var time2 = new Date('2023-01-22 00:00:00'); // 春節(jié)時間
var str = getDiff(time1, time2);
// 設(shè)置頁面元素中的內(nèi)容: 語法:元素.inneText = 內(nèi)容. 覆蓋性的設(shè)置
dv.innerText = '距離春節(jié)還有:'+str;
}, 1000)
四嘿棘、BOM 和 DOM
4.1 BOM 瀏覽器對象模型
瀏覽器對象模型: 所有的瀏覽器操作方法都在對象中
- BOM中的頂級對象 是window
- 瀏覽器操作中的各個操作對象 都是window對象的屬性成員
- 全局中的this和top關(guān)鍵字 指向window對象
- BOM操作中 可以省略window焦人,比如: 瀏覽器彈窗 windiw.alert()花椭,實際使用中可以省略window 直接 alert()
- 在全局中通過var定義的變量或函數(shù) 其實就是添加在window對象中的屬性和方法
4.1.1 瀏覽器事件
(1) load 瀏覽器加載事件
// 1. load 瀏覽器加載事件(當(dāng)瀏覽器頁面中將所有資源[圖片,cssm,js....]都加載完畢的時候觸發(fā))
window.onload = function () {
// 這個函數(shù)會在 頁面中所有內(nèi)容都加載完畢后才觸發(fā) 執(zhí)行
console.log( dv ) // <div id="dv"></div>
}
(2) scroll 瀏覽器頁面滾動滾動事件
// 2. scroll 瀏覽器頁面滾動滾動事件
window.onscroll = function () {
console.log( '瀏覽器滾動了' )
}
(3) resize 瀏覽器可視窗口的尺寸變化事件
// 3. resize 瀏覽器可視窗口的尺寸變化事件
window.onresize = function(){
console.log( '窗口大小變化了' );
}
4.1.2 BOM的相關(guān)操作
(1) 獲取瀏覽器的窗口尺寸
- window.innerWidth 瀏覽器可視窗口的寬度(包含滾動條)
- window.innerHeight 瀏覽器可視窗口的高度(包含滾動條)
console.log( window.innerWidth )
console.log( window.innerHeight )
// 在窗口大小變化事件中獲取窗口大小
// 當(dāng)瀏覽器可視窗口大小小于 800的時候div不顯示
window.onresize = function () {
console.log(window.innerHeight)
console.log(window.innerWidth)
if (window.innerWidth < 800) {
// div隱藏
dv.style.display = 'none'
} else {
dv.style.display = 'block'
}
}
(2) 瀏覽器信息
瀏覽器信息通過navigator對象獲取,window.navigator
// 1. 獲取瀏覽器整體信息
console.log( navigator.userAgent ) // Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36
(3) 瀏覽器地址欄
1. location.href 獲取設(shè)置瀏覽器地址url的
// location.href 獲取設(shè)置瀏覽器地址url的,如果給location.href一個新的地址,則頁面會發(fā)生跳轉(zhuǎn)
btn1.onclick = function () {
location.;
}
// 地址中的 中文等特殊字符會被轉(zhuǎn)為url編碼格式展示
console.log( location.href )
2. location.reload() 刷新頁面
// location.reload() 刷新頁面,注意: 不要在全局中直接書寫,不然會一直刷新頁面
location.reload()
btn2.onclick = function () {
location.reload();
}
(4) 瀏覽器的歷史記錄信息
1. history.back()
回退到歷史記錄中的上一個頁面,前提要有歷史記錄
2. history.forward()
前進到歷史記錄中的下一個頁面,前提要有歷史記錄
3. history.go(n)
n為正數(shù)則前進到歷史記錄中的前幾個頁面
n為負(fù)數(shù)則回退到歷史記錄中的后幾個頁面
history.go(-1) 相當(dāng)于 history.back()
history.go(1) 相當(dāng)于 history.forward()
history.go() 會刷新頁面
(5) 瀏覽器的滾動距離
瀏覽器水平滾動距離
瀏覽器垂直滾動距離
1.頁面有DOCTYPE文檔聲明的時候
通過 document.documentElement.scrollLeft 獲取
通過 document.documentElement.scrollTop 獲取
console.log( window.document.documentElement.scrollLeft )
console.log( document.documentElement.scrollTop )
2.頁面沒有DOCTYPE文檔聲明的時候
通過 document.body.scrollLeft 獲取
通過 document.body.scrollTop 獲取
javascript
console.log(document.body.scrollLeft)
console.log( document.body.scrollTop )
(6) 頂部通欄
// 當(dāng)瀏覽器滾動距離小于(800)的時候,隱藏頂部通欄,否則顯示
window.onscroll = function () {
// 獲取滾動的距離
var goLength = document.documentElement.scrollTop;
if (goLength >= 800) {
top1.style.height = '80px';// 顯示頂部通欄
} else {
top1.style.height = '0px';// 隱藏頂部通欄
}
}
4.2 定時器
在前端 js中 代碼執(zhí)行是單線程(同一時間只能做一件事)
JS 提供給我們一個 異步代碼執(zhí)行機制
異步代碼執(zhí)行機制(EventLoop)
- 當(dāng)代碼執(zhí)行過程中,遇見異步代碼了
- 不會立即執(zhí)行異步代碼,而是將異步代碼放到 事件隊列池 中等待
- 繼續(xù)向后執(zhí)行同步代碼
- 等到所有同步代碼執(zhí)行完畢之后,調(diào)用棧清空了,再去異步事件隊列池中拿到異步代碼執(zhí)行
定時器中的函數(shù)是異步執(zhí)行的代碼
4.2.1 定時器開啟
(1)延時定時器
- 語法: setTimeout(函數(shù),數(shù)字,參數(shù)1,參數(shù)2,參數(shù)3,...)
- 函數(shù): 表示時間達到的時候要執(zhí)行的函數(shù)
第一個位置的參數(shù),可以不寫函數(shù),寫js代碼字符串也行 - 數(shù)字: 倒計時間, 單位毫秒
- 第二位置之后的參數(shù),是前面函數(shù)執(zhí)行時候的實參
- 函數(shù): 表示時間達到的時候要執(zhí)行的函數(shù)
console.log( new Date() )
setTimeout(function () {
console.log( '兩秒過去了' )
console.log( new Date() )
},2000)
(2)間隔定時器
- 語法: setInterval(函數(shù),數(shù)字,參數(shù)1,參數(shù)2,參數(shù)3,...)
- 函數(shù): 表示每間隔一段時間要執(zhí)行的函數(shù)
第一個位置的參數(shù),可以不寫函數(shù),寫js代碼字符串也行 - 數(shù)字: 倒計時間, 單位毫秒
- 第二位置之后的參數(shù),是前面函數(shù)執(zhí)行時候的實參
- 函數(shù): 表示每間隔一段時間要執(zhí)行的函數(shù)
setInterval(function(){
console.log( '2s過去了' )
},2000)
4.2.2 定時器返回值
- 返回值為數(shù)字,表示開始定時器的標(biāo)識
- 兩種定時器的返回值都是一個樣
- 不區(qū)分定時器種類,只是表示定時器的第幾個定時器
var t1 = setTimeout(function () {})
var t2 = setInterval(function () {})
console.log( 't1:',t1 )
console.log( 't2:',t2 )
4.2.3 關(guān)閉定時器
- 關(guān)閉銷毀定時器的是,不區(qū)分定時器種類,只要給出的定時器標(biāo)識數(shù)是對的,就可以銷毀
- 語法:
- clearInterval(定時器標(biāo)識)
- clearTimeout(定時器標(biāo)識)
var t1 = setTimeout(function () {console.log( 'timeout' )},3000);
var t2 = setInterval(function () {console.log( 'Interval' )},1000);
btn.onclick = function () {
// clearInterval(t1)
// clearInterval(t2)
clearTimeout(t1)
clearTimeout(t2)
}
4.3 DOM
認(rèn)識DOM - Document Object Model 文檔對象模型
- 如何找到頁面中我們操作的元素
- 操作(操作文本,操作屬性,操作樣式,操作增刪改查)
4.3.1 DOM獲取元素
用一個變量保存頁面中某一個或某些元素
獲取元素方法分兩類獲取非常規(guī)元素和獲取常規(guī)元素
(1) 獲取非常規(guī)元素
- html: document.documentElement
- head: document.head
- body: document.body
- title: document.title
(2)獲取常規(guī)元素
語法 | 名字 | 返回值 |
---|---|---|
.getElementById() | id 獲取元素,只能獲取一個元素 | 有則返回元素奕污,無則返回null |
.getElementsByTagName() | 標(biāo)簽名來獲取元素, 返回類數(shù)組 | 有則返回到數(shù)組中嘱根,無則返回空偽數(shù)組 |
.getElementsByClassName() | 類名來獲取元素该抒, 返回類數(shù)組 | 有則返回數(shù)組凑保,無則返回空偽數(shù)組,為數(shù)組有l(wèi)ength屬性 |
.querySelector() | 選擇器來獲取元素芝此, 只能獲取到匹配的第一個 | 有則返回第一個元素婚苹,無則返回null |
.querySelectorAll() | 選擇器來獲取元素, 返回類數(shù)組 | 有則返回數(shù)組廓译,無則返回空偽數(shù)組责循,可以使用forEach遍歷數(shù)組方法 |
4.3.2 元素屬性
標(biāo)簽屬性分類有三種
(1) 原生屬性
- 在 W3C 規(guī)范中有的屬性名
- 比如: id class style type src href...
(2) 自定義屬性
- 在 W3C 規(guī)范中沒有的屬性名,是我們自己在書寫在標(biāo)簽上的
(3) H5 自定義屬性
- 目的: 就是為了區(qū)分自定義屬性和原生屬性寫在標(biāo)簽上的形式
- 要求: 書寫 H5 自定義屬性的時候,都要 data- 開頭
- 比如: data-index = '888'
- data- 表示這個是 H5 自定義屬性
- index 表示屬性名
- '888' 表示屬性值
4.3.3 操作元素屬性
(1) 操作原生屬性
- 語法: 元素.屬性名 = 屬性值
- 注意: 如果遇到布爾類型屬性,可以使用false或true賦值
(2) 操作自定義屬性(非H5)
<div id="box" index='666' data-index='888' data-id=999>hello</div>
<img src="https://img1.baidu.com/it/u=3923683862,2037492630&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=587"> <br>
<script>
//設(shè)置 語法: 元素.setAttribute(屬性名,屬性值)
dv.setAttribute('stock',99);
// 刪除 語法: 元素.removeAttribute(屬性名)
dv.removeAttribute('index')
// 獲取 語法: 元素.getAttribute(屬性名)
// 返回值: 該元素自定義屬性的值
var res = dv.getAttribute('index');
console.log( res ) // '666'
</script>
(3) 操作H5自定義屬性
每一個 元素節(jié)點 身上都有一個自帶的屬性名叫做 dataset
這個屬性的值是一個類似于 對象的數(shù)據(jù)結(jié)構(gòu),存儲的改標(biāo)簽上所有的H5自定義屬性
H5 自定義屬性的操作,就是對象dataset這個數(shù)據(jù)結(jié)構(gòu)的操作(同對象操作語法)
// 獲取元素
var dv = document.getElementById('box');
var img = document.querySelector('img');
// 查 語法: 元素.dataset.屬性名
console.log( dv.dataset.size )
// 增 語法: 元素.dataset.屬性名 = 屬性值
dv.dataset.size = 999;
// 改 語法: 元素.dataset.屬性名 = 屬性值
dv.dataset.id = 777
// 刪 語法: delete 元素.dataset.屬性
delete dv.dataset.index;
(4) 練習(xí)全選案例
- 全選按鈕的點擊操作
- 當(dāng)全選按鈕是選中的狀態(tài)的時候,所有選項按鈕都是選中狀態(tài)
- 當(dāng)全選按鈕是未選中的狀態(tài)的時候,所有選項按鈕都是未選中狀態(tài)
- 點擊每一個選項按鈕的操作
- 每一個選項按鈕點擊的時候,都要判斷
- 如果所有選項按鈕都是選中狀態(tài),則全選按鈕選中
- 如果所有選項按鈕有任何一個未選中,則全選按鈕未選中
* {
margin: 0;
padding: 0;
}
.box {
width: 100px;
padding: 20px;
margin: 50px auto;
border: 2px solid #333;
border-radius: 10px;
}
hr {
margin: 10px 0;
}
<div class="box">
<input type="checkbox" class="all">全選
<hr>
<input type="checkbox" class="item"> 選項一<br>
<input type="checkbox" class="item"> 選項二<br>
<input type="checkbox" class="item"> 選項三<br>
<input type="checkbox" class="item"> 選項四<br>
</div>
// 獲取元素
var allBtn = document.querySelector('.all');
// 將偽數(shù)組轉(zhuǎn)為真數(shù)組方法
// 語法: Array.from(偽數(shù)組)
// 返回一個真數(shù)組(元素和偽數(shù)組元素一模一樣)
// 為了后面方便操作,將獲取的所有選項按鈕偽數(shù)組轉(zhuǎn)為真數(shù)組
var items = Array.from(document.querySelectorAll('.item'));
// 1. 全選按鈕的點擊操作
allBtn.onclick = function () {
// 遍歷選項按鈕數(shù)組
items.forEach(function (item) {
// 將全選按鈕的 選中 狀態(tài)給每一個選項按鈕
item.checked = allBtn.checked;
})
}
// 2. 點擊每一個選項按鈕的操作
items.forEach(function (item) {
// 遍歷選項按鈕元素數(shù)組,給每一個選項按鈕點擊事件
item.onclick = function () { // 事件處理函數(shù)
// 通過數(shù)組的every方法 判斷 是否 每一個選項按鈕都是 選中
// 選項按鈕全選中為true,只有有一個沒有選中則為false
// 將結(jié)果 給全選按鈕的checked屬性
allBtn.checked = items.every(function (item) {
return item.checked;
})
};
})
4.3.4 操作元素的樣式
在js中操作元素的樣式有三種
- 獲取元素行內(nèi)樣式(只能獲取元素的行內(nèi)樣式)
- 獲取元素的非行內(nèi)樣式(包含了行內(nèi)樣式和非行內(nèi)樣式)
- 設(shè)置元素的樣式(只能設(shè)置元素的行內(nèi)樣式)
注意: 涉及到帶中劃線的樣式名的時候
- 轉(zhuǎn)為駝峰寫法
- 使用數(shù)組關(guān)聯(lián)法
(1) 獲取元素的行內(nèi)樣式
語法: 元素.style.樣式名
console.log( ele.style.width );// 100px
console.log( ele.style.height );// 非行內(nèi)樣式
console.log( ele.style.backgroundColor ) // green
console.log( ele.style['background-color'] ) // green
(2) 獲取元素的非行內(nèi)樣式
語法: window.getComputedStyle(你要獲取樣式的元素).樣式名
// 注意:getComputedStyle在低版本ie中不能使用
console.log( window.getComputedStyle(ele).width ) // 100px
console.log( window.getComputedStyle(ele).height ) // 200px
console.log( window.getComputedStyle(ele).fontSize ) // 20px
console.log( window.getComputedStyle(ele)['font-size'] ) // 20px
// 在低版本ie中獲取元素的非行內(nèi)樣式
// 語法: 元素.currentStyle.樣式名 在主流瀏覽器中不能使用
console.log( ele.currentStyle.fontSize ) // 20px
console.log( ele.currentStyle.width ) // 100px
(3) 設(shè)置元素的樣式(只能設(shè)置行內(nèi)樣式)
語法: 元素.style.樣式名 = 樣式值
ele.style.backgroundColor = 'blue';
ele.style['background-color'] = 'blue';
ele.style.fontSize = '50px';
4.3.5 操作元素的類名
- className
- 就是原生屬性的操作 元素.屬性名
- 因為 JS中有一個關(guān)鍵字叫 class,為了避開改名叫做className
- 注意: 類名的值 是字符串,可以多個類名一起
- classList
- 每一個元素身上都有一個屬性 叫做classList
- 該屬性對應(yīng)的值是一個類似于 數(shù)組的解構(gòu),方法是該元素的所有類名
- 增刪改查都是對象元素的classList操作,有專門的方法
- 增: 元素.classList.add(類名)
- 刪: 元素.classList.remove(類名)
- 切換: 元素.classList.toggle(類名)
- 原來有該類名則刪除,沒有則添加
// className
// 設(shè)置: 元素.className = "值"
// 因為是用的是 = 賦值,會把之前的類名覆蓋
ele.className = 'box';
ele.className = '';
// 追加類名 元素.className += ' 值'
ele.className += ' box'
// classList
console.log( ele.classList )
// 增
ele.classList.add('box');
ele.classList.add('active');
// 刪除
ele.classList.remove('b');
// 切換
ele.onclick = function () {
ele.classList.toggle('active');
}
4.3.6 操作元素的內(nèi)容
(1) innerText
讀
- 語法: 元素.innerText
- 獲取元素的所有文本內(nèi)容
寫 - 語法: 元素.innerText = '值'
- 作用: 完全覆蓋是的書寫標(biāo)簽文本內(nèi)容
- 注意: 沒有辦法識別解析 html格式的字符串
// innerText
console.log(ele.innerText)
ele.innerText = '666';
ele.innerText = '<h1>888</h1>';
(2) innerHTML
是一個讀寫屬性
讀
- 語法: 元素.innerHTML
- 獲取元素的所有內(nèi)容(包含了超文本內(nèi)容),以html格式字符串的形式返回
寫 - 語法: 元素.innerHTML = '值'
- 作用: 完全覆蓋是的書寫標(biāo)簽 超文文本內(nèi)容
- 注意: 可以識別解析 html格式的字符串
// innerHTML
console.log(ele.innerHTML)
ele.innerHTML = '666';
ele.innerHTML = '<h1>888</h1>';
(3) value
表單標(biāo)簽的內(nèi)容操作
一個讀寫屬性,其實就是原生屬性value操作
讀
- 語法: 表單元素.value
- 得到: 該表單元素的value值
寫 - 語法: 表單元素.vlaue = '值'
- 作用: 設(shè)置表單元素的value值
// value
console.log( inp.value )
inp.value = 888
4.3.7 獲取元素的尺寸
有兩套語法offsetWdith和offsetHeight
(1) 語法
- 元素.offsetWdith
- 獲取元素的 內(nèi)容+padding+border 區(qū)域的寬度
- 元素.offsetHeight
- 獲取元素的 內(nèi)容+padding+border 區(qū)域的高度
- 注意: 不管盒子是什么模型,區(qū)域不變
// // 1. offset方式
console.log( ele.offsetWidth )
console.log( ele.offsetHeight )
(2) 語法
- 元素.clientWdith
- 獲取元素的 內(nèi)容+padding 區(qū)域的寬度
- 元素.clientHeight
- 獲取元素的 內(nèi)容+padding 區(qū)域的高度
// 2. client方式
console.log(ele.clientWidth)
console.log(ele.clientHeight)
4.3.8 獲取元素的偏移量
(1) 獲取偏移量參考元素
語法: 元素.offsetParent
得到: 該元素的偏移量參考父級
- 就是該元素的定位父級
- 如果到body都沒有定位父級,那么這里的offsetParent就是body
(2)第一套語法
- 元素.offsetLeft
- 獲取元素相對于 offsetParent 的左側(cè)距離
- 元素.offsetTop
- 獲取元素相對于 offsetParent 的上方距離
(3)第二套語法
- 元素.clientLeft
- 獲取元素(內(nèi)容+padding區(qū)域) 相對于該元素border左邊的尺寸
- 元素.clientTop
- 獲取元素(內(nèi)容+padding區(qū)域) 相對于該元素border上邊的尺寸
console.log( 'offsetParent:',spanEle.offsetParent )
console.log( 'offsetLeft:',spanEle.offsetLeft )
console.log( 'offsetTop:',spanEle.offsetTop )
console.log( 'clientLeft:',spanEle.clientLeft )
console.log( 'clientTop:',spanEle.clientTop )
4.3.9 獲取可視窗口尺寸
BOM 級別獲取: 包含滾動條
- innerWidth
- innerHeight
DOM 級別獲取: 不包含滾動條
- document.documentElement.clientHeight
- document.documentElement.clientWidth
// 獲取可視窗口
console.log( 'BOM' )
console.log( '寬度',window.innerWidth )
console.log( '高度',window.innerHeight )
console.log( 'DOM' )
console.log( '寬度',document.documentElement.clientWidth)
console.log( '高度',document.documentElement.clientHeight)