欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript函數(shù)增強以及額外知識

 更新時間:2022年06月07日 15:02:22   作者:用戶9553267381418  
函數(shù)就是封裝了一段可以被重復執(zhí)行調(diào)用的代碼塊,下面這篇文章主要給大家介紹了關(guān)于JavaScript函數(shù)增強以及額外知識的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下

一、函數(shù)增強

1.1 函數(shù)對象的屬性

JavaScript中函數(shù)也是一個對象,那么對象中就可以有屬性和方法。

  • name:一個函數(shù)的名字我們可以通過name來訪問

  • length:屬性length用于返回函數(shù)參數(shù)的個數(shù)

    • 注意:rest參數(shù)是不參與參數(shù)的個數(shù)的
var bar = function(m, n, ...others) {
}

console.log(bar.length) // 2

1.2 arguments

  • arguments 是一個對應(yīng)于傳遞給函數(shù)的參數(shù)的類數(shù)組(array-like)對象

  • 注意:array-like意味著它不是一個數(shù)組類型,而是一個對象類型

    • 擁有數(shù)組的一些特性,比如說length,比如可以通過index索引來訪問

    • 沒有數(shù)組的一些方法,比如filter、map等

  • arguments轉(zhuǎn)數(shù)組

    遍歷arguments,添加到一個新數(shù)組中

    調(diào)用數(shù)組slice函數(shù)的apply方法

    [].slice.apply(arguments)
    Array.prototype.slice.apply(arguments)
    ES6中的兩個方法
    • Array.from
    • […arguments]
  • 特別注意:箭頭函數(shù)不綁定arguments
    • 在箭頭函數(shù)中使用arguments會去上層作用域查找
    function foo() {
      var bar = () => {
        console.log(arguments)
      }
      bar()
    }
    
    foo(111, 222) // Arguments(2) [111, 222, callee: ?, Symbol(Symbol.iterator): ?]

1.3 剩余rest參數(shù)

  • ES6中引用了rest parameter,可以將不定數(shù)量的參數(shù)放入到一個數(shù)組中:

    • 如果最后一個參數(shù)是 ... 為前綴的,那么它會將剩余的參數(shù)放到該參數(shù)中,并且作為一個數(shù)組
    function foo(num1, num2, ...otherNums) {
      // otherNums數(shù)組
      console.log(otherNums) // [111, 222, 333]
    }
    
    foo(20, 30, 111, 222, 333)
  • 那么剩余參數(shù)和arguments有什么區(qū)別呢?

    • 剩余參數(shù)只包含那些沒有對應(yīng)形參的實參,而 arguments 對象包含了傳給函數(shù)的所有實參

    • arguments對象不是一個真正的數(shù)組,而rest參數(shù)是一個真正的數(shù)組,可以進行數(shù)組的所有操作

    • arguments是早期的ECMAScript中為了方便去獲取所有的參數(shù)提供的一個數(shù)據(jù)結(jié)構(gòu),而rest參數(shù)是ES6中提供并且希望以此來替代arguments的

  • 注意:剩余參數(shù)必須放到最后一個位置,否則會報錯

1.4 純函數(shù)的使用

  • 純函數(shù)的概念:
    • 確定的輸入一定產(chǎn)生確定的輸出
    • 執(zhí)行過程中不能副作用
      • 副作用是指在執(zhí)行一個函數(shù)時,除了返回函數(shù)值之外,還對調(diào)用函數(shù)產(chǎn)生了附加的影響,比如修改了全局變量,修改參數(shù)或者改變外部的存儲
  • 實際開發(fā)中應(yīng)用:
    • React中就要求無論是函數(shù)還是class聲明一個組件,這個組件都必須像純函數(shù)一樣,保護它們的props不被修改
  • 沒有必要每一個函數(shù)都是純函數(shù)
  • 數(shù)組的方法中slice就是一個純函數(shù),不會修改數(shù)組本身,而splice函數(shù)不是一個純函數(shù):

    • slice:slice截取數(shù)組時不會對原數(shù)組進行任何操作,而是生成一個新的數(shù)組

    • splice:splice截取數(shù)組, 會返回一個新的數(shù)組, 也會對原數(shù)組進行修改

1.5 柯里化的過程

  • 什么是柯里化

    • 只傳遞給函數(shù)一部分參數(shù)來調(diào)用它,讓它返回一個函數(shù)去處理剩余的參數(shù)
  • 兩個案例:

    • logInfo

      // 1.沒有柯里化的時候做法
      function logInfo(date, type, message) {
        console.log(`時間:${date} 類型:${type} 內(nèi)容:${message}`)
      }
      
      // // 打印日志
      // logInfo("2022-06-01", "DEBUG", "修復界面搜索按鈕點擊的bug")
      
      // // 又修復了一個bug
      // logInfo("2022-06-01", "DEBUG", "修復了從服務(wù)器請求數(shù)據(jù)后展示的bug")
      // logInfo("2022-06-01", "DEBUG", "修復了從服務(wù)器請求數(shù)據(jù)后展示的bug")
      // logInfo("2022-06-01", "DEBUG", "修復了從服務(wù)器請求數(shù)據(jù)后展示的bug")
      
      // logInfo("2022-06-01", "FEATURE", "增加了商品的過濾功能")
      
      
      // 2.對函數(shù)進行柯里化: 柯里化函數(shù)的做法
      // var logInfo = date => type => message => {
      //   console.log(`時間:${date} 類型:${type} 內(nèi)容:${message}`)
      // }
      function logInfo(date) {
        return function(type) {
          return function(message) {
            console.log(`時間:${date} 類型:${type} 內(nèi)容:${message}`)
          }
        }
      }
      
      var logToday = logInfo("2022-06-01")
      var logTodayDebug = logToday("DEBUG")
      var logTodayFeature = logToday("FEATURE")
      
      // 打印debug日志
      logTodayDebug("修復了從服務(wù)器請求數(shù)據(jù)后展示的bug")
      logTodayDebug("修復界面搜索按鈕點擊的bug")
      logTodayDebug("修復界面搜索按鈕點擊的bug")
      logTodayDebug("修復界面搜索按鈕點擊的bug")
      logTodayDebug("修復界面搜索按鈕點擊的bug")
      
      logTodayFeature("新建過濾功能")
      logTodayFeature("新建搜索功能")
    • makeAdder

      function makeAdder(count) {
        function add(num) {
          return count + num
        }
        return add
      }
      
      // 1.數(shù)字和5相加
      var adder5 = makeAdder(5)
      adder5(10)
      adder5(15)
      adder5(18)
      
      // 2.數(shù)組和10相加
      var adder10 = makeAdder(10)
      adder10(10)
      adder10(16)
      adder10(19)
  • 柯里化優(yōu)勢:

    • 函數(shù)的職責單一
    • 函數(shù)的參數(shù)復用
  • 自動柯里化的函數(shù)封裝

    // 將一個普通函數(shù)轉(zhuǎn)化成柯里化函數(shù)
    function curried(fn) {
      function curryFn(...args) {
        // 傳入的參數(shù)大于等于fn的需要的參數(shù)個數(shù),直接執(zhí)行fn函數(shù)
        // 否則返回新的函數(shù)繼續(xù)接收參數(shù)
        if(args.length >= fn.length) {
          return fn.apply(this, args)
        } else {
          // 返回新的函數(shù)并接收參數(shù)
          return function(...newArgs) {
            // 遞歸調(diào)用currFn,此處的參數(shù)為上一次傳入的參數(shù)和之后傳入的參數(shù)
            return curryFn.apply(this, args.concat(newArgs))
          }
        }
      }
      return curryFn
    }
  • 注意:函數(shù)柯里化性能并不高(使用到閉包,可能會導致內(nèi)存泄露)

1.6 組合函數(shù)的使用

  • 組合函數(shù)
    • 多個函數(shù)組合在一起, 依次調(diào)用
  • 封裝組合函數(shù)

    // 傳入多個函數(shù),自動的將多個函數(shù)組合在一起依次調(diào)用
    function composeFn(...fns) {
      var length = fns.length
      // 邊界判斷
      if (length <= 0) return
      for (var fn of fns) {
        if (typeof fn !== "function") {
          throw new Error("Expected a function")
        }
      }
    
      return function (...args) {
        // 第一個函數(shù)可能傳入多個參數(shù)
        var result = fns[0].apply(this, args)
        // 之后的函數(shù)依次調(diào)用
        for (var i = 1; i < length; i++) {
          result = fns[i].apply(this, [result])
        }
    
        return result
      }
    }

二、額外知識

2.1 with

  • with語句 擴展一個語句的作用域鏈。

    var obj = {
      message: "Hello World"
    }
    
    with (obj) {
      console.log(message) // Hello World
    }
  • 不建議使用with語句,因為它可能是混淆錯誤和兼容性問題的根源

2.2 eval

  • 內(nèi)建函數(shù) eval 允許執(zhí)行一個代碼字符串

    • eval是一個特殊的函數(shù),它可以將傳入的字符串當做JavaScript代碼來運行

    • eval會將最后一句執(zhí)行語句的結(jié)果,作為返回值

    var message = "Hello World"
    var codeString = `var name = "kobe"; console.log(name); console.log(message); "abc";`
    var result = eval(codeString)
    console.log(result) // abc
  • 不建議在開發(fā)中使用eval:

    • eval代碼的可讀性非常的差(代碼的可讀性是高質(zhì)量代碼的重要原則)

    • eval是一個字符串,那么有可能在執(zhí)行的過程中被刻意篡改,那么可能會造成被攻擊的風險

    • eval的執(zhí)行必須經(jīng)過JavaScript解釋器,不能被JavaScript引擎優(yōu)化

2.3 嚴格模式

  • 什么是嚴格模式?
    • 嚴格模式是一種具有限制性的JavaScript模式,從而使代碼隱式的脫離了“懶散(sloppy)模式”

    • 支持嚴格模式的瀏覽器在檢測到代碼中有嚴格模式時,會以更加嚴格的方式對代碼進行檢測和執(zhí)行

  • 嚴格模式對正常的JavaScript語義進行了一些限制:

    • 嚴格模式通過拋出錯誤來消除一些原有的 靜默(silent)錯誤

    • 嚴格模式讓JS引擎在執(zhí)行代碼時可以進行更多的優(yōu)化(不需要對一些特殊的語法進行處理)

    • 嚴格模式禁用了在ECMAScript未來版本中可能會定義的一些語法

  • 如何開啟嚴格模式:
    • 嚴格模式通過在文件或者函數(shù)開頭使用 use strict 來開啟
    // 給整個script開啟嚴格模式
    "use strict"
    
    // 給一個函數(shù)開啟嚴格模式
    function foo() {
      "use strict"
    }
  • 嚴格模式的限制:

    無法意外的創(chuàng)建全局變量

    嚴格模式會使引起靜默失敗(silently fail,注:不報錯也沒有任何效果)的賦值操作拋出異常

    嚴格模式下試圖刪除不可刪除的屬性

    嚴格模式不允許函數(shù)參數(shù)有相同的名稱

    不允許0的八進制語法

    在嚴格模式下,不允許使用with

    在嚴格模式下,eval不再為上層引用變量

    嚴格模式下,this綁定不會默認轉(zhuǎn)成對象

    "use strict"
    // 1.不會意外創(chuàng)建全局變量
    // function foo() {
    //   message = "Hello World"
    // }
    
    // foo()
    // console.log(message) // 報錯
    
    // 2.發(fā)現(xiàn)靜默錯誤
    var obj = {
      name: "kobe"
    }
    
    Object.defineProperty(obj, "name", {
      writable: false,
      configurable: false
    })
    
    // obj.name = "curry"
    console.log(obj.name)
    
    // delete obj.name
    console.log(obj)
    
    // 3.參數(shù)名稱不能相同
    // function foo(num, num) {
    
    // }
    
    // 4.不能以0開頭
    // console.log(0o123) // 0o是ES6新語法可以寫
    
    // 5.eval函數(shù)不能為上層創(chuàng)建變量
    // eval(`var message = "Hello World"`)
    // console.log(message)
    
    // 6.嚴格模式下, this是不會轉(zhuǎn)成對象類型的
    function foo() {
      console.log(this)
    }
    foo.apply("abc")
    foo.apply(123)
    foo.apply(undefined)
    foo.apply(null)
    
    // 獨立函數(shù)執(zhí)行默認模式下, 綁定window對象
    // 在嚴格模式下, 不綁定全局對象而是undefined
    foo()

總結(jié)

到此這篇關(guān)于JavaScript函數(shù)增強及額外知識的文章就介紹到這了,更多相關(guān)js函數(shù)增強知識內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論