当前位置: 首页 > news >正文

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

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// 第一步对数字*2function double(num) {return num * 2}// 第二步对数字**2function 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>// 第一步对数字*2function double(num) {return num * 2}// 第二步对数字**2function pow(num) {return num ** 2}// 封装的函数: 你传入多个函数, 我自动的将多个函数组合在一起挨个调用function composeFn(...fns) {// 1.边界判断(edge case)var length = fns.lengthif (length <= 0) returnfor (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.nameconsole.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对象// 在严格模式下, 不绑定全局对象而是undefinedfoo()</script></body>
</html>

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

JavaScript对象的增强知识

1 Object.defineProperty

对属性操作的控制

2 Object.defineProperties

Object.defineProperty

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>var obj = {name: "why", // configurable: trueage: 18}Object.defineProperty(obj, "name", {configurable: false, // 告诉js引擎, obj对象的name属性不可以被删除enumerable: false, // 告诉js引擎, obj对象的name属性不可枚举(for in/Object.keys)writable: false, // 告诉js引擎, obj对象的name属性不写入(只读属性 readonly)value: "coderwhy" // 告诉js引擎, 返回这个value})delete obj.nameconsole.log(obj)// 通过Object.defineProperty添加一个新的属性Object.defineProperty(obj, "address", {})delete obj.addressconsole.log(obj)console.log(Object.keys(obj))obj.name = "kobe"console.log(obj.name)</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>// vue2响应式原理var obj = {name: "why"}// 对obj对象中的name添加描述符(存取属性描述符)var _name = ""Object.defineProperty(obj, "name", {configurable: true,enumerable: false,set: function(value) {console.log("set方法被调用了", value)_name = value},get: function() {console.log("get方法被调用了")return _name}})obj.name = "kobe"obj.name = "jame"obj.name = "curry"obj.name = "coderwhy"// 获取值console.log(obj.name)</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>var obj = {name: "why",age: 18,height: 1.88}// Object.defineProperty(obj, "name", {})// Object.defineProperty(obj, "age", {})// Object.defineProperty(obj, "height", {})// 新增的方法Object.defineProperties(obj, {name: {configurable: true,enumerable: true,writable: false},age: {},height: {}})</script></body>
</html>

5 对象的其他方法补充

对象方法补充

<!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 obj = {name: "why",age: 18}// 1.获取属性描述符console.log(Object.getOwnPropertyDescriptor(obj, "name"))console.log(Object.getOwnPropertyDescriptors(obj))// 2.阻止对象的扩展Object.preventExtensions(obj)obj.address = "广州市"console.log(obj)// 3.密封对象(不能进行配置)Object.seal(obj)delete obj.nameconsole.log(obj)// 4.冻结对象(不能进行写入)Object.freeze(obj)obj.name = "kobe"console.log(obj)</script></body>
</html>


http://www.mrgr.cn/news/98276.html

相关文章:

  • 【docker】--部署--安装docker教程
  • 【HD-RK3576-PI】Docker搭建与使用
  • 【第41节】windows的中断与异常及异常处理方式
  • 记录一个虚拟机分配资源的问题
  • 第二十四:查看当前 端口号是否被占用
  • Open-TeleVision源码解析——宇树摇操方案的重要参考:VR控制人形机器人采集数据
  • 高并发内存池(三):PageCache(页缓存)的实现
  • python基础:数据类型转换、运算符(算术运算符、比较运算符、逻辑运算符、三元运算符、位运算符)
  • CTF--bp
  • Kubernetes服务注册到consul流程实践
  • ArkTS语言入门之接口、泛型、空安全、特殊运算符等
  • vulkanscenegraph显示倾斜模型(5.9)-vsg中vulkan资源的编译
  • 基于PySide6与pycatia的CATIA绘图比例智能调节工具开发全解析
  • 入门到精通,C语言十大经典程序
  • 从0到1使用C++操作MSXML
  • C语言十大经典数学应用
  • 考研单词笔记 2025.04.13
  • 【甲子光年】DeepSeek开启AI算法变革元年
  • Go:方法
  • 【随身wifi】青龙面板保姆级教程