39.[前端开发-JavaScript高级]Day04-函数增强-argument-额外知识-对象增强

发布于:2025-04-14 ⋅ 阅读:(18) ⋅ 点赞:(0)

JavaScript函数的增强知识

1 函数属性和arguments

函数对象的属性

认识arguments

arguments转Array

箭头函数不绑定arguments

函数的剩余(rest)参数

2 纯函数的理解和应用

理解JavaScript纯函数

副作用概念的理解

纯函数的案例

判断下面函数是否是纯函数?

纯函数的作用和优势

3 柯里化的理解和应用

柯里化概念的理解

柯里化的代码转换

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  
  <script>

    // 普通的函数
    function foo1(x, y, z) {
      console.log(x + y + z)
    }

    // foo1(10, 20, 30)
    // foo1(20, 33, 55)


    // 因为foo不是一个柯里化的函数, 所以目前是不能这样调用
    // 柯里化函数
    function foo2(x) {
      return function(y) {
        return function(z) {
          console.log(x + y + z)
        }
      }
    }

    foo2(10)(20)(30)
    foo2(20)(33)(55)


    // 另外一种写法: 箭头函数的写法
    // function foo3(x) {
    //   return y => {
    //     return z => {
    //       console.log(x + y + z)
    //     }
    //   }
    // }

    var foo3 = x => y => z => {
      console.log(x + y + z)
    }

    foo3(10)(20)(30)


  </script>

</body>
</html>

柯里化优势一 - 函数的职责单一

柯里化优势二 - 函数的参数服用

柯里化案例练习

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  
  <script>

    // 案例一: 打印一些日志
    // 信息一: 日志的时间
    // 信息二: 日志的类型: info/debug/feature
    // 信息三: 具体的信息

    // 1.没有柯里化的时候做法
    function logInfo(date, type, message) {
      console.log(`时间:${date} 类型:${type} 内容:${message}`)
    }

    // // 打印日志
    // logInfo("2022-06-01", "DEBUG", "修复界面搜索按钮点击的bug")

    // // 又修复了一个bug
    // logInfo("2022-06-01", "DEBUG", "修复了从服务器请求数据后展示的bug")
    // logInfo("2022-06-01", "DEBUG", "修复了从服务器请求数据后展示的bug")
    // logInfo("2022-06-01", "DEBUG", "修复了从服务器请求数据后展示的bug")
    
    // logInfo("2022-06-01", "FEATURE", "增加了商品的过滤功能")


    // 2.对函数进行柯里化: 柯里化函数的做法
    // var logInfo = date => type => message => {
    //   console.log(`时间:${date} 类型:${type} 内容:${message}`)
    // }
    function logInfo(date) {
      return function(type) {
        return function(message) {
          console.log(`时间:${date} 类型:${type} 内容:${message}`)
        }
      }
    }

    var logToday = logInfo("2022-06-01")
    var logTodayDebug = logToday("DEBUG")
    var logTodayFeature = logToday("FEATURE")

    // 打印debug日志
    logTodayDebug("修复了从服务器请求数据后展示的bug")
    logTodayDebug("修复界面搜索按钮点击的bug")
    logTodayDebug("修复界面搜索按钮点击的bug")
    logTodayDebug("修复界面搜索按钮点击的bug")
    logTodayDebug("修复界面搜索按钮点击的bug")

    logTodayFeature("新建过滤功能")
    logTodayFeature("新建搜索功能")

  </script>

</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  
  <script>

    function sum(num1, num2) {
      return num1 + num2
    }

    sum(5, 10)
    sum(5, 15)
    sum(5, 18)

    // makeAdder函数就是对sum的柯里化
    function makeAdder(count) {
      function add(num) {
        return count + num
      }
      return add
    }

    // 1.数字和5相加
    var adder5 = makeAdder(5)
    adder5(10)
    adder5(15)
    adder5(18)

    // 2.数组和10相加
    var adder10 = makeAdder(10)
    adder10(10)
    adder10(16)
    adder10(19)

    // adder5 = null
    // adder10 = null

  </script>

</body>
</html>

柯里化高级 - 自动柯里化函数

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  
  <script>

    function foo(x, y, z) {
      console.log(x + y + z)
    }

    function sum(num1, num2) {
      return num1 + num2
    }

    function logInfo(date, type, message) {
      console.log(`时间:${date} 类型:${type} 内容:${message}`)
    }

    // 手动转化

    // 封装函数: 自动转化柯里化过程(有一点难度)
    function hyCurrying(fn) {
      function curryFn(...args) {
        // 两类操作:
        // 第一类操作: 继续返回一个新的函数, 继续接受参数
        // 第二类操作: 直接执行fn的函数
        if (args.length >= fn.length) { // 执行第二类
          // return fn(...args)
          return fn.apply(this, args)
        } else { // 执行第一类
          return function(...newArgs) {
            // return curryFn(...args.concat(newArgs))
            return curryFn.apply(this, args.concat(newArgs))
          }
        }
      }

      return curryFn
    }

    // 对其他的函数进行柯里化
    var fooCurry = hyCurrying(foo)
    fooCurry(10)(20)(30)
    fooCurry(55, 12, 56)

    var sumCurry = hyCurrying(sum)
    var sum5 = sumCurry(5)
    console.log(sum5(10))
    console.log(sum5(15))
    console.log(sum5(18))

    var logInfoCurry = hyCurrying(logInfo)
    logInfoCurry("2022-06-01")("DEBUG")("我发现一个bug, 哈哈哈哈")


    // 举个栗子
    // var names = ["abc", "cba", "nba"]
    // // spread
    // console.log(...names)

  </script>

</body>
</html>

4 组合函数理解和应用

组合函数概念的理解

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  
  <script>

    var num = 100

    // 第一步对数字*2
    function double(num) {
      return num * 2
    }

    // 第二步对数字**2
    function pow(num) {
      return num ** 2
    }

    console.log(pow(double(num)))
    console.log(pow(double(55)))
    console.log(pow(double(22)))

    // 将上面的两个函数组合在一起, 生成一个新的函数
    function composeFn(num) {
      return pow(double(num))
    }

    console.log(composeFn(100))
    console.log(composeFn(55))
    console.log(composeFn(22))

  </script>

</body>
</html>

实现组合函数

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  
  <script>
    // 第一步对数字*2
    function double(num) {
      return num * 2
    }

    // 第二步对数字**2
    function pow(num) {
      return num ** 2
    }

    // 封装的函数: 你传入多个函数, 我自动的将多个函数组合在一起挨个调用
    function composeFn(...fns) {
      // 1.边界判断(edge case)
      var length = fns.length
      if (length <= 0) return
      for (var i = 0; i < length; i++) {
        var fn = fns[i]
        if (typeof fn !== "function") {
          throw new Error(`index position ${i} must be function`)
        }
      }

      // 2.返回的新函数
      return function(...args) {
        var result = fns[0].apply(this, args)
        for (var i = 1; i < length; i++) {
          var fn = fns[i]
          result = fn.apply(this, [result])
        }
        return result
      }
    }

    var newFn = composeFn(double, pow, console.log)
    newFn(100)
    newFn(55)
    newFn(22)
    // console.log(newFn(100))
    // console.log(newFn(55))
    // console.log(newFn(22))

  </script>

</body>
</html>

5 with、eval的使用

with语句的使用

eval函数

6 严格模式的使用

认识严格模式

开启严格模式

严格模式限制

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  
  <script>
    "use strict"
    // 1.不会意外创建全局变量
    // function foo() {
    //   message = "Hello World"
    // }

    // foo()
    // console.log(message)

    // 2.发现静默错误
    var obj = {
      name: "why"
    }

    Object.defineProperty(obj, "name", {
      writable: false,
      configurable: false
    })

    // obj.name = "kobe"
    console.log(obj.name)

    // delete obj.name
    console.log(obj)

    // 3.参数名称不能相同
    // function foo(num, num) {

    // }

    // 4.不能以0开头
    // console.log(0o123)

    // 5.eval函数不能为上层创建变量
    // eval(`var message = "Hello World"`)
    // console.log(message)

    // 6.严格模式下, this是不会转成对象类型的
    function foo() {
      console.log(this)
    }
    foo.apply("abc")
    foo.apply(123)
    foo.apply(undefined)
    foo.apply(null)
    
    // 独立函数执行默认模式下, 绑定window对象
    // 在严格模式下, 不绑定全局对象而是undefined
    foo()

  </script>

</body>
</html>

手写apply、call、bind函数实现(原型后)

JavaScript对象的增强知识

1 Object.defineProperty

对属性操作的控制

2 Object.defineProperties

Object.defineProperty

3 数据属性描述符

属性描述符分类

数据属性描述符

数据属性描述符测试代码

4 存取属性描述符

存取属性描述符

存储属性描述符测试代码

同时定义多个属性

5 对象的其他方法补充

对象方法补充


网站公告

今日签到

点亮在社区的每一天
去签到