天天看點

JavaScript學習筆記JavaScript數組操作節點數組周遊方式作用域預解析字元串操作DOM對象浏覽器的兩個資料存儲執行上下文this關鍵字this的劫持垃圾回收機制閉包定時器元素的自定義屬性classList數組時間對象數學函數顯示原型與隐式原型原型鍊

目錄

  • 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

三種使用方式

  1. 在浏覽器控制台上直接運作js語言片段
  2. 在html檔案的script标簽中
  3. 使用.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():彈窗提示

JavaScript學習筆記JavaScript數組操作節點數組周遊方式作用域預解析字元串操作DOM對象浏覽器的兩個資料存儲執行上下文this關鍵字this的劫持垃圾回收機制閉包定時器元素的自定義屬性classList數組時間對象數學函數顯示原型與隐式原型原型鍊

confirm():确認模态,具備傳回值

JavaScript學習筆記JavaScript數組操作節點數組周遊方式作用域預解析字元串操作DOM對象浏覽器的兩個資料存儲執行上下文this關鍵字this的劫持垃圾回收機制閉包定時器元素的自定義屬性classList數組時間對象數學函數顯示原型與隐式原型原型鍊

prompt():輸入模态

JavaScript學習筆記JavaScript數組操作節點數組周遊方式作用域預解析字元串操作DOM對象浏覽器的兩個資料存儲執行上下文this關鍵字this的劫持垃圾回收機制閉包定時器元素的自定義屬性classList數組時間對象數學函數顯示原型與隐式原型原型鍊

擷取文檔元素

  • 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])
  }
}
           

擷取頁面元素的樣式屬性值

  1. e利用element.style 擷取元素的樣式對象
  2. 利用全局函數 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中目前存在三種作用域:

  1. 全局作用域 es6之前
  2. 函數作用域 es6之前
  3. 塊級作用域{} 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

  1. 跳轉頁面,location.href=‘’
  2. 跳轉頁面不計入曆史,更新位址欄,不計入曆史操作,location.replace(‘’)
  3. 重新整理頁面,location.reload()
  4. 位址欄參數?号後的資料,location.search

history

浏覽器浏覽記錄

  1. history.forward(),前進
  2. history.back(),後退
  3. 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類:

  1. 全局執行上下文
  2. 函數執行上下文
  3. eval()執行上下文(忽略,隻做了解)

this關鍵字

  1. 在浏覽器環境中的全局上下文中,this永遠指向的是 頂層對象 window
  2. 在浏覽器環境中函數執行上下文中,this指向的也是 頂層對象 window , 嚴格模式除外! 函數執行上下文,設定了嚴格模式,那麼this指向的 undefined
  3. 如果函數是被某個對象進行調用時,那麼該函數(方法)中的this指向的是,它的調用對象(調用者)!而非持有者!
  4. 構造函數中this,指向的是新建立出來的一個該構造函數類型的 執行個體 {} 空對象!
  5. 事件對象的事件處理函數中的this,指向的是 目前被綁定的元素對象,僅适用于 function函數
  6. 箭頭函數,它不存在自己的this,它的this是該箭頭函數被建立時,當時的執行上下文環境中的this!并且永不改變包括this的三大劫持手段!(類似于‘印随效應’)

構造函數與普通函數的差別

  1. 構造函數中預設傳回值已經構造完成的對象
  2. 普通函數預設傳回值是 undefined
  3. 構造函數需要搭配new關鍵字進行使用
  4. 構造函數的目的不是為了實作某種功能,而是去快速構造某一類型的執行個體對象
  5. 構造函數中的this指向的是new關鍵字所建立的該構造函數類型的對象執行個體!

new關鍵字是配合構造函數使用:

new關鍵字,做了幾件事情:

  1. new關鍵字會建立一個該構造函數的執行個體對象,一開始是空的{}
  2. new關鍵字會将剛才建立的執行個體對象的__proto__屬性指向為 構造函數所儲存的 prototype指向的對象
  3. new關鍵字會将構造函數中的this 指向為 該執行個體對象
  4. 最終傳回這個 執行個體對象

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程式在運作的過程中,随着運作時間的增加,那麼會相應的産生一些垃圾資料,垃圾回收機制主要是定時 的去清理這些垃圾資料,避免記憶體溢出、洩露導緻程式崩潰!

閉包

閉包:把一些資料進行封裝!包裹!形成一個獨立的空間,該空間隻會被能通路到該空間的‘人’使用。

什麼是閉包?

閉包就是一個函數在其他函數的内部嵌套聲明,并且該函數内部使用了上級函數的資料!并且該函數被傳回出去了!

閉包的優點:

  1. 使用閉包可以形成對立的空間,避免變量名污染問題
  2. 利用閉包,可以在函數外,也能通路到函數内部的資料!

閉包的缺點:

  1. 閉包的産生有很多時候是隐式産生的,最終會造成記憶體洩漏

定時器

js提供了兩種建立定時器的方式:

  • setTimeout(一次性的)

    關閉定時器:clearTimeout()

  • setInerval(永久性的)

    關閉定時器:clearInterval()

元素的自定義屬性

如何建立自定義屬性

  1. 直接在元素的開始标簽中,書寫自定義的屬性名以及指派操作
  2. 利用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()

操作時間對象

  1. 擷取對應的時間資料
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())
           
  1. 設定對應的時間資料
//   将以上的所有方法的 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

//   以上描述尋找的過程就稱為  原型鍊!
           

繼續閱讀