目錄
- JavaScript
-
- 三種使用方式
- 三種聲明變量
- js中的辨別符命名規範
- 資料類型
- JSON對象
-
- 序列化
- 反序列化
- 資料類型的轉換
- 運算符
- 彈窗
- 擷取文檔元素
- 元素對象的标簽體屬性
- 數組
-
- 判斷是否是數組
- 數組的常見操作
- 對數組進行去重操作
- 擷取頁面元素的樣式屬性值
- 操作節點
-
- 建立節點
- 添加節點
- 替換節點
- 删除操作
- 查詢操作
- 收集form表單資料
- 數組周遊方式
-
- 1. 傳統的for循環來周遊
- 2. forEach()
- 3. every()
- 4.some()
- 5.map()
- 6.filter()
- 7.find()
- 8.findIndex()
- 作用域
- 預解析
- 字元串操作
-
- 1.charAt()
- 2.split()
- 3.concat()
- 4.includes()
- 5.indexOf()
- 6.lastIndexOf()
- 7.trim()
- 8.trimStart()
- 9.trimEnd()
- 10.toUpperCase()
- 11.toLowerCase()
- 12.substring()
- 13.startsWith()
- 14.endsWith()
- 15.replace()
- DOM對象
-
- window
- location
- history
- navigator
- 浏覽器的兩個資料存儲
-
- localStorage
- sessionStorage
- 執行上下文
- this關鍵字
-
- 構造函數與普通函數的差別
- this的劫持
- 垃圾回收機制
- 閉包
- 定時器
- 元素的自定義屬性
- classList數組
- 時間對象
-
- 建立時間對象4種
- 操作時間對象
- 數學函數
- 顯示原型與隐式原型
- 原型鍊
JavaScript
三種使用方式
- 在浏覽器控制台上直接運作js語言片段
- 在html檔案的script标簽中
- 使用.js檔案書寫js代碼,然後在html中通過script标簽引入代碼
方式2常見的位置如下:
- head标簽中
- body标簽的末尾
- html标簽中,與body标簽同級(推薦使用)
三種聲明變量
關鍵字 | 說明 |
---|---|
var | 可以重複聲明相同的變量 |
let | 不能在同一作用域重複聲明相同變量 |
const | 不能在同一作用域重複聲明相同變量 |
js中的辨別符命名規範
- 辨別符隻能由字母、數字、下畫線、以及$符号組成
- 辨別符不能以數字進行開頭
- 辨別符嚴格區分大小寫
- 不能采用關鍵字或者保留字進行辨別符的定義
- 辨別符如果由多個單詞構成,應遵循‘小駝峰命名法’
- 辨別符的命名應遵循‘見名知意’
資料類型
- 原始資料類型7種
- undefined
- Boolean
- Number
- String
- BigInt
- Symbol
- null
- 對象類型
- Object
口訣:四基(Number、String、Boolean、BigInt)兩空(undefined、null)雙一(一個符号Symbol、一個對象Object)
檢視資料類型使用typeof
JSON對象
json對象(花括号對象)
序列化
var res = JSON.stringify(obj)
console.log(res, typeof res)
反序列化
var newobj = JSON.parse(res)
console.log(newobj, typeof newobj)
資料類型的轉換
資料類型的轉換可分為強制轉換和隐式轉換兩種。
強制轉換:人為的通過手段去改變一個資料的類型
隐式轉換:沒有人為的參與,是程式解析自動進行轉換
函數 | 說明 |
---|---|
Number() | 将其他資料類型強制轉換為Number資料類型 |
parseInt() | 将其他資料類型強制轉換為Number資料類型 |
parseFloat() | 将其他資料類型強制轉換為Number整數值 |
parseFloat() | 将其他資料類型轉換為Number的浮點數 |
String() | 将其他資料類型強制轉換為字元串類型 |
Boolean() | 将其他資料類型強制轉換為布爾類型 |
運算符
js中運算符分類:
- 算術運算符
- 指派運算符
- 比較運算符
- 邏輯運算符
- 三元運算符
- 單目運算符
彈窗
alert():彈窗提示
confirm():确認模态,具備傳回值
prompt():輸入模态
擷取文檔元素
- doucument.querySelector():傳回值是符合css選擇器下的第一個頁面元素對象
- document.querySelectorAll():傳回值是符合css選擇器所有頁面元素對象,不管元素有多少個始終以NodeList僞數組的形式傳回
- document.getElementById():通過元素的id屬性值進行擷取
- document.getElementsByClassName():通過元素的class屬性值進行擷取!以HTMLCollection僞數組形式傳回
- document.getElementsByTagName():通過元素的标簽名進行擷取
元素對象的标簽體屬性
- innerHTML:用于更改元素的标簽體的内容,合法的字元會被浏覽器自動解析為标簽!
- innerText:用于更改元素的文本資訊,該文本資訊是不會被浏覽器當作标簽來正常解析的
數組
數組:是存儲一組資料的一個容器,屬于Object類型。
1.兩種建立方式
方式一
方式二
2.擷取數組中元素的值,利用元素的下标
判斷是否是數組
通過Array的靜态方法isArray()進行判斷,傳回true或false
let arr = []
console.log(Array.isArray(arr))
數組的常見操作
方法 | 說明 |
---|---|
length | 傳回目前數組長度 |
push() | 添加元素到數組的末尾 |
pop() | 删除數組末尾元素,傳回值是移除的末尾元素 |
unshift() | 添加元素到數組的頭部 |
shift() | 删除數組頭部的元素,傳回值是被删除的元素 |
splice() | 在數組的任意位置實作元素的添加、删除、修改 |
concat() | 連接配接多個數組,并傳回連接配接後的新數組,沒有操作元素組 |
join() | 将數組中的個元素分散通過指定的字元進行連接配接,傳回一個字元串資料 |
includes() | 判斷一個元素是否存在于目前資料中,傳回true或false |
indexOf() | 從左往右判斷元素是否存在,傳回下标或-1 |
lastindexOf() | 從右向左判斷元素是否存在,傳回下标或-1 |
slice() | 數組切片,擷取數組的子數組,slice(開始下标,結束下标) ,左閉右開的區間 |
splice(x,y,args…)
- x : 确定在數組的那個位置進行操作
- y : 是确實從對應位置開始删除的元素個數
- args: 用于更新的新元素清單
splice舉例
// 需求,我想在1索引的位置,删除2個元素,并用 新的元素進行替換
arr.splice(1, 2, 'x', 'y', 'z')
// 需求,我想在2索引的位置,删除1個元素,沒有新元素替換
arr.splice(2, 1)
// 需求,我想替換索引3位置元素的值,更新
arr.splice(3, 1, 'world!')
// 需求,我想在索引0的位置,添加兩個新元素
let res = arr.splice(0, 0, 'x', 'y', 'z')
利用concat方法實作數組淺拷貝
對數組進行去重操作
方式一
//利用空數組
let arr2 = []
for (let i = 0; i < arr.length; i++) {
if (!arr2.includes(arr[i])) {
arr2.push(arr[i])
}
}
方式二
//利用 lastindexOf() splice()
let index
for (let i = 0; i < arr.length; i++) {
index = arr.lastIndexOf(arr[i]) //index = 3
while (index != i) {
arr.splice(index, 1)
index = arr.lastIndexOf(arr[i])
}
}
擷取頁面元素的樣式屬性值
- e利用element.style 擷取元素的樣式對象
- 利用全局函數 getComputedStyle(element)
兩者的差別:
- style屬性的方式隻能去擷取元素自身的style屬性所設定的樣式值
- getComputedStyle(element) 擷取元素正在應用的樣式屬性值
- style屬性是可讀可寫,而getComputedStyle(element是隻讀的不能重新指派
操作節點
建立節點
添加節點
// 在挂載前 初始化 元素節點
mydiv.id = 'div01'
mydiv.className = 'box'
mydiv.innerHTML = '我是div元素'
挂載節點
方式一:appendChild(element)
方式二:insertBefore(新節點元素,舊節點元素)
// 如果insertBefore的第二個參數為 null 則将新元素節點添加到該父節點的末尾 等價于 appendChild
document.body.insertBefore(mydiv, null)
替換節點
//擷取父節點,由父節點來完成替換操作
let ul = document.querySelector('ul')
//替換操作
ul.replaceChild(newli, oldli)
// 利用指定的新元素,去替換目前父元素下所有的子元素
ul.replaceChildren(newli1)
删除操作
方式一:元素自删除
let firstli = document.querySelector('.first-li')
firstli.remove() // 元素自我删除
方式二:利用父節點删除指定子元素節點
let ul = document.querySelector('ul')
ul.removeChild(firstli)
查詢操作
方式一:通過元素節點的屬性查詢自己的父元素節點
//parentNode傳回指定的節點在 DOM 樹中的父節點
let res = firstli.parentNode // 節點
console.log(res)
//parentElement傳回目前節點的父元素節點,如果該元素沒有父節點,或者父節點不是一個 DOM 元素,則傳回 null
console.log(firstli.parentElement === res)
方式二:通過父元素查詢它的所有子元素節點
let ul = document.querySelector('ul')
// 元素的屬性 children 屬性傳回的是一個僞數組
console.log(ul.children)
收集form表單資料
普通方式
let btn = document.querySelector('.btn')
btn.addEventListener('click', function () {
let inputs = document.querySelectorAll('input[name]')
for (let i = 0; i < inputs.length; i++) {
console.log(inputs[i].value)
}
})
快速方式
//new FormData(表單對象)
let btn = document.querySelector('.btn')
btn.addEventListener('click', function () {
let formdata = new FormData(document.querySelector('form'))
console.log(formdata.get('id'))
console.log(formdata.get('name'))
console.log(formdata.get('sex'))
console.log(formdata.get('age'))
})
數組周遊方式
1. 傳統的for循環來周遊
2. forEach()
// el : 代表目前正在通路的數組元素
// index:代表目前正在通路的元素下标
// myarr:操作數組本身 一般情況下會省略myarr參數
arr.forEach((el, index, myarr) => {}
3. every()
與forEach基本一樣,every有傳回值,傳回布爾值,有個元素不滿足傳回false。
作用:判斷某個數組中是否所有的元素都滿足相應要求。
// 需求:判斷一個數組中是否每一個元素都是偶數
let myarr = [2, 2, 4, 8, 16, 10]
let res = myarr.every((el) => {
return el % 2 == 0
})
if (res) {
console.log('該數組全部是偶數')
} else {
console.log('該數組中隻是有一個元素不是偶數')
}
4.some()
與every方法相反,有個元素滿足傳回false。
5.map()
會傳回一個新的數組
let arr = [100, 200, 300, 400]
// 需求:我想将arr數組中的每一個元素在原有的基礎上增加一倍!
let res = arr.map((el) => {
return el * 2
})
//該方法可以用來實作淺拷貝
let res = arr.map((el) => {
return el
})
6.filter()
過濾器,也會傳回一個新的數組
// 需求:篩選出arr數組中的所有偶數 組成一個新的數組
let res = arr.filter((el) => {
return el % 2 == 0
})
7.find()
從數組中查找符合條件的第一個元素并傳回該元素,如果周遊完整數組都沒有找到符合添加的元素則傳回undefined。
8.findIndex()
從數組中查找符合條件的第一個元素并傳回該元素的下标值,如果周遊完整數組都沒有找到符合添加的元素則傳回-1。
作用域
作用域:指變量或函數的作用範圍
js中目前存在三種作用域:
- 全局作用域 es6之前
- 函數作用域 es6之前
- 塊級作用域{} es6之後才有塊級作用域
預解析
預解析:js代碼在真正的執行前,會先執行一個操作,該操作成為預解析。
預解析主要涉及兩個内容:目前作用域下的var變量和function函數進行提升。
let和const所修飾的變量不具備提升操作
字元串操作
将字元串看作是數組的形式,進行通路字元串中單個字元,利用下标通路。
let str1 = 'hello world!'
console.log(str1[0])
console.log(str1[1])
console.log(str1[2])
// length屬性 檢視字元串的長度!
console.log(str1.length)
從正常來說,基本資料類型不是對象,是無法擁有屬性和方法的,也不能像操作對象那樣操作普通資料。但是在js中一個工具,js引擎在執行非對象類型的資料時,如果該資料類型并不是Object,那麼js會進行包裝,把它包裝成一個Object類型。
1.charAt()
通過指定的下标進行通路對應的字元,類似于str[0]
let str = 'hello world!'
let res = str.charAt(0) // 等價于 str[0]
console.log(res)
2.split()
通過指定的字元串分割成一個字元數組
let str = 'hello world!'
let res = str.split('')
3.concat()
将多個字元串進行拼接,等價于+
let str1 = 'hello'
let str2 = 'world!'
let str3 = str1.concat(str2)
console.log(str3)
4.includes()
chaxvn是否存在一個指定的字元,存在則傳回true,不存在傳回false。
let str = 'abcdefg'
let res = str.includes('a')
console.log(res)
5.indexOf()
查詢是否存在一個指定字元,存在傳回對應下标值,不存在傳回-1。從左往右查找第一個比對的字元下标。
let str = 'abcdefg'
let res = str.indexOf('a')
console.log(res)
6.lastIndexOf()
查詢是否存在一個指定字元,存在傳回對應下标值,不存在傳回-1。從右往左查找第一個比對的字元下标。
7.trim()
去除字元串前後的空格。
let str = ' hello world! '
let res = str.trim()
console.log(res)
8.trimStart()
去除字元串前面的空格。
9.trimEnd()
去除字元串後面的空格。
10.toUpperCase()
将字元串中所有的小寫字母轉換為大寫字母。
let str = 'abcdefgABCDN'
let res = str.toUpperCase()
console.log(res)
11.toLowerCase()
将字元串中所有的大寫字母轉換為小寫字母。
12.substring()
substring(開始下标,結束下标) 方法是對字元串進行截取。
- 如果 indexStart 等于 indexEnd,substring 傳回一個空字元串
- 如果省略 indexEnd,substring 提取字元一直到字元串末尾,
- 如果任一參數小于 0 或為 NaN,則被當作0。
13.startsWith()
判斷該字元串是否以指定的字元串進行開頭。
let str = 'hello world!'
let res = str.startsWith('hello')
console.log(res)
14.endsWith()
判斷該字元串是否以指定的字元串進行結尾。
15.replace()
将指定的字元替換為其他字元。
let str = 'hello world!'
let res = str.replace('hello', 'xxxx')
console.log(res)
DOM對象
window
除了指向的是浏覽器的視窗,還代表着js在浏覽器環境下全局對象,也稱為頂層對象。
location
- 跳轉頁面,location.href=‘’
- 跳轉頁面不計入曆史,更新位址欄,不計入曆史操作,location.replace(‘’)
- 重新整理頁面,location.reload()
- 位址欄參數?号後的資料,location.search
history
浏覽器浏覽記錄
- history.forward(),前進
- history.back(),後退
- history.go(1) 等價于 history.forward();history.go(-1) 等價于 history.back()
navigator
用于檢視裝置資訊,查詢目前浏覽器的資訊、版本、名稱等。
浏覽器的兩個資料存儲
localStorage
資料持久化到浏覽器中,關閉視窗或浏覽器,都不會消失。
// 設定資料, key 和 value 資料類型必須是字元串類型
localStorage.setItem('name', '張三')
// 設定資料 []
localStorage['age'] = 18
// 讀取資料
console.log(localStorage.getItem('name'))
console.log(localStorage['age'])
sessionStorage
資料臨時存到浏覽器中,以鍵值對的形式,視窗關閉資料就消失。
// 設定資料, key 和 value 資料類型必須是字元串類型
sessionStorage.setItem('name', '張三')
// 設定資料 []
sessionStorage['age'] = 18
// 讀取資料
console.log(sessionStorage.getItem('name'))
console.log(sessionStorage['age'])
執行上下文
js代碼在執行過程中,會存在一個環境,js引擎會将js代碼,分别設定一個執行環境。
執行上下文環境分3類:
- 全局執行上下文
- 函數執行上下文
- eval()執行上下文(忽略,隻做了解)
this關鍵字
- 在浏覽器環境中的全局上下文中,this永遠指向的是 頂層對象 window
- 在浏覽器環境中函數執行上下文中,this指向的也是 頂層對象 window , 嚴格模式除外! 函數執行上下文,設定了嚴格模式,那麼this指向的 undefined
- 如果函數是被某個對象進行調用時,那麼該函數(方法)中的this指向的是,它的調用對象(調用者)!而非持有者!
- 構造函數中this,指向的是新建立出來的一個該構造函數類型的 執行個體 {} 空對象!
- 事件對象的事件處理函數中的this,指向的是 目前被綁定的元素對象,僅适用于 function函數
- 箭頭函數,它不存在自己的this,它的this是該箭頭函數被建立時,當時的執行上下文環境中的this!并且永不改變包括this的三大劫持手段!(類似于‘印随效應’)
構造函數與普通函數的差別
- 構造函數中預設傳回值已經構造完成的對象
- 普通函數預設傳回值是 undefined
- 構造函數需要搭配new關鍵字進行使用
- 構造函數的目的不是為了實作某種功能,而是去快速構造某一類型的執行個體對象
- 構造函數中的this指向的是new關鍵字所建立的該構造函數類型的對象執行個體!
new關鍵字是配合構造函數使用:
new關鍵字,做了幾件事情:
- new關鍵字會建立一個該構造函數的執行個體對象,一開始是空的{}
- new關鍵字會将剛才建立的執行個體對象的__proto__屬性指向為 構造函數所儲存的 prototype指向的對象
- new關鍵字會将構造函數中的this 指向為 該執行個體對象
- 最終傳回這個 執行個體對象
this的劫持
this的劫持方法: call() 、 apply() 、 bind(),以上的三個方法都屬于,Function執行個體對象身上的方法!箭頭函數this不能被劫持!
// call劫持
var obj1 = {
name:'obj1',
fun:function(a,b){
console.log(this,a,b)
}
}
var obj2 = {
name:'obj2'
}
// 正常情況調用
obj1.fun(100,200)
// call方法調用
obj1.fun.call(obj2,100,200)
垃圾回收機制
垃圾回收:JavaScript程式在運作的過程中,随着運作時間的增加,那麼會相應的産生一些垃圾資料,垃圾回收機制主要是定時 的去清理這些垃圾資料,避免記憶體溢出、洩露導緻程式崩潰!
閉包
閉包:把一些資料進行封裝!包裹!形成一個獨立的空間,該空間隻會被能通路到該空間的‘人’使用。
什麼是閉包?
閉包就是一個函數在其他函數的内部嵌套聲明,并且該函數内部使用了上級函數的資料!并且該函數被傳回出去了!
閉包的優點:
- 使用閉包可以形成對立的空間,避免變量名污染問題
- 利用閉包,可以在函數外,也能通路到函數内部的資料!
閉包的缺點:
- 閉包的産生有很多時候是隐式産生的,最終會造成記憶體洩漏
定時器
js提供了兩種建立定時器的方式:
-
setTimeout(一次性的)
關閉定時器:clearTimeout()
-
setInerval(永久性的)
關閉定時器:clearInterval()
元素的自定義屬性
如何建立自定義屬性
- 直接在元素的開始标簽中,書寫自定義的屬性名以及指派操作
- 利用data-* 形式建立自定義屬性
讀取自定義的元素屬性值
element.getAttribute(‘屬性名’),該方式可讀取自定義的與官方預定義的。
修改、設定一個元素的自定義屬性,利用setAttribute會将資料隐式的轉換為string類型。
element.setAttribute(‘add’, true)
特别的data-屬性的讀取方式
element.dataset.*(*是自定義的data-後面的内容)
classList數組
比className好用
className添加類的樣式時需要下面這樣加,注意類名前面有個空格。
classList方式如下
//添加
box.classList.add('box2')
//移除
box.classList.remove('box2')
時間對象
建立時間對象4種
方式一
let date = new Date() // 傳回一個目前系統時間的,時間對象
方式二
let date = new Date(59000)
方式三
let date = new Date(‘1997-10-19’)
方式四
依次傳入 年 月 日 時 分 秒 毫秒 進行構造時間對象
let date = new Date(2023, 1, 31, 11, 34, 48, 1500)
特殊的使用方式
Date()函數 傳回的是目前時間對象的字元串形式!
let date1 = Date()
操作時間對象
- 擷取對應的時間資料
let date = new Date() // 14:23:1:578
console.log(date)
// 1- 擷取時間對象的年份
console.log(date.getFullYear())
//2- 擷取時間對象的月份, 注意月份是從 0開始計算的 0代表1月
console.log(date.getMonth() + 1)
//3- 擷取時間對象的日 一個月的第幾天
console.log(date.getDate())
//4- 擷取時間對象的 星期數 注意:範圍是0-6 0代表星期天
console.log(date.getDay())
//5- 擷取時間對象的 小時數
console.log(date.getHours())
//6- 擷取時間對象的 分鐘數
console.log(date.getMinutes())
//7- 擷取時間對象的 秒數
console.log(date.getSeconds())
//8- 擷取時間對象的 毫秒數
console.log(date.getMilliseconds())
- 設定對應的時間資料
// 将以上的所有方法的 get 替換為 set,如
date.setFullYear(2000)
console.log(date)
擷取時間對象的時間戳
//擷取目前系統時間的時間戳
console.log(Date.now())
// 擷取目前時間對象的時間戳
console.log(date.getTime())
數學函數
注意:Math函數不能作為構造函數使用! 是無法執行個體化一個數學對象!
方法 | 說明 |
---|---|
floor() | 地闆數,對一個數向下取整 |
ceil() | 天花闆數,對一個數向上取整 |
max() | 傳回目前參數清單中最大值 |
min() | 傳回目前清單中最小值 |
pow() | 求一個數的幂 |
sqrt() | 開平方根 |
round() | 對一個數四舍五入 |
random() | 随機數,随機傳回一個0-1之間的小數,不包括1 |
顯示原型與隐式原型
- JS中任何的一個執行個體對象都具備一個 隐式原型屬性 __ proto __
- JS中所有的function函數身上都具備一個 顯示原型屬性 prototype
function身上同時具備 __ proto __ 和 prototype
原型鍊
// 執行個體對象身上__proto__ 存儲的是什麼資料類型? Object
// 原型鍊
// 每一個執行個體對象上都具備 __proto__ 原型對象
// 當一個對象在自身上找不到對應的屬性或者方法時,會沿着__proto__原型對象身上去尋找! obj {}
// 如果往上一級的__proto__身上還是找不到想要的屬性或者方法 obj.__proto__
// 那麼它會繼續沿着目前這一級__proto__繼續尋找! obj.__proto__.__proto__
// .... obj.__proto__.__proto__.__proto__
// 沿着原型鍊最終找到 null 就結束! 如果已經通路到null 都還沒有找到想要的屬性或者方法 則放回 undefined
// 以上描述尋找的過程就稱為 原型鍊!