【JS】Chapter15-高階技巧

站在巨人的肩膀上

黑馬程序員前端JavaScript入門到精通全套視頻教程,javascript核心進階ES6語法、API、js高級等基礎知識和實戰教程

(十五)高階技巧

1. 深淺拷貝

  • 開發中我們經常需要復制一個對象。如果直接用賦值會有下面問題:
    // 一個 pink 對象
    const pink = {name: 'pink老師',age: 18
    }
    const red = pink
    console.log(red)    // { name: 'pink老師', age: 18 }
    red.name = 'red老師'
    console.log(red)    // { name: 'red老師', age: 18 }
    // 但是 pink 對象里面的 name 值也發生了變化
    console.log(pink)   // { name: 'red老師', age: 18 }
    

1.1 淺拷貝

  • 首先淺拷貝和深拷貝只針對引用類型。
  • 淺拷貝:拷貝的是地址
  • 常見方法:
    1. 拷貝對象:Object.assgin() / 展開運算符 {…obj} 拷貝對象
    2. 拷貝數組:Array.prototype.concat() 或者 […arr]
  • 例子1:
    const obj = {uname: 'pink'
    }
    const o = { ...obj }
    console.log(o)      // { uname: 'pink' }
    o.uname = 'red'
    console.log(o)      // { uname: 'red' }
    console.log(obj)    // { uname: 'pink' }
    
  • 例子2:
    // 一個 pink 對象
    const pink = {name: 'pink老師',age: 18
    }
    const red = {}
    Object.assign(red, pink)
    console.log(red)    // { name: 'pink老師', age: 18 }
    red.name = 'red老師'
    console.log(red)    // { name: 'red老師', age: 18 }
    // 不會影響 pink 對象
    console.log(pink)   // { name: 'pink老師', age: 18 }
    
  • 例子3:
    ```js
    // 一個 pink 對象
    const pink = {
    name: ‘pink老師’,
    age: 18,
    family: {
    mother: ‘pink媽媽’
    }
    }
    const red = {}
    Object.assign(red, pink)
    console.log(red) // { name: ‘pink老師’, age: 18 }
    red.name = ‘red老師’
    // 更改對象里面的 family 還是會有影響
    console.log(red) // { name: ‘red老師’, age: 18 }
    // 不會影響 pink 對象
    console.log(pink) // { name: ‘pink老師’, age: 18 }
    - 如果是簡單數據類型拷貝值,引用數據類型拷貝的是地址 (簡單理解:如果是單層對象,沒問題,如果有多層就有問題)
    
  • 直接賦值和淺拷貝有什么區別?
    • 直接賦值的方法,只要是對象,都會相互影響,因為是直接拷貝對象棧里面的地址
    • 淺拷貝如果是一層對象,不相互影響,如果出現多層對象拷貝還會相互影響
  • 淺拷貝怎么理解?
    • 拷貝對象之后,里面的屬性值是簡單數據類型直接拷貝值
    • 如果屬性值是引用數據類型則拷貝的是地址

1.2 深拷貝

  • 首先淺拷貝和深拷貝只針對引用類型
  • 深拷貝:拷貝的是對象,不是地址
  • 常見方法:
    1. 通過遞歸實現深拷貝
    2. lodash/cloneDeep
    3. 通過JSON.stringify()實現
1.2.1 通過遞歸實現深拷貝
  • 函數遞歸:
    • 如果一個函數在內部可以調用其本身,那么這個函數就是遞歸函數
  • 簡單理解:函數內部自己調用自己, 這個函數就是遞歸函數
  • 遞歸函數的作用和循環效果類似
  • 由于遞歸很容易發生“棧溢出”錯誤(stack overflow),所以必須要加退出條件return
  • 例子:
    let num = 1
    // fn 就是遞歸函數
    function fn() {console.log('我要打印6次')if(num >= 6) {return}num++fn()    // 函數內部調用函數自己
    }
    fn()
    
  • 利用遞歸函數實現 setTimeout 模擬 setInterval效果。
    function getTime() {const time = new Date().toLocalString()console.log(time)setTimeout(getTime, 1000)   // 定時器調用當前函數
    }
    getTime()
    
  • 通過遞歸函數實現深拷貝(簡版)
    const o = {}
    function deepCopy(newObj, oldObj) {for(let k in oldObj) {if(oldObj[k] instanceof Array) {newObj[k] = []deepCopy(newObj[k], oldObj[k])}else if(oldObj[k] instanceof Object) {newObj[k] = {}deepCopy(newObj[k], oldObj[k])}else {newObj[k] = oldObj[k]}}
    }
    
1.2.2 js庫lodash里面cloneDeep內部實現了深拷貝
const obj = {uname: 'pink',age: 18,hobby: ['籃球', '足球'],family: {baby: '小pink'}
}
// 語法:_.cloneDeep(要被克隆的對象)
const o = _.cloneDeep(obj)
console.log(o)
o.family.baby = '老pink'
console.log(obj)
1.2.3 通過JSON.stringify()實現
const obj = {uname: 'pink',age: 18,hobby: ['籃球', '足球'],family: {baby: '小pink'}
}
const o = JSON.parse(JSON.stringify(obj))
console.log(o)
o.family.baby = '老pink'
console.log(obj)

2. 異常處理

2.1 throw 拋異常

  • 異常處理是指預估代碼執行過程中可能發生的錯誤,然后最大程度的避免錯誤的發生導致整個程序無法繼續運行
  • 總結:
    1. throw 拋出異常信息,程序也會終止執行
    2. throw 后面跟的是錯誤提示信息
    3. Error 對象配合 throw 使用,能夠設置更詳細的錯誤信息
  • 例子:
    function counter(x, y) {if(!x || !y) {// throw '參數不能為空!';throw new Error('參數不能為空!')}return x + y
    }
    counter()
    

2.2 try/catch 捕獲異常

  • 我們可以通過try / catch 捕獲錯誤信息(瀏覽器提供的錯誤信息) try 試試 catch 攔住 finally 最后
  • 總結:
    1. try…catch 用于捕獲錯誤信息
    2. 將預估可能發生錯誤的代碼寫在 try 代碼段中
    3. 如果 try 代碼段中出現錯誤后,會執行 catch 代碼段,并截獲到錯誤信息
    4. finally 不管是否有錯誤,都會執行
  • 例子:
    function foo() {try {// 查找 DOM 節點const p = document.querySelectro('.p')p.style.color = 'red'} catch(error) {// try 代碼段中執行有錯誤時,會執行 catch 代碼段// 查看錯誤信息console.log(error.message)// 終止代碼繼續執行return}finally {alert('執行')}console.log('如果出現錯誤,我的語句不會執行')
    }
    foo()
    

2.3 debugger

  • 我們可以通過 try / catch 捕獲錯誤信息(瀏覽器提供的錯誤信息)
  • 例子:
    const arr = [1, 3, 5]
    const newArr = arr.map((item, index) => {debuggerconsole.log(item)       // 當前元素console.log(index)      // 當前元素索引號return item + 10        // 讓當前元素 + 10
    })
    console.log(newArr)         // [11, 13, 15]
    

3. 處理this

  • this 是 JavaScript 最具“魅惑”的知識點,不同的應用場合 this 的取值可能會有意想不到的結果,在此我們對以往學習過的關于【 this 默認的取值】情況進行歸納和總結。

3.1 this指向

3.1.1 普通函數this指向
  • 普通函數的調用方式決定了 this 的值,即【誰調用 this 的值指向誰】
  • 普通函數沒有明確調用者時 this 值為 window,嚴格模式下沒有調用者時 this 的值為 undefined。
  • 例子1:
    // 普通函數
    function sayHi() {console.log(this)
    }
    // 函數表達式
    const sayHello = function() {console.log(this)
    }
    // 函數的調用方式決定了 this 的值
    sayHi()     // window
    windows.sayHi()
    
  • 例子2:
    // 普通對象
    const user = {name: '小明',walk: function() {console.log(this)}
    }
    // 動態為 user 添加方法
    user.sayHi = sayHi
    user.sayHello = sayHello
    // 函數的調用方式決定了 this 的值
    user.sayHi()
    user.sayHello()
    
  • 例子3:
    <script>'use strict'function fn() {console.log(this)   // undefined}fn()
    </script>
    
3.1.2 箭頭函數this指向
  • 箭頭函數中的 this 與普通函數完全不同,也不受調用方式的影響,事實上箭頭函數中并不存在 this !
    1. 箭頭函數會默認幫我們綁定外層 this 的值,所以在箭頭函數中 this 的值和外層的 this 是一樣的
    2. 箭頭函數中的this引用的就是最近作用域中的this
    3. 向外層作用域中,一層一層查找this,直到有this的定義
  • 例子1:
    console.log(this)   // 此處為 window
    // 箭頭函數
    const sayHi = function() {console.log(this)   // 該箭頭函數中的 this 為函數聲明環境中 this 一致
    }
    
  • 例子2:
    // 普通對象
    const user = {name: '小明',// 該箭頭函數中的 this 為函數聲明環境中 this 一致walk: () => {console.log(this)}
    }
    
  • 注意情況1:
    • 在開發中【使用箭頭函數前需要考慮函數中 this 的值】,事件回調函數使用箭頭函數時,this 為全局的 window
    • 因此DOM事件回調函數如果里面需要DOM對象的this,則不推薦使用箭頭函數
    • 例子:
      // DOM 節點
      const btn = document.querySelector('.btn')
      // 箭頭函數,此時 this 指向了 window
      btn.addEventListener('click', () => {console.log(this)
      })
      // 普通函數,此時 this 指向了 DOM 對象
      btn.addEventListener('click', function () {console.log(this)
      })
      
  • 注意情況2:
    • 同樣由于箭頭函數 this 的原因,基于原型的面向對象也不推薦采用箭頭函數
    • 例子:
      function Person() {
      }
      // 原型對象上添加了箭頭函數
      Person.prototype.walk = () => {console.log('人都要走路...')console.log(this);  // window
      }
      const p1 = new Person()
      p1.walk()
      
  • 總結:
    1. 函數內不存在this,沿用上一級的
    2. 不適用
      • 構造函數,原型函數,dom事件函數等等
    3. 適用
      • 需要使用上層this的地方
    4. 使用正確的話,它會在很多地方帶來方便,后面我們會大量使用慢慢體會

3.2 改變this

  • JavaScript 中還允許指定函數中 this 的指向,有 3 個方法可以動態指定普通函數中 this 的指向:
    • call()
    • apply()
    • bind()
3.2.1 call()–了解
  • 使用 call 方法調用函數,同時指定被調用函數中 this 的值
  • 語法:
    fun.call(thisArg, arg1, arg2, ...)
    
    • thisArg:在 fun 函數運行時指定的 this 值
    • arg1,arg2:傳遞的其他參數
    • 返回值就是函數的返回值,因為它就是調用函數
  • 例子1:
    const obj = {name: 'pink'
    }
    function fn() {console.log(this)   // 指向 obj {name: 'pink'}
    }
    fn.call(obj)
    
  • 例子2:
    const obj = {name: 'pink'
    }
    function fn(x, y) {console.log(this)   // 指向 obj {name: 'pink'}console.log(x + y)  // 傳遞過來的參數相加
    }
    fn.call(obj, 1, 2)
    
3.2.2 apply()-理解
  • 使用 apply 方法調用函數,同時指定被調用函數中 this 的值
  • 語法:
    fun.apply(thisArg, [argsArray])
    
    • thisArg:在fun函數運行時指定的 this 值
    • argsArray:傳遞的值,必須包含在數組里面
    • 返回值就是函數的返回值,因為它就是調用函數
    • 因此 apply 主要跟數組有關系,比如使用 Math.max() 求數組的最大值
  • 例子:
    // 求和函數
    function counter(x, y) {return x + y
    }
    // 調用 counter 函數,并傳入參數
    let result = counter.apply(null, [5, 10])
    console.log(result)
    
  • 求數組最大值2個方法:
    // 求數組最大值
    const arr = [3, 5, 2, 9]
    console.log(Math.max.apply(null, arr))  // 9,利用apply
    console.log(Math.max(...arr))           // 9,利用展開運算符
    
3.2.3 bind()-重點
  • bind() 方法不會調用函數。但是能改變函數內部this 指向
  • 語法:
    fun.bind(thisArg, arg1, arg2, ...)
    
    • thisArg:在 fun 函數運行時指定的 this 值
    • arg1,arg2:傳遞的其他參數
    • 返回由指定的 this 值和初始化參數改造的 原函數拷貝 (新函數)
    • 因此當我們只是想改變 this 指向,并且不想調用這個函數的時候,可以使用 bind,比如改變定時器內部的this指向.
  • 例子:
    // 普通函數
    function sayHi() {console.log(this)
    }
    let user = {name: '小明',age: 18
    }
    // 調用 bind 指定 this 的值
    let sayHello = sayHi.bind(user);
    // 調用使用 bind 創建的新函數
    sayHello()
    
3.2.4 call apply bind 總結
  • 相同點:
    • 都可以改變函數內部的this指向.
  • 區別點:
    • call 和 apply 會調用函數, 并且改變函數內部this指向.
    • call 和 apply 傳遞的參數不一樣, call 傳遞參數 aru1, aru2…形式,apply 必須數組形式[arg]
    • bind 不會調用函數, 可以改變函數內部this指向.
  • 主要應用場景:
    • call 調用函數并且可以傳遞參數
    • apply 經常跟數組有關系. 比如借助于數學對象實現數組最大值最小值
    • bind 不調用函數,但是還想改變this指向. 比如改變定時器內部的this指向.

4. 性能優化

4.1 防抖

  • 所謂防抖(debounce),就是指觸發事件后在 n 秒內函數只能執行一次,如果在 n 秒內又觸發了事件,則會重新計算函數執行時間
  • 現實例子:北京買房政策,需要連續5年的社保,如果中間有一年斷了社保,則需要從新開始計算
  • 開發使用場景:搜索框防抖
    • 假設輸入就可以發送請求,但是不能每次輸入都去發送請求,輸入比較快發送請求會比較多
    • 我們設定一個時間,假如300ms, 當輸入第一個字符時候,300ms后發送請求,但是在200ms的時候又輸入了一個字符,則需要再等300ms 后發送請求
  • 利用防抖來處理-鼠標滑過盒子顯示文字
    const box = document.querySelector('.box')
    let i = 1
    function mouseMove() {box.innerHTML = i++
    }
    function debounce(fn, t = 500) {let timeIdreturn function () {// 如果有定時器,先清除if(timeId)clearTimeout(timeId)// 開啟定時器timeId = setTimeout(function() {fn()}, t)}
    }
    box.addEventListener('mousemove', debounce(mouseMove, 500))
    
    • 核心思路:利用定時器實現,當鼠標滑過,判斷有沒有定時器,還有就清除,以最后一次滑動為準開啟定時器

4.2 節流

  • 所謂節流(throttle),就是指連續觸發事件但是在 n 秒中只執行一次函數

  • 現實例子:只有等到了上一個人做完核酸,整個動作完成了,第二個人才能排隊跟上

  • 開發使用場景:小米輪播圖點擊效果、鼠標移動、頁面尺寸縮放resize、滾動條滾動 就可以加節流

    • 假如一張輪播圖完成切換需要300ms,不加節流效果,快速點擊,則嗖嗖嗖的切換
    • 加上節流效果,不管快速點擊多少次,300ms時間內,只能切換一張圖片。
  • 利用節流來處理-鼠標滑過盒子顯示文字:

    const box = document.querySelector('.box')
    let i = 1
    function mouseMove() {box.innerHTML = i++// 如果存在開銷較大操作,大量數據處理,大量dom操作,可能會卡
    }
    function throttle(fn, t = 500) {let startTime = 0return function () {let now = Date.now()if(now - startTime >= t) {fn()startTime = now}}
    }
    box.addEventListener('mousemove', throttle(mouseMove, 500))
    
    • 利用節流的方式,鼠標經過,500ms,數字才顯示
  • 節流和防抖的區別是?

    • 節流: 就是指連續觸發事件但是在 n 秒中只執行一次函數,比如可以利用節流實現 1s 之內只能觸發一次鼠標移動事件
    • 防抖:如果在 n 秒內又觸發了事件,則會重新計算函數執行時間
  • 節流和防抖的使用場景是?

    • 節流: 鼠標移動,頁面尺寸發生變化,滾動條滾動等開銷比較大的情況下
    • 防抖: 搜索框輸入,設定每次輸入完畢n秒后發送請求,如果期間還有輸入,則從新計算時間

4.3 Lodash 庫實現節流和防抖

  • 節流

    const box = document.querySelector('.box')
    let i = 1
    function mouseMove() {box.innerHTML = i++// 如果存在開銷較大操作,大量數據處理,大量dom操作,可能會卡
    }
    box.addEventListener('mousemove', _.throttle(mouseMove, 1000))
    
  • 防抖

    const box = document.querySelector('.box')
    let i = 1
    function mouseMove() {box.innerHTML = i++// 如果存在開銷較大操作,大量數據處理,大量dom操作,可能會卡
    }
    box.addEventListener('mousemove', _.debounce(mouseMove, 1000))
    

5. 節流綜合案例

頁面打開,可以記錄上一次的視頻播放位置

  • 思路:
    1. 在ontimeupdate事件觸發的時候,每隔1秒鐘,就記錄當前時間到本地存儲
    2. 下次打開頁面, onloadeddata 事件觸發,就可以從本地存儲取出時間,讓視頻從取出的時間播放,如果沒有就默認為0s
    3. 獲得當前時間 video.currentTime
  • 代碼:
    const video = document.querySelector('video')
    video.ontimeupdate = _.throttle(() => {localStorage.setItem('currentTime', video.currentTime)
    }, 1000)
    video.onloadeeddata = () => {video.currentTime = local.getItem('currentTime') || 0
    }
    

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/160426.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/160426.shtml
英文地址,請注明出處:http://en.pswp.cn/news/160426.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

微信訂房功能怎么做_公眾號里怎么實現在線訂房系統

微信公眾號在線訂房系統&#xff1a;一鍵解決您的住宿問題 在當今數字化時代&#xff0c;微信公眾號已經成為人們生活中不可或缺的一部分。它提供了各種各樣的功能和服務&#xff0c;讓我們的生活變得更加便捷和高效。而如今&#xff0c;微信公眾號也實現了在線訂房功能&#…

什么是應急演練腳本?其設計原則是什么?

應急演練腳本是一種系統性、有計劃的模擬性文件&#xff0c;旨在測試和評估組織在緊急情況下的應對能力。這種腳本提供了一系列步驟和場景&#xff0c;以確保團隊能夠高效、協調地應對各種緊急事件。以下將詳細探討應急演練腳本的定義、設計原則以及實施過程。 一、應急演練腳本…

常見面試題-Redis持久化策略

談談Redis 的持久化策略&#xff1f; 參考文章&#xff1a; Redis 持久化機制演進與百度智能云的實踐 Redis的確是將數據存儲在內存的&#xff0c;但是也會有相關的持久化機制將內存持久化備份到磁盤&#xff0c;以便于重啟時數據能夠重新恢復到內存中&#xff0c;避免數據丟…

【Python 千題 —— 基礎篇】奇數列表

題目描述 題目描述 創建奇數列表。使用 for 循環創建一個包含 20 以內奇數的列表。 輸入描述 無輸入。 輸出描述 輸出創建的列表。 示例 示例 ① 輸出&#xff1a; 創建的奇數列表為: [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]代碼講解 下面是本題的代碼&#xff1a; #…

9. 回文數 --力扣 --JAVA

題目 給你一個整數 x &#xff0c;如果 x 是一個回文整數&#xff0c;返回 true &#xff1b;否則&#xff0c;返回 false 。 回文數是指正序&#xff08;從左向右&#xff09;和倒序&#xff08;從右向左&#xff09;讀都是一樣的整數。 例如&#xff0c;121 是回文&#xff0…

二、爬蟲-爬取肯德基在北京的店鋪地址

1、算法框架解釋 針對這個案例&#xff0c;現在對爬蟲的基礎使用做總結如下&#xff1a; 1、算法框架 (1)設定傳入參數 ~url: 當前整個頁面的url:當前頁面的網址 當前頁面某個局部的url:打開檢查 ~data:需要爬取數據的關鍵字&…

DB2中實現數據字段的拼接(LISTAGG() 與 xml2clob、xmlagg)

DB2中實現數據字段拼接&#xff08;LISTAGG 與 xml2clob、xmlagg&#xff09; 1. 使用函數LISTAGG()1.1 同oracle實現方式1.2 DB2中使用LISTAGG()1.2.1 關于DB2版本1.2.2 數據準備1.2.3 代碼實現 2 解決DB2中關于 LISTAGG() 超長問題2.1 使用xmlagg xmlelement2.2 將xml標簽去…

數據結構與算法編程題11

已知兩個鏈表A和B分別表示兩個集合&#xff0c;其元素遞增排列。 請設計算法求出A與B的交集&#xff0c;并存放于A鏈表中。 a: 1, 2, 2, 4, 5, 7, 8, 9, 10 b: 1, 2, 3, 6, 7, 8 #include <iostream> using namespace std;typedef int Elemtype; #define ERROR 0; #defin…

【iOS】實現評論區展開效果

文章目錄 前言實現行高自適應實現評論展開效果解決cell中的buttom的復用問題 前言 在知乎日報的評論區中&#xff0c;用到了Masonry行高自適應來實現評論的展開&#xff0c;這里設計許多控件的約束問題&#xff0c;當時困擾了筆者許久&#xff0c;特此撰寫博客記錄 實現行高自…

如何構建更簡潔的前端架構?

目錄 為什么需要前端架構&#xff1f; 那么&#xff0c;前端架構是什么樣的呢&#xff1f; 使用了哪些層&#xff1f; 那么&#xff0c;這種架構會出什么問題呢&#xff1f; 我們應該如何避免這些錯誤&#xff1f; 哪些原則應適用于組件&#xff1f; Anti-Patterns 反模…

小程序存在優惠卷遍歷,但是歪了

進入小程序&#xff0c;因為是一個小商城&#xff0c;所以照例先查看收貨地址是否存在越權&#xff0c;以及能否未授權訪問&#xff0c;但是發現不存在這些問題&#xff0c;所以去查看優惠卷 進入領券中心&#xff0c;點擊領取優惠券時抓包 發現數據包&#xff0c;存在敏感參數…

數據庫的級聯刪除

級聯刪除是指在數據庫中刪除一個對象時&#xff0c;與該對象有關的其他對象也被自動刪除。在 Django 中&#xff0c;級聯刪除通常通過在模型中定義外鍵時使用 on_delete 參數來實現。以下是一些常見的 on_delete 選項&#xff1a; 1.models.CASCADE: 當關聯的對象被刪除時&…

CentOS 7 使用Fmt庫

安裝 fmt Git下載地址&#xff1a;https://github.com/fmtlib/fmt 步驟1&#xff1a;首先&#xff0c;你需要下載fmt的源代碼。你可以從https://github.com/fmtlib/fmt或者源代碼官方網站下載。并上傳至/usr/local/source_code/ ? 步驟2&#xff1a;下載完成后&#xff…

【Docker】Docker安裝Nginx配置靜態資源

1.下載鏡像 2.創建nginx配置文件 3.創建nginx容器運行 4.配置nginx靜態資源 1.下載鏡像 Dockerhub官網&#xff1a;Docker docker pull nginx docker pull nginx下載最新版本 默認latest 下載指定版本docker pull nginx:xxx 2.創建nginx配置文件 啟動容器之前要創建nginx…

怎么使用sentinel,以及所有的知識點

Sentinel是一個開源的流量控制和實時監控系統&#xff0c;主要用于保護企業級應用程序免受不良的請求。下面是使用Sentinel需要了解的知識點&#xff1a; 1. 什么是流量控制&#xff1f; 流量控制指的是限制應用程序的請求流量&#xff0c;防止過多的請求超出系統的承受范圍。…

基于單片機停車場環境監測系統仿真設計

**單片機設計介紹&#xff0c; 基于單片機停車場環境監測系統仿真設計 文章目錄 一 概要二、功能設計設計思路 三、 軟件設計原理圖 五、 程序六、 文章目錄 一 概要 基于單片機的停車場環境監測系統是一種利用單片機技術實現環境監測和數據處理的系統。它可以感知停車場的溫濕…

Python (十一) 迭代器與生成器

迭代器 迭代器是訪問集合元素的一種方式&#xff0c;可以記住遍歷的位置的對象 迭代器有兩個基本的方法&#xff1a;iter() 和 next() 字符串&#xff0c;列表或元組對象都可用于創建迭代器 字符串迭代 str1 Python str_iter iter(str1) print(next(str_iter)) print(next(st…

zip4j壓縮使用總結

一、引入依賴 <dependency><groupId>net.lingala.zip4j</groupId><artifactId>zip4j</artifactId><version>1.3.1</version></dependency>二、使用添加文件&#xff08;addFiles&#xff09;的方式生成壓縮包 /*** Author wan…

藍橋杯物聯網_STM32L071_2_繼電器控制

CubeMX配置&#xff1a; Function.c及Function.h&#xff1a; #include "Function.h" #include "gpio.h" void Function_LD5_ON(void){HAL_GPIO_WritePin(LD5_GPIO_Port, LD5_Pin, GPIO_PIN_RESET); }void Function_LD5_OFF(void){HAL_GPIO_WritePin(LD5_…

HarmonyOS應用開發者認證題目滿分指南

為了幫助大家快速的上手HarmonyOS應用程序開發&#xff0c;官方制作了一些免費的課程&#xff1a;HarmonyOS第一課。每個課程后面都有一些練習題&#xff0c;下面就是這些題目的滿分答案。 【習題】運行Hello World工程 判斷題 1.DevEco Studio是開發HarmonyOS應用的一站式集…