Javascript
快来分享你的内容吧~
- 2024-07-08·后端基本语句语法:1.接收输入(弹出对话框): let age = prompt('请输入年龄')2.打印输出:document.write(``)3.控制台 输出语句,将"内容"输出在控制台中便于以后的调试:console.log(xx)4.弹出对话框:alert()5.获取变量值(避免变量和字符串混合输出时+和""要求的繁琐):"${变量}""eg: "我"+age+"岁了" 等价于 `我${ag查看全文编程导航_小y:小马同学,可以每天分享几篇技术文章 [机智] 不建议一次性同步多篇文章,鱼友们学习阅读来不太及 ~ 可以定时发布下210分享
- 2022-02-16·技术栈:前端 golang查看全文#资源# 阅读 js红宝书 本书是 JavaScript 经典图书的新版。第 4 版涵盖 ECMAScript 2019,全面、深入地介绍了 JavaScript 开发者必须掌握的前端开发技术,涉及 JavaScript 的基础特性和高级特性。书中详尽讨论了 JavaScript 的各个方面,...程序员鱼皮:要是能再简单介绍一下这本书就更好了哈哈4240分享
又一个新项目完结,让 AI 帮你盯全网热点!
大家好,我是程序员鱼皮。又经过了一段时间的爆肝,我在编程导航的保姆级新项目教程《AI 热点监控工具》,完结啦! 本项目学习地址:https://www.codefather.cn/course/2026625439052627970 这是一套以 **AI 编程实战** 为核心的项目教程,基于 Express 5 + React 19 + OpenRouter + Socket.io,用 AI 编程的方式从 0 到 1 开发一个 `AI 热点监控工具`,带你亲身体验 AI Vibe Coding 的完整工作流,学会用 AI 快速做出实用的提效工具。**没有任何编程基础也能跟着学习!**  我带大家开发了关键词监控、多数据源聚合抓取、AI 内容审核分析、WebSocket 实时推送、多维度筛选排序、Agent Skills 技能包等功能:  除了全程直播讲解的视频教程之外,还提供了整套文字教程,可想而知我最近掉了多少头发。。。  这还不够,每个项目我都写了详细的简历写法和面试题解,做完项目直接写到简历上、突击面试,一条龙服务!  真心换真心,我做项目教程的付出也得到了大家的认可,也帮很多同学拿到了大厂 offer~  接下来鱼皮给大家快速介绍这个项目,希望让更多需要它的同学看到,把它变成自己的项目。春招正处于黄金时段,简历上写满前沿技术,不仅求职有底气,做项目的能力也会大幅提升! **⭐️ 后文有加入学习的方式,千万不要错过!** ## 项目介绍 项目有 6 大核心能力。 1)配置监控关键词:用户输入要监控的关键词,比如 "Vibe Coding"、"Claude" 等,系统会自动开始监控。支持激活 / 暂停单个关键词。  2)AI 自动抓取和分析热点:系统每 30 分钟自动从 Twitter、Bing、HackerNews、搜狗、B 站、微博等 8+ 个信息源抓取内容,利用 AI 进行查询扩展、真假识别、相关性分析和智能摘要,过滤低质量内容后展示在信息流中。  3)多维度筛选和排序:支持按信息来源、重要性、时间范围进行筛选,支持按热度综合、相关性、发布时间排序,帮助用户快速定位需要的热点信息。  4)全网搜索:除了监控关键词的实时热点流外,还可以直接搜索特定的关键词,从全网获取信息。  5)实时通知:通过 WebSocket 实时推送热点通知,高重要性的热点还会通过邮件通知。  6)Agent Skills 技能包:将热点监控能力封装为标准的 Agent Skills,安装后在 Cursor、VSCode Copilot、Claude Code 等 AI 编程工具中都能直接使用,无需启动任何服务。  当你学会这个项目后,你不仅能开发 AI 热点监控工具,更能灵活运用 AI 编程开发各种工具类产品:数据聚合平台、AI 内容审核系统、实时推送服务、Agent Skills 技能包,尽情发挥自己的想象力吧~ 学前沿技术、涨开发经验,从 0 到 1 的实用工具开发,绝对让你收获满满! 而且为了让更多同学参与学习,我直接把所有代码 **完整开源** !能力强的同学可以自学,点个 star 就算对鱼皮的支持啦~ > 开源仓库:https://github.com/liyupi/yupi-hot-monitor ## 项目收获 本项目选题新颖,紧跟 AI 编程时代,以 **实用工具开发** 为导向,区别于增删改查的烂大街项目。项目内容精炼,**不到一周就能学完**,帮你成为 AI 时代企业的香饽饽,给你的简历和求职大幅增加竞争力! Node.js 全栈 AI 编程项目,技术丰富,玩透 AI Vibe Coding~  鱼皮给大家讲的是 **通用的 AI 编程方法和实用工具开发全流程**,从这个项目中你可以学到: - 如何用 AI 编程从 0 到 1 开发一个完整的工具? - 如何安装和使用 MCP 增强 AI 能力? - 如何安装和使用 Agent Skills 提升 AI 编程质量? - 如何从多个信息源(Twitter、Bing、HN、B 站等)聚合抓取内容? - 如何通过 OpenRouter 接入 AI 大模型,实现智能内容审核? - 如何实现查询扩展(Query Expansion),提高信息检索的召回率? - 如何基于 Socket.io 实现 WebSocket 实时推送? - 如何使用 Aceternity UI 打造炫酷的科技感前端界面? - 如何开发标准化的 Agent Skills 技能包,并在多种 AI 工具中验证? - 如何在 AI 编程中进行人工确认、版本控制和迭代优化? 此外,还能学会很多 AI 编程、工具设计、技术方案迭代的方法,提升排查问题、自主解决 Bug 的能力。鱼皮还给大家提供了大量的项目扩展点,有能力的同学可以进一步拉开和别人的区分度,无限进步! 满满的项目正反馈:  除视频教程外,鱼皮编程导航的项目还提供: | 教程资料 | 求职助力 | | ---------------------------- | ------------------------------ | | 详细的文字教程 / 直播笔记 | ⭐️ 现成的简历写法,直接写满简历 | | 完整的项目源码 | ⭐️ 项目相关面试题解和真实面经 | | 1 对 1 答疑解惑 + 专属交流群 | ⭐️ 项目扩展思路,拉开区分度 | | 前端 + Java 后端万用项目模板 | ⭐️ 从学项目到拿 Offer 一条龙 |  ## 加入学习 比起看网上的教程学习,鱼皮项目系列的优势:从学知识 => 实践项目 => 复习笔记 => 项目答疑 => 简历写法 => 面试题解的一条龙服务 编程导航已有 **20+ 套项目教程!** 每个项目的学习重点不同,从 0 到 1 带做,涵盖企业级 Java 后端 + 前端全栈项目、最新 AI 应用开发 + AI 编程项目、大厂架构进阶项目。  欢迎加入 [编程导航](https://www.codefather.cn/vip),不仅能学习往期 **所有** 原创项目,还能享受更多原创资料、1 对 1 学习和求职指导、几百场面试视频,开启你的编程起飞之旅~ 1 天不到 1 块钱,绝对是对自己最值的投资!成为编程导航会员后,可以解锁 20+ 套项目教程和海量资料,如图:  下面是更多关于本项目的介绍。 ## 更多介绍 该项目功能丰富,涵盖关键词管理、热点采集和分析、信息展示和筛选、实时通知系统、全网信息源搜索、Agent Skills 六大模块,20+ 功能点,覆盖了从信息采集、AI 智能分析到实时推送通知的完整热点监控闭环。  本项目采用前后端分离架构,前端使用 React + Vite,后端使用 Express + Prisma,通过 REST API 和 WebSocket 通信。通过定时任务引擎来驱动多数据源采集和 AI 分析,Agent Skills 作为独立模块可在多种 AI 编程工具中复用。  ## 加入学习 欢迎加入 [编程导航](https://www.codefather.cn/vip),不仅能学习往期 **所有** 原创项目(20+ 套),还能享受更多原创资料、学习和求职指导、几百场面试视频,开启你的编程起飞之旅~  已经有 **几万名** 小伙伴学起来了,还有很多大家自发整理的笔记。不得不说,做项目真的给了很多同学坚持学习的目标、也有了更多拿 Offer 的机会,大家的动力也更足了!冲冲冲! 
JS——【笔记】JavaScript基础
### 基本语句语法: 1.接收输入(弹出对话框): let age = prompt('请输入年龄') 2.打印输出:document.write(\`\`) 3.控制台 输出语句,将"内容"输出在控制台中便于以后的调试:console.log(xx) 4.弹出对话框:alert() 5.获取变量值(避免变量和字符串混合输出时+和""要求的繁琐): `${变量}` ```eg: "我"+age+"岁了" 等价于 `我${age}岁了` ``` ### 一、运算符 1.逻辑运算符运算顺序 先&&后||(无论出现的前后顺序如何) 2.`let num = +prompt('请输入一个数')`;prompt前加+能把变量转化为数字型 ### 二、数组 #### 1.声明 `let arr = [1,2,3]` 数组按顺序保存,每个数据有自己编号 #### 2.数组增加元素 **arr.push**(新增的内容):将一个或多个元素添加到数组==末尾==,并返回该数组长度 **arr.unshift**(新增的内容):将一个或多个元素添加到数组==开头==,并返回该数组长度 #### 3.数组删除元素 **arr.pop()**:从数组中删除最后一个元素并返回删除的元素 **arr.shift()**:从数组中删除开头一个元素并返回删除的元素 **arr.splice**(操作开始的下标,删除的个数):删除指定元素/个数 ### 三、函数 ##### 1.普通函数 声明: `function 函数名(参数列表){ }` 调用: 函数名() `function getSum(num1,num2){ document.write(num1+num2) return 返回值 /* 可无return,默认返回undefined */ } getSum(2,3)` 返回多个值:通过数组存多个值再返回实现 return \[返回值1,返回值2\] ##### 2.匿名函数 通过将匿名函数赋值给一个变量来调用,称为函数表达式 `eg; 声明 let fn = function(){ //函数体 } 调用: fn() //变量名()` ##### 3立即执行函数 立即执行,无需调用 方式一: `(function(形参){函数体})(实参)` 方式二: `(function(形参){函数体}(实参))` ### 三、对象(引用数据类型) 可理解为无序的数据集合 #### 1.声明: `let 对象名 = { 属性名:属性值,/*多个属性值用,分割*/ 方法名:函数 }` eg: `let person = { uname:'Tony', age: 18, sex: '男', sayHi: function (形参){ document.write('Hi~') } }` #### 2.访问属性: 方式1:对象.属性名 `eg:person.age` 方式2:对象\['属性名'\] `eg:person['age']` #### 3访问方法 对象.方法名(实参) `eg:person.sayHi()` #### 4.修改属性 对象.属性 = 新值 `eg:person.age = 17` #### 5.新增 新增属性 对象.新属性名 = 属性值 `eg:person.score = 98` 新增/修改(覆盖)方法 对象.方法名 = function(){} `eg:person.move = function() = {` `document.weite(移动一点)` `}` #### 6.删除属性 delete 对象名.属性名 `eg:delect person.score` #### 7.用for in循环语句遍历对象属性 格式: `for(let k in obj){/*其中k为变量,表示对象属性,常用k或key表示*/ }` eg: `for(let k in person){ /*k === 'uname === 'age' === 'set'*/ console.log(k)//得到带字符串的属性名 console.log(person.k)/* 错误,试图用对象.属性名方式获取属性值,但属性k不存在*/ console.log(person[k])/*正确,可以用对象[属性名]"不用加引号,k为变量"的方式获取属性值(按照遍历所得的属性顺序获取属性值)*/ }` ### 四、内置对象 JavaScript提供的对象,包含各种属性和方法给开发调用 如document.write()、consolo.log()都属于内置对象 对象及方法可查看文档(MDN Web Docs) #### 1、Math对象 常用方法:  `说明 Math.ceil(1.1) //返回2,向上取整,返回的整数 Math.floor(1.2) //返回1向下取整,返回的整数 Math.round(1.5) /*返回2*/ Math.round(-1.5) /*返回-1*/ //就近取整(负数往大的取) Math.max(1,5,9) Math.min(1,3,9) //返回最大值和最小值 Math.random()*(m-n+1) + n /*生成一个从n到m的随机数*/`
JavaScript进阶ES6学习第四天
<html> <head></head> <body> <div class="content ql-editor"> <p><br></p> <p><br></p> <p><br></p> <h1>JavaScript 进阶 - 第4天</h1> <p><br></p> <p><br></p> <p><br></p> <h2>深浅拷贝</h2> <p><br></p> <p><br></p> <p><br></p> <h3>浅拷贝</h3> <p><br></p> <p><br></p> <p>首先浅拷贝和深拷贝只针对引用类型</p> <p><br></p> <p>浅拷贝:拷贝的是地址</p> <p><br></p> <p>常见方法:</p> <p><br></p> <ol> <li data-list="ordered"><span class="ql-ui"></span>拷贝对象:<a href="http://Object.assgin" target="_blank">Object.assgin</a>() / 展开运算符 {<a href="http://...obj" target="_blank">...obj</a>} 拷贝对象</li> <li data-list="ordered"><span class="ql-ui"></span>拷贝数组:<a href="http://Array.prototype.concat" target="_blank">Array.prototype.concat</a>() 或者 [<a href="http://...arr" target="_blank">...arr</a>]</li> </ol> <p><br></p> <p><br></p> <p>如果是简单数据类型拷贝值,引用数据类型拷贝的是地址 (简单理解: 如果是单层对象,没问题,如果有多层就有问题)</p> <p><br></p> <p><br></p> <p><br></p> <h3>深拷贝</h3> <p><br></p> <p><br></p> <p>首先浅拷贝和深拷贝只针对引用类型</p> <p><br></p> <p>深拷贝:拷贝的是对象,不是地址</p> <p><br></p> <p>常见方法:</p> <p><br></p> <ol> <li data-list="ordered"><span class="ql-ui"></span>通过递归实现深拷贝</li> <li data-list="ordered"><span class="ql-ui"></span>lodash/cloneDeep</li> <li data-list="ordered"><span class="ql-ui"></span>通过JSON.stringify()实现</li> </ol> <p><br></p> <p><br></p> <h4>递归实现深拷贝</h4> <p><br></p> <p><br></p> <p>函数递归:</p> <p><br></p> <p>如果一个函数在内部可以调用其本身,那么这个函数就是递归函数</p> <p><br></p> <ol> <li data-list="bullet"><span class="ql-ui"></span>简单理解:函数内部自己调用自己, 这个函数就是递归函数</li> <li data-list="bullet"><span class="ql-ui"></span>递归函数的作用和循环效果类似</li> <li data-list="bullet"><span class="ql-ui"></span>由于递归很容易发生“栈溢出”错误(stack overflow),所以必须要加退出条件 return</li> </ol> <p><br></p> <div class="ql-code-block-container"> <div class="ql-code-block"> <body> </div> <div class="ql-code-block"> <script> </div> <div class="ql-code-block"> const obj = { </div> <div class="ql-code-block"> uname: 'pink', </div> <div class="ql-code-block"> age: 18, </div> <div class="ql-code-block"> hobby: ['乒乓球', '足球'], </div> <div class="ql-code-block"> family: { </div> <div class="ql-code-block"> baby: '小pink' </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> const o = {} </div> <div class="ql-code-block"> // 拷贝函数 </div> <div class="ql-code-block"> function deepCopy(newObj, oldObj) { </div> <div class="ql-code-block"> debugger </div> <div class="ql-code-block"> for (let k in oldObj) { </div> <div class="ql-code-block"> // 处理数组的问题 一定先写数组 在写 对象 不能颠倒 </div> <div class="ql-code-block"> if (oldObj[k] instanceof Array) { </div> <div class="ql-code-block"> newObj[k] = [] </div> <div class="ql-code-block"> // newObj[k] 接收 [] hobby </div> <div class="ql-code-block"> // oldObj[k] ['乒乓球', '足球'] </div> <div class="ql-code-block"> deepCopy(newObj[k], oldObj[k]) </div> <div class="ql-code-block"> } else if (oldObj[k] instanceof Object) { </div> <div class="ql-code-block"> newObj[k] = {} </div> <div class="ql-code-block"> deepCopy(newObj[k], oldObj[k]) </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> else { </div> <div class="ql-code-block"> // k 属性名 uname age oldObj[k] 属性值 18 </div> <div class="ql-code-block"> // newObj[k] === o.uname 给新对象添加属性 </div> <div class="ql-code-block"> newObj[k] = oldObj[k] </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> deepCopy(o, obj) // 函数调用 两个参数 o 新对象 obj 旧对象 </div> <div class="ql-code-block"> console.log(o) </div> <div class="ql-code-block"> o.age = 20 </div> <div class="ql-code-block"> o.hobby[0] = '篮球' </div> <div class="ql-code-block"> o.family.baby = '老pink' </div> <div class="ql-code-block"> console.log(obj) </div> <div class="ql-code-block"> console.log([1, 23] instanceof Object) </div> <div class="ql-code-block"> // 复习 </div> <div class="ql-code-block"> // const obj = { </div> <div class="ql-code-block"> // uname: 'pink', </div> <div class="ql-code-block"> // age: 18, </div> <div class="ql-code-block"> // hobby: ['乒乓球', '足球'] </div> <div class="ql-code-block"> // } </div> <div class="ql-code-block"> // function deepCopy({ }, oldObj) { </div> <div class="ql-code-block"> // // k 属性名 oldObj[k] 属性值 </div> <div class="ql-code-block"> // for (let k in oldObj) { </div> <div class="ql-code-block"> // // 处理数组的问题 k 变量 </div> <div class="ql-code-block"> // newObj[k] = oldObj[k] </div> <div class="ql-code-block"> // // o.uname = 'pink' </div> <div class="ql-code-block"> // // newObj.k = 'pink' </div> <div class="ql-code-block"> // } </div> <div class="ql-code-block"> // } </div> <div class="ql-code-block"> </script> </div> <div class="ql-code-block"> </body><body> </div> <div class="ql-code-block"> <script> </div> <div class="ql-code-block"> const obj = { </div> <div class="ql-code-block"> uname: 'pink', </div> <div class="ql-code-block"> age: 18, </div> <div class="ql-code-block"> hobby: ['乒乓球', '足球'], </div> <div class="ql-code-block"> family: { </div> <div class="ql-code-block"> baby: '小pink' </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> const o = {} </div> <div class="ql-code-block"> // 拷贝函数 </div> <div class="ql-code-block"> function deepCopy(newObj, oldObj) { </div> <div class="ql-code-block"> debugger </div> <div class="ql-code-block"> for (let k in oldObj) { </div> <div class="ql-code-block"> // 处理数组的问题 一定先写数组 在写 对象 不能颠倒 </div> <div class="ql-code-block"> if (oldObj[k] instanceof Array) { </div> <div class="ql-code-block"> newObj[k] = [] </div> <div class="ql-code-block"> // newObj[k] 接收 [] hobby </div> <div class="ql-code-block"> // oldObj[k] ['乒乓球', '足球'] </div> <div class="ql-code-block"> deepCopy(newObj[k], oldObj[k]) </div> <div class="ql-code-block"> } else if (oldObj[k] instanceof Object) { </div> <div class="ql-code-block"> newObj[k] = {} </div> <div class="ql-code-block"> deepCopy(newObj[k], oldObj[k]) </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> else { </div> <div class="ql-code-block"> // k 属性名 uname age oldObj[k] 属性值 18 </div> <div class="ql-code-block"> // newObj[k] === o.uname 给新对象添加属性 </div> <div class="ql-code-block"> newObj[k] = oldObj[k] </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> deepCopy(o, obj) // 函数调用 两个参数 o 新对象 obj 旧对象 </div> <div class="ql-code-block"> console.log(o) </div> <div class="ql-code-block"> o.age = 20 </div> <div class="ql-code-block"> o.hobby[0] = '篮球' </div> <div class="ql-code-block"> o.family.baby = '老pink' </div> <div class="ql-code-block"> console.log(obj) </div> <div class="ql-code-block"> console.log([1, 23] instanceof Object) </div> <div class="ql-code-block"> // 复习 </div> <div class="ql-code-block"> // const obj = { </div> <div class="ql-code-block"> // uname: 'pink', </div> <div class="ql-code-block"> // age: 18, </div> <div class="ql-code-block"> // hobby: ['乒乓球', '足球'] </div> <div class="ql-code-block"> // } </div> <div class="ql-code-block"> // function deepCopy({ }, oldObj) { </div> <div class="ql-code-block"> // // k 属性名 oldObj[k] 属性值 </div> <div class="ql-code-block"> // for (let k in oldObj) { </div> <div class="ql-code-block"> // // 处理数组的问题 k 变量 </div> <div class="ql-code-block"> // newObj[k] = oldObj[k] </div> <div class="ql-code-block"> // // o.uname = 'pink' </div> <div class="ql-code-block"> // // newObj.k = 'pink' </div> <div class="ql-code-block"> // } </div> <div class="ql-code-block"> // } </div> <div class="ql-code-block"> </script> </div> <div class="ql-code-block"> </body> </div> </div> <p><br></p> <p><br></p> <h4>js库lodash里面cloneDeep内部实现了深拷贝</h4> <p><br></p> <p><br></p> <div class="ql-code-block-container"> <div class="ql-code-block"> <body> </div> <div class="ql-code-block"> <!-- 先引用 --> </div> <div class="ql-code-block"> <script src="./lodash.min.js"></script> </div> <div class="ql-code-block"> <script> </div> <div class="ql-code-block"> const obj = { </div> <div class="ql-code-block"> uname: 'pink', </div> <div class="ql-code-block"> age: 18, </div> <div class="ql-code-block"> hobby: ['乒乓球', '足球'], </div> <div class="ql-code-block"> family: { </div> <div class="ql-code-block"> baby: '小pink' </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> const o = _.cloneDeep(obj) </div> <div class="ql-code-block"> console.log(o) </div> <div class="ql-code-block"> o.family.baby = '老pink' </div> <div class="ql-code-block"> console.log(obj) </div> <div class="ql-code-block"> </script> </div> <div class="ql-code-block"> </body><body> </div> <div class="ql-code-block"> <!-- 先引用 --> </div> <div class="ql-code-block"> <script src="./lodash.min.js"></script> </div> <div class="ql-code-block"> <script> </div> <div class="ql-code-block"> const obj = { </div> <div class="ql-code-block"> uname: 'pink', </div> <div class="ql-code-block"> age: 18, </div> <div class="ql-code-block"> hobby: ['乒乓球', '足球'], </div> <div class="ql-code-block"> family: { </div> <div class="ql-code-block"> baby: '小pink' </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> const o = _.cloneDeep(obj) </div> <div class="ql-code-block"> console.log(o) </div> <div class="ql-code-block"> o.family.baby = '老pink' </div> <div class="ql-code-block"> console.log(obj) </div> <div class="ql-code-block"> </script> </div> <div class="ql-code-block"> </body> </div> </div> <p><br></p> <p><br></p> <h4>JSON序列化</h4> <p><br></p> <p><br></p> <div class="ql-code-block-container"> <div class="ql-code-block"> <body> </div> <div class="ql-code-block"> <script> </div> <div class="ql-code-block"> const obj = { </div> <div class="ql-code-block"> uname: 'pink', </div> <div class="ql-code-block"> age: 18, </div> <div class="ql-code-block"> hobby: ['乒乓球', '足球'], </div> <div class="ql-code-block"> family: { </div> <div class="ql-code-block"> baby: '小pink' </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> // 把对象转换为 JSON 字符串 </div> <div class="ql-code-block"> // console.log(JSON.stringify(obj)) </div> <div class="ql-code-block"> const o = JSON.parse(JSON.stringify(obj)) </div> <div class="ql-code-block"> console.log(o) </div> <div class="ql-code-block"> o.family.baby = '123' </div> <div class="ql-code-block"> console.log(obj) </div> <div class="ql-code-block"> </script> </div> <div class="ql-code-block"> </body><body> </div> <div class="ql-code-block"> <script> </div> <div class="ql-code-block"> const obj = { </div> <div class="ql-code-block"> uname: 'pink', </div> <div class="ql-code-block"> age: 18, </div> <div class="ql-code-block"> hobby: ['乒乓球', '足球'], </div> <div class="ql-code-block"> family: { </div> <div class="ql-code-block"> baby: '小pink' </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> // 把对象转换为 JSON 字符串 </div> <div class="ql-code-block"> // console.log(JSON.stringify(obj)) </div> <div class="ql-code-block"> const o = JSON.parse(JSON.stringify(obj)) </div> <div class="ql-code-block"> console.log(o) </div> <div class="ql-code-block"> o.family.baby = '123' </div> <div class="ql-code-block"> console.log(obj) </div> <div class="ql-code-block"> </script> </div> <div class="ql-code-block"> </body> </div> </div> <p><br></p> <p><br></p> <h2>异常处理</h2> <p><br></p> <p><br></p> <p><br></p> <p>了解 JavaScript 中程序异常处理的方法,提升代码运行的健壮性。</p> <p><br></p> <p><br></p> <p><br></p> <h3>throw</h3> <p><br></p> <p><br></p> <p>异常处理是指预估代码执行过程中可能发生的错误,然后最大程度的避免错误的发生导致整个程序无法继续运行</p> <p><br></p> <p>总结:</p> <p><br></p> <ol> <li data-list="ordered"><span class="ql-ui"></span>throw 抛出异常信息,程序也会终止执行</li> <li data-list="ordered"><span class="ql-ui"></span>throw 后面跟的是错误提示信息</li> <li data-list="ordered"><span class="ql-ui"></span>Error 对象配合 throw 使用,能够设置更详细的错误信息</li> </ol> <p><br></p> <div class="ql-code-block-container"> <div class="ql-code-block"> <script> </div> <div class="ql-code-block"> function counter(x, y) { </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> if(!x || !y) { </div> <div class="ql-code-block"> // throw '参数不能为空!'; </div> <div class="ql-code-block"> throw new Error('参数不能为空!') </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> return x + y </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> counter() </div> <div class="ql-code-block"> </script><script> </div> <div class="ql-code-block"> function counter(x, y) { </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> if(!x || !y) { </div> <div class="ql-code-block"> // throw '参数不能为空!'; </div> <div class="ql-code-block"> throw new Error('参数不能为空!') </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> return x + y </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> counter() </div> <div class="ql-code-block"> </script> </div> </div> <p><br></p> <p>总结:</p> <p><br></p> <ol> <li data-list="ordered"><span class="ql-ui"></span>throw 抛出异常信息,程序也会终止执行</li> <li data-list="ordered"><span class="ql-ui"></span>throw 后面跟的是错误提示信息</li> <li data-list="ordered"><span class="ql-ui"></span>Error 对象配合 throw 使用,能够设置更详细的错误信息</li> </ol> <p><br></p> <p><br></p> <h3>try ... catch</h3> <p><br></p> <p><br></p> <div class="ql-code-block-container"> <div class="ql-code-block"> <script> </div> <div class="ql-code-block"> function foo() { </div> <div class="ql-code-block"> try { </div> <div class="ql-code-block"> // 查找 DOM 节点 </div> <div class="ql-code-block"> const p = document.querySelector('.p') </div> <div class="ql-code-block"> p.style.color = 'red' </div> <div class="ql-code-block"> } catch (error) { </div> <div class="ql-code-block"> // try 代码段中执行有错误时,会执行 catch 代码段 </div> <div class="ql-code-block"> // 查看错误信息 </div> <div class="ql-code-block"> console.log(error.message) </div> <div class="ql-code-block"> // 终止代码继续执行 </div> <div class="ql-code-block"> return </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> finally { </div> <div class="ql-code-block"> alert('执行') </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> console.log('如果出现错误,我的语句不会执行') </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> foo() </div> <div class="ql-code-block"> </script><script> </div> <div class="ql-code-block"> function foo() { </div> <div class="ql-code-block"> try { </div> <div class="ql-code-block"> // 查找 DOM 节点 </div> <div class="ql-code-block"> const p = document.querySelector('.p') </div> <div class="ql-code-block"> p.style.color = 'red' </div> <div class="ql-code-block"> } catch (error) { </div> <div class="ql-code-block"> // try 代码段中执行有错误时,会执行 catch 代码段 </div> <div class="ql-code-block"> // 查看错误信息 </div> <div class="ql-code-block"> console.log(error.message) </div> <div class="ql-code-block"> // 终止代码继续执行 </div> <div class="ql-code-block"> return </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> finally { </div> <div class="ql-code-block"> alert('执行') </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> console.log('如果出现错误,我的语句不会执行') </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> foo() </div> <div class="ql-code-block"> </script> </div> </div> <p><br></p> <p>总结:</p> <p><br></p> <ol> <li data-list="ordered"><span class="ql-ui"></span><a href="http://try...catch" target="_blank">try...catch</a> 用于捕获错误信息</li> <li data-list="ordered"><span class="ql-ui"></span>将预估可能发生错误的代码写在 try 代码段中</li> <li data-list="ordered"><span class="ql-ui"></span>如果 try 代码段中出现错误后,会执行 catch 代码段,并截获到错误信息</li> </ol> <p><br></p> <p><br></p> <h3>debugger</h3> <p><br></p> <p><br></p> <p>相当于断点调试</p> <p><br></p> <p><br></p> <h2>处理this</h2> <p><br></p> <p><br></p> <p><br></p> <p>了解函数中 this 在不同场景下的默认值,知道动态指定函数 this 值的方法。</p> <p><br></p> <p><br></p> <p>this 是 JavaScript 最具“魅惑”的知识点,不同的应用场合 this 的取值可能会有意想不到的结果,在此我们对以往学习过的关于【 this 默认的取值】情况进行归纳和总结。</p> <p><br></p> <p><br></p> <h3>普通函数</h3> <p><br></p> <p><br></p> <p><strong>普通函数</strong>的调用方式决定了 this 的值,即【谁调用 this 的值指向谁】,如下代码所示:</p> <p><br></p> <div class="ql-code-block-container"> <div class="ql-code-block"> <script> </div> <div class="ql-code-block"> // 普通函数 </div> <div class="ql-code-block"> function sayHi() { </div> <div class="ql-code-block"> console.log(this) </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> // 函数表达式 </div> <div class="ql-code-block"> const sayHello = function () { </div> <div class="ql-code-block"> console.log(this) </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> // 函数的调用方式决定了 this 的值 </div> <div class="ql-code-block"> sayHi() // window </div> <div class="ql-code-block"> window.sayHi() </div> <div class="ql-code-block"> </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> // 普通对象 </div> <div class="ql-code-block"> const user = { </div> <div class="ql-code-block"> name: '小明', </div> <div class="ql-code-block"> walk: function () { </div> <div class="ql-code-block"> console.log(this) </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> // 动态为 user 添加方法 </div> <div class="ql-code-block"> user.sayHi = sayHi </div> <div class="ql-code-block"> uesr.sayHello = sayHello </div> <div class="ql-code-block"> // 函数调用方式,决定了 this 的值 </div> <div class="ql-code-block"> user.sayHi() </div> <div class="ql-code-block"> user.sayHello() </div> <div class="ql-code-block"> </script><script> </div> <div class="ql-code-block"> // 普通函数 </div> <div class="ql-code-block"> function sayHi() { </div> <div class="ql-code-block"> console.log(this) </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> // 函数表达式 </div> <div class="ql-code-block"> const sayHello = function () { </div> <div class="ql-code-block"> console.log(this) </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> // 函数的调用方式决定了 this 的值 </div> <div class="ql-code-block"> sayHi() // window </div> <div class="ql-code-block"> window.sayHi() </div> <div class="ql-code-block"> </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> // 普通对象 </div> <div class="ql-code-block"> const user = { </div> <div class="ql-code-block"> name: '小明', </div> <div class="ql-code-block"> walk: function () { </div> <div class="ql-code-block"> console.log(this) </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> // 动态为 user 添加方法 </div> <div class="ql-code-block"> user.sayHi = sayHi </div> <div class="ql-code-block"> uesr.sayHello = sayHello </div> <div class="ql-code-block"> // 函数调用方式,决定了 this 的值 </div> <div class="ql-code-block"> user.sayHi() </div> <div class="ql-code-block"> user.sayHello() </div> <div class="ql-code-block"> </script> </div> </div> <p><br></p> <p>注: 普通函数没有明确调用者时 this 值为 window,严格模式下没有调用者时 this 的值为 undefined。</p> <p><br></p> <p><br></p> <h3>箭头函数</h3> <p><br></p> <p><br></p> <p><strong>箭头函数</strong>中的 this 与普通函数完全不同,也不受调用方式的影响,事实上箭头函数中并不存在 this !箭头函数中访问的 this 不过是箭头函数所在作用域的 this 变量。</p> <p><br></p> <div class="ql-code-block-container"> <div class="ql-code-block"> <script> </div> <div class="ql-code-block"> </div> <div class="ql-code-block"> console.log(this) // 此处为 window </div> <div class="ql-code-block"> // 箭头函数 </div> <div class="ql-code-block"> const sayHi = function() { </div> <div class="ql-code-block"> console.log(this) // 该箭头函数中的 this 为函数声明环境中 this 一致 </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> // 普通对象 </div> <div class="ql-code-block"> const user = { </div> <div class="ql-code-block"> name: '小明', </div> <div class="ql-code-block"> // 该箭头函数中的 this 为函数声明环境中 this 一致 </div> <div class="ql-code-block"> walk: () => { </div> <div class="ql-code-block"> console.log(this) </div> <div class="ql-code-block"> }, </div> <div class="ql-code-block"> </div> <div class="ql-code-block"> sleep: function () { </div> <div class="ql-code-block"> let str = 'hello' </div> <div class="ql-code-block"> console.log(this) </div> <div class="ql-code-block"> let fn = () => { </div> <div class="ql-code-block"> console.log(str) </div> <div class="ql-code-block"> console.log(this) // 该箭头函数中的 this 与 sleep 中的 this 一致 </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> // 调用箭头函数 </div> <div class="ql-code-block"> fn(); </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> // 动态添加方法 </div> <div class="ql-code-block"> user.sayHi = sayHi </div> <div class="ql-code-block"> </div> <div class="ql-code-block"> // 函数调用 </div> <div class="ql-code-block"> user.sayHi() </div> <div class="ql-code-block"> user.sleep() </div> <div class="ql-code-block"> user.walk() </div> <div class="ql-code-block"> </script><script> </div> <div class="ql-code-block"> </div> <div class="ql-code-block"> console.log(this) // 此处为 window </div> <div class="ql-code-block"> // 箭头函数 </div> <div class="ql-code-block"> const sayHi = function() { </div> <div class="ql-code-block"> console.log(this) // 该箭头函数中的 this 为函数声明环境中 this 一致 </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> // 普通对象 </div> <div class="ql-code-block"> const user = { </div> <div class="ql-code-block"> name: '小明', </div> <div class="ql-code-block"> // 该箭头函数中的 this 为函数声明环境中 this 一致 </div> <div class="ql-code-block"> walk: () => { </div> <div class="ql-code-block"> console.log(this) </div> <div class="ql-code-block"> }, </div> <div class="ql-code-block"> </div> <div class="ql-code-block"> sleep: function () { </div> <div class="ql-code-block"> let str = 'hello' </div> <div class="ql-code-block"> console.log(this) </div> <div class="ql-code-block"> let fn = () => { </div> <div class="ql-code-block"> console.log(str) </div> <div class="ql-code-block"> console.log(this) // 该箭头函数中的 this 与 sleep 中的 this 一致 </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> // 调用箭头函数 </div> <div class="ql-code-block"> fn(); </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> // 动态添加方法 </div> <div class="ql-code-block"> user.sayHi = sayHi </div> <div class="ql-code-block"> </div> <div class="ql-code-block"> // 函数调用 </div> <div class="ql-code-block"> user.sayHi() </div> <div class="ql-code-block"> user.sleep() </div> <div class="ql-code-block"> user.walk() </div> <div class="ql-code-block"> </script> </div> </div> <p><br></p> <p>在开发中【使用箭头函数前需要考虑函数中 this 的值】,<strong>事件回调函数</strong>使用箭头函数时,this 为全局的 window,因此DOM事件回调函数不推荐使用箭头函数,如下代码所示:</p> <p><br></p> <div class="ql-code-block-container"> <div class="ql-code-block"> <script> </div> <div class="ql-code-block"> // DOM 节点 </div> <div class="ql-code-block"> const btn = document.querySelector('.btn') </div> <div class="ql-code-block"> // 箭头函数 此时 this 指向了 window </div> <div class="ql-code-block"> btn.addEventListener('click', () => { </div> <div class="ql-code-block"> console.log(this) </div> <div class="ql-code-block"> }) </div> <div class="ql-code-block"> // 普通函数 此时 this 指向了 DOM 对象 </div> <div class="ql-code-block"> btn.addEventListener('click', function () { </div> <div class="ql-code-block"> console.log(this) </div> <div class="ql-code-block"> }) </div> <div class="ql-code-block"> </script><script> </div> <div class="ql-code-block"> // DOM 节点 </div> <div class="ql-code-block"> const btn = document.querySelector('.btn') </div> <div class="ql-code-block"> // 箭头函数 此时 this 指向了 window </div> <div class="ql-code-block"> btn.addEventListener('click', () => { </div> <div class="ql-code-block"> console.log(this) </div> <div class="ql-code-block"> }) </div> <div class="ql-code-block"> // 普通函数 此时 this 指向了 DOM 对象 </div> <div class="ql-code-block"> btn.addEventListener('click', function () { </div> <div class="ql-code-block"> console.log(this) </div> <div class="ql-code-block"> }) </div> <div class="ql-code-block"> </script> </div> </div> <p><br></p> <p>同样由于箭头函数 this 的原因,<strong>基于原型的面向对象也不推荐采用箭头函数</strong>,如下代码所示:</p> <p><br></p> <div class="ql-code-block-container"> <div class="ql-code-block"> <script> </div> <div class="ql-code-block"> function Person() { </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> // 原型对像上添加了箭头函数 </div> <div class="ql-code-block"> Person.prototype.walk = () => { </div> <div class="ql-code-block"> console.log('人都要走路...') </div> <div class="ql-code-block"> console.log(this); // window </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> const p1 = new Person() </div> <div class="ql-code-block"> p1.walk() </div> <div class="ql-code-block"> </script><script> </div> <div class="ql-code-block"> function Person() { </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> // 原型对像上添加了箭头函数 </div> <div class="ql-code-block"> Person.prototype.walk = () => { </div> <div class="ql-code-block"> console.log('人都要走路...') </div> <div class="ql-code-block"> console.log(this); // window </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> const p1 = new Person() </div> <div class="ql-code-block"> p1.walk() </div> <div class="ql-code-block"> </script> </div> </div> <p><br></p> <p><br></p> <h3>改变this指向</h3> <p><br></p> <p><br></p> <p>以上归纳了普通函数和箭头函数中关于 this 默认值的情形,不仅如此 JavaScript 中还允许指定函数中 this 的指向,有 3 个方法可以动态指定普通函数中 this 的指向:</p> <p><br></p> <p><br></p> <h4>call</h4> <p><br></p> <p><br></p> <p>使用 call 方法调用函数,同时指定函数中 this 的值,使用方法如下代码所示:</p> <p><br></p> <div class="ql-code-block-container"> <div class="ql-code-block"> <script> </div> <div class="ql-code-block"> // 普通函数 </div> <div class="ql-code-block"> function sayHi() { </div> <div class="ql-code-block"> console.log(this); </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> let user = { </div> <div class="ql-code-block"> name: '小明', </div> <div class="ql-code-block"> age: 18 </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> let student = { </div> <div class="ql-code-block"> name: '小红', </div> <div class="ql-code-block"> age: 16 </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> // 调用函数并指定 this 的值 </div> <div class="ql-code-block"> sayHi.call(user); // this 值为 user </div> <div class="ql-code-block"> sayHi.call(student); // this 值为 student </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> // 求和函数 </div> <div class="ql-code-block"> function counter(x, y) { </div> <div class="ql-code-block"> return x + y; </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> // 调用 counter 函数,并传入参数 </div> <div class="ql-code-block"> let result = counter.call(null, 5, 10); </div> <div class="ql-code-block"> console.log(result); </div> <div class="ql-code-block"> </script><script> </div> <div class="ql-code-block"> // 普通函数 </div> <div class="ql-code-block"> function sayHi() { </div> <div class="ql-code-block"> console.log(this); </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> let user = { </div> <div class="ql-code-block"> name: '小明', </div> <div class="ql-code-block"> age: 18 </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> let student = { </div> <div class="ql-code-block"> name: '小红', </div> <div class="ql-code-block"> age: 16 </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> // 调用函数并指定 this 的值 </div> <div class="ql-code-block"> sayHi.call(user); // this 值为 user </div> <div class="ql-code-block"> sayHi.call(student); // this 值为 student </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> // 求和函数 </div> <div class="ql-code-block"> function counter(x, y) { </div> <div class="ql-code-block"> return x + y; </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> // 调用 counter 函数,并传入参数 </div> <div class="ql-code-block"> let result = counter.call(null, 5, 10); </div> <div class="ql-code-block"> console.log(result); </div> <div class="ql-code-block"> </script> </div> </div> <p><br></p> <p>总结:</p> <p><br></p> <ol> <li data-list="ordered"><span class="ql-ui"></span>call 方法能够在调用函数的同时指定 this 的值</li> <li data-list="ordered"><span class="ql-ui"></span>使用 call 方法调用函数时,第1个参数为 this 指定的值</li> <li data-list="ordered"><span class="ql-ui"></span>call 方法的其余参数会依次自动传入函数做为函数的参数</li> </ol> <p><br></p> <p><br></p> <h4>apply</h4> <p><br></p> <p><br></p> <p>使用 call 方法<strong>调用函数</strong>,同时指定函数中 this 的值,使用方法如下代码所示:</p> <p><br></p> <div class="ql-code-block-container"> <div class="ql-code-block"> <script> </div> <div class="ql-code-block"> // 普通函数 </div> <div class="ql-code-block"> function sayHi() { </div> <div class="ql-code-block"> console.log(this) </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> let user = { </div> <div class="ql-code-block"> name: '小明', </div> <div class="ql-code-block"> age: 18 </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> let student = { </div> <div class="ql-code-block"> name: '小红', </div> <div class="ql-code-block"> age: 16 </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> // 调用函数并指定 this 的值 </div> <div class="ql-code-block"> sayHi.apply(user) // this 值为 user </div> <div class="ql-code-block"> sayHi.apply(student) // this 值为 student </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> // 求和函数 </div> <div class="ql-code-block"> function counter(x, y) { </div> <div class="ql-code-block"> return x + y </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> // 调用 counter 函数,并传入参数 </div> <div class="ql-code-block"> let result = counter.apply(null, [5, 10]) </div> <div class="ql-code-block"> console.log(result) </div> <div class="ql-code-block"> </script><script> </div> <div class="ql-code-block"> // 普通函数 </div> <div class="ql-code-block"> function sayHi() { </div> <div class="ql-code-block"> console.log(this) </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> let user = { </div> <div class="ql-code-block"> name: '小明', </div> <div class="ql-code-block"> age: 18 </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> let student = { </div> <div class="ql-code-block"> name: '小红', </div> <div class="ql-code-block"> age: 16 </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> // 调用函数并指定 this 的值 </div> <div class="ql-code-block"> sayHi.apply(user) // this 值为 user </div> <div class="ql-code-block"> sayHi.apply(student) // this 值为 student </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> // 求和函数 </div> <div class="ql-code-block"> function counter(x, y) { </div> <div class="ql-code-block"> return x + y </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> // 调用 counter 函数,并传入参数 </div> <div class="ql-code-block"> let result = counter.apply(null, [5, 10]) </div> <div class="ql-code-block"> console.log(result) </div> <div class="ql-code-block"> </script> </div> </div> <p><br></p> <p>总结:</p> <p><br></p> <ol> <li data-list="ordered"><span class="ql-ui"></span>apply 方法能够在调用函数的同时指定 this 的值</li> <li data-list="ordered"><span class="ql-ui"></span>使用 apply 方法调用函数时,第1个参数为 this 指定的值</li> <li data-list="ordered"><span class="ql-ui"></span>apply 方法第2个参数为数组,数组的单元值依次自动传入函数做为函数的参数</li> </ol> <p><br></p> <p><br></p> <h4>bind</h4> <p><br></p> <p><br></p> <p>bind 方法并<strong>不会调用函数</strong>,而是创建一个指定了 this 值的新函数,使用方法如下代码所示:</p> <p><br></p> <div class="ql-code-block-container"> <div class="ql-code-block"> <script> </div> <div class="ql-code-block"> // 普通函数 </div> <div class="ql-code-block"> function sayHi() { </div> <div class="ql-code-block"> console.log(this) </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> let user = { </div> <div class="ql-code-block"> name: '小明', </div> <div class="ql-code-block"> age: 18 </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> // 调用 bind 指定 this 的值 </div> <div class="ql-code-block"> let sayHello = sayHi.bind(user); </div> <div class="ql-code-block"> // 调用使用 bind 创建的新函数 </div> <div class="ql-code-block"> sayHello() </div> <div class="ql-code-block"> </script><script> </div> <div class="ql-code-block"> // 普通函数 </div> <div class="ql-code-block"> function sayHi() { </div> <div class="ql-code-block"> console.log(this) </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> let user = { </div> <div class="ql-code-block"> name: '小明', </div> <div class="ql-code-block"> age: 18 </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> // 调用 bind 指定 this 的值 </div> <div class="ql-code-block"> let sayHello = sayHi.bind(user); </div> <div class="ql-code-block"> // 调用使用 bind 创建的新函数 </div> <div class="ql-code-block"> sayHello() </div> <div class="ql-code-block"> </script> </div> </div> <p><br></p> <p>注:bind 方法创建新的函数,与原函数的唯一的变化是改变了 this 的值。</p> <p><br></p> <p><br></p> <h2>防抖节流</h2> <p><br></p> <p><br></p> <ol> <li data-list="ordered"><span class="ql-ui"></span>防抖(debounce)</li> <li data-list="ordered"><span class="ql-ui"></span>所谓防抖,就是指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数执行时间</li> <li data-list="ordered"><span class="ql-ui"></span>节流(throttle)</li> <li data-list="ordered"><span class="ql-ui"></span>所谓节流,就是指连续触发事件但是在 n 秒中只执行一次函数</li> </ol> <p><br></p> <p><br></p> </div> </body> </html>
JavaScript进阶ES6学习第三天
<html> <head></head> <body> <div class="content ql-editor"> <p><br></p> <p><br></p> <h1>JavaScript 进阶 - 第3天笔记</h1> <p><br></p> <p><br></p> <p><br></p> <p>了解构造函数原型对象的语法特征,掌握 JavaScript 中面向对象编程的实现方式,基于面向对象编程思想实现 DOM 操作的封装。</p> <p><br></p> <p><br></p> <ol> <li data-list="bullet"><span class="ql-ui"></span>了解面向对象编程的一般特征</li> <li data-list="bullet"><span class="ql-ui"></span>掌握基于构造函数原型对象的逻辑封装</li> <li data-list="bullet"><span class="ql-ui"></span>掌握基于原型对象实现的继承</li> <li data-list="bullet"><span class="ql-ui"></span>理解什么原型链及其作用</li> <li data-list="bullet"><span class="ql-ui"></span>能够处理程序异常提升程序执行的健壮性</li> </ol> <p><br></p> <p><br></p> <h2>编程思想</h2> <p><br></p> <p><br></p> <p><br></p> <p>学习 JavaScript 中基于原型的面向对象编程序的语法实现,理解面向对象编程的特征。</p> <p><br></p> <p><br></p> <p><br></p> <h3>面向过程</h3> <p><br></p> <p><br></p> <p>面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候再一个一个的依次</p> <p><br></p> <p>调用就可以了。</p> <p><br></p> <p>举个栗子:蛋炒饭</p> <p><br></p> <h3>面向对象</h3> <p><br></p> <p><br></p> <p>面向对象是把事务分解成为一个个对象,然后由对象之间分工与合作。</p> <p><br></p> <p><img src="disableDownload"></p> <p><br></p> <p>在面向对象程序开发思想中,每一个对象都是功能中心,具有明确分工。</p> <p><br></p> <p>面向对象编程具有灵活、代码可复用、容易维护和开发的优点,更适合多人合作的大型软件项目。</p> <p><br></p> <p>面向对象的特性:</p> <p><br></p> <ol> <li data-list="bullet"><span class="ql-ui"></span> 封装性</li> <li data-list="bullet"><span class="ql-ui"></span> 继承性</li> <li data-list="bullet"><span class="ql-ui"></span> 多态性</li> </ol> <p><br></p> <p><br></p> <h2>构造函数</h2> <p><br></p> <p><br></p> <p>对比以下通过面向对象的构造函数实现的封装:</p> <p><br></p> <div class="ql-code-block-container"> <div class="ql-code-block"> <script> </div> <div class="ql-code-block"> function Person() { </div> <div class="ql-code-block"> this.name = '佚名' </div> <div class="ql-code-block"> // 设置名字 </div> <div class="ql-code-block"> this.setName = function (name) { </div> <div class="ql-code-block"> this.name = name </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> // 读取名字 </div> <div class="ql-code-block"> this.getName = () => { </div> <div class="ql-code-block"> console.log(this.name) </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> // 实例对像,获得了构造函数中封装的所有逻辑 </div> <div class="ql-code-block"> let p1 = new Person() </div> <div class="ql-code-block"> p1.setName('小明') </div> <div class="ql-code-block"> console.log(p1.name) </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> // 实例对象 </div> <div class="ql-code-block"> let p2 = new Person() </div> <div class="ql-code-block"> console.log(p2.name) </div> <div class="ql-code-block"> </script> </div> </div> <p><br></p> <p>封装是面向对象思想中比较重要的一部分,js面向对象可以通过构造函数实现的封装。</p> <p><br></p> <p>同样的将变量和函数组合到了一起并能通过 this 实现数据的共享,所不同的是借助构造函数创建出来的实例对象之</p> <p><br></p> <p>间是彼此不影响的</p> <p><br></p> <p><br></p> <p>总结:</p> <p></p> <ol> <li data-list="ordered"><span class="ql-ui"></span>构造函数体现了面向对象的封装特性</li> <li data-list="ordered"><span class="ql-ui"></span>构造函数实例创建的对象彼此独立、互不影响</li> </ol> <p><br></p> <p><br></p> <p>封装是面向对象思想中比较重要的一部分,js面向对象可以通过构造函数实现的封装。</p> <p><br></p> <p>前面我们学过的构造函数方法很好用,但是 存在浪费内存的问题</p> <p><br></p> <p><br></p> <h2>原型对象</h2> <p><br></p> <p><br></p> <p>构造函数通过原型分配的函数是所有对象所 共享的。</p> <p><br></p> <ol> <li data-list="bullet"><span class="ql-ui"></span>JavaScript 规定,每一个构造函数都有一个 prototype 属性,指向另一个对象,所以我们也称为原型对象</li> <li data-list="bullet"><span class="ql-ui"></span>这个对象可以挂载函数,对象实例化不会多次创建原型上函数,节约内存</li> <li data-list="bullet"><span class="ql-ui"></span>我们可以把那些不变的方法,直接定义在 prototype 对象上,这样所有对象的实例就可以共享这些方法。</li> <li data-list="bullet"><span class="ql-ui"></span>构造函数和原型对象中的this 都指向 实例化的对象</li> </ol> <p><br></p> <div class="ql-code-block-container"> <div class="ql-code-block"> <script> </div> <div class="ql-code-block"> function Person() { </div> <div class="ql-code-block"> </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> // 每个函数都有 prototype 属性 </div> <div class="ql-code-block"> console.log(Person.prototype) </div> <div class="ql-code-block"> </script> </div> </div> <p><br></p> <p>了解了 JavaScript 中构造函数与原型对象的关系后,再来看原型对象具体的作用,如下代码所示:</p> <p><br></p> <div class="ql-code-block-container"> <div class="ql-code-block"> <script> </div> <div class="ql-code-block"> function Person() { </div> <div class="ql-code-block"> // 此处未定义任何方法 </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> // 为构造函数的原型对象添加方法 </div> <div class="ql-code-block"> Person.prototype.sayHi = function () { </div> <div class="ql-code-block"> console.log('Hi~'); </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> </div> <div class="ql-code-block"> // 实例化 </div> <div class="ql-code-block"> let p1 = new Person(); </div> <div class="ql-code-block"> p1.sayHi(); // 输出结果为 Hi~ </div> <div class="ql-code-block"> </script> </div> </div> <p><br></p> <p>构造函数 Person 中未定义任何方法,这时实例对象调用了原型对象中的方法 sayHi,接下来改动一下代码:</p> <p><br></p> <div class="ql-code-block-container"> <div class="ql-code-block"> <script> </div> <div class="ql-code-block"> function Person() { </div> <div class="ql-code-block"> // 此处定义同名方法 sayHi </div> <div class="ql-code-block"> this.sayHi = function () { </div> <div class="ql-code-block"> console.log('嗨!'); </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> // 为构造函数的原型对象添加方法 </div> <div class="ql-code-block"> Person.prototype.sayHi = function () { </div> <div class="ql-code-block"> console.log('Hi~'); </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> let p1 = new Person(); </div> <div class="ql-code-block"> p1.sayHi(); // 输出结果为 嗨! </div> <div class="ql-code-block"> </script> </div> </div> <p><br></p> <p>构造函数 Person 中定义与原型对象中相同名称的方法,这时实例对象调用则是构造函中的方法 sayHi。</p> <p><br></p> <p>通过以上两个简单示例不难发现 JavaScript 中对象的工作机制:<strong>当访问对象的属性或方法时,先在当前实例对象是查找,然后再去原型对象查找,并且原型对象被所有实例共享。</strong></p> <p><br></p> <div class="ql-code-block-container"> <div class="ql-code-block"> <script> </div> <div class="ql-code-block"> function Person() { </div> <div class="ql-code-block"> // 此处定义同名方法 sayHi </div> <div class="ql-code-block"> this.sayHi = function () { </div> <div class="ql-code-block"> console.log('嗨!' + this.name) </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> // 为构造函数的原型对象添加方法 </div> <div class="ql-code-block"> Person.prototype.sayHi = function () { </div> <div class="ql-code-block"> console.log('Hi~' + this.name) </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> // 在构造函数的原型对象上添加属性 </div> <div class="ql-code-block"> Person.prototype.name = '小明' </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> let p1 = new Person() </div> <div class="ql-code-block"> p1.sayHi(); // 输出结果为 嗨! </div> <div class="ql-code-block"> </div> <div class="ql-code-block"> let p2 = new Person() </div> <div class="ql-code-block"> p2.sayHi() </div> <div class="ql-code-block"> </script> </div> </div> <p><br></p> <p>总结:<strong>结合构造函数原型的特征,实际开发重往往会将封装的功能函数添加到原型对象中。</strong></p> <p><br></p> <p><br></p> <h3>constructor 属性</h3> <p><br></p> <p><br></p> <p>在哪里? 每个原型对象里面都有个constructor 属性(constructor 构造函数)</p> <p><br></p> <p>作用:该属性指向该原型对象的构造函数, 简单理解,就是指向我的爸爸,我是有爸爸的孩子</p> <p><br></p> <p><strong>使用场景:</strong></p> <p><br></p> <p>如果有多个对象的方法,我们可以给原型对象采取对象形式赋值.</p> <p><br></p> <p>但是这样就会覆盖构造函数原型对象原来的内容,这样修改后的原型对象 constructor 就不再指向当前构造函数了</p> <p><br></p> <p>此时,我们可以在修改后的原型对象中,添加一个 constructor 指向原来的构造函数。</p> <p><br></p> <p><br></p> <h3>对象原型</h3> <p><br></p> <p><br></p> <p>对象都会有一个属性 <strong>proto</strong> 指向构造函数的 prototype 原型对象,之所以我们对象可以使用构造函数 prototype</p> <p><br></p> <p>原型对象的属性和方法,就是因为对象有 <strong>proto</strong> 原型的存在。</p> <p><br></p> <p>注意:</p> <p><br></p> <ol> <li data-list="bullet"><span class="ql-ui"></span><strong>_proto_</strong> 是JS非标准属性</li> <li data-list="bullet"><span class="ql-ui"></span>[[prototype]]和_<strong>proto_</strong>意义相同</li> <li data-list="bullet"><span class="ql-ui"></span>用来表明当前实例对象指向哪个原型对象prototype</li> <li data-list="bullet"><span class="ql-ui"></span><strong>_proto_</strong>对象原型里面也有一个 constructor属性,指向创建该实例对象的构造函数</li> </ol> <p><br></p> <p><br></p> <h3>原型继承</h3> <p><br></p> <p><br></p> <p>继承是面向对象编程的另一个特征,通过继承进一步提升代码封装的程度,JavaScript 中大多是借助原型对象实现继承</p> <p><br></p> <p>的特性。</p> <p><br></p> <p>龙生龙、凤生凤、老鼠的儿子会打洞描述的正是继承的含义。</p> <p><br></p> <div class="ql-code-block-container"> <div class="ql-code-block"> <body> </div> <div class="ql-code-block"> <script> </div> <div class="ql-code-block"> // 继续抽取 公共的部分放到原型上 </div> <div class="ql-code-block"> // const Person1 = { </div> <div class="ql-code-block"> // eyes: 2, </div> <div class="ql-code-block"> // head: 1 </div> <div class="ql-code-block"> // } </div> <div class="ql-code-block"> // const Person2 = { </div> <div class="ql-code-block"> // eyes: 2, </div> <div class="ql-code-block"> // head: 1 </div> <div class="ql-code-block"> // } </div> <div class="ql-code-block"> // 构造函数 new 出来的对象 结构一样,但是对象不一样 </div> <div class="ql-code-block"> function Person() { </div> <div class="ql-code-block"> this.eyes = 2 </div> <div class="ql-code-block"> this.head = 1 </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> // console.log(new Person) </div> <div class="ql-code-block"> // 女人 构造函数 继承 想要 继承 Person </div> <div class="ql-code-block"> function Woman() { </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> // Woman 通过原型来继承 Person </div> <div class="ql-code-block"> // 父构造函数(父类) 子构造函数(子类) </div> <div class="ql-code-block"> // 子类的原型 = new 父类 </div> <div class="ql-code-block"> Woman.prototype = new Person() // {eyes: 2, head: 1} </div> <div class="ql-code-block"> // 指回原来的构造函数 </div> <div class="ql-code-block"> Woman.prototype.constructor = Woman </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> // 给女人添加一个方法 生孩子 </div> <div class="ql-code-block"> Woman.prototype.baby = function () { </div> <div class="ql-code-block"> console.log('宝贝') </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> const red = new Woman() </div> <div class="ql-code-block"> console.log(red) </div> <div class="ql-code-block"> // console.log(Woman.prototype) </div> <div class="ql-code-block"> // 男人 构造函数 继承 想要 继承 Person </div> <div class="ql-code-block"> function Man() { </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> // 通过 原型继承 Person </div> <div class="ql-code-block"> Man.prototype = new Person() </div> <div class="ql-code-block"> Man.prototype.constructor = Man </div> <div class="ql-code-block"> const pink = new Man() </div> <div class="ql-code-block"> console.log(pink) </div> <div class="ql-code-block"> </script> </div> <div class="ql-code-block"> </body> </div> </div> <p><br></p> <p><br></p> <h3>原型链</h3> <p><br></p> <p><br></p> <p>基于原型对象的继承使得不同构造函数的原型对象关联在一起,并且这种关联的关系是一种链状的结构,我们将原型对</p> <p><br></p> <p>象的链状结构关系称为原型链</p> <p><br></p> <div class="ql-code-block-container"> <div class="ql-code-block"> <body> </div> <div class="ql-code-block"> <script> </div> <div class="ql-code-block"> // function Objetc() {} </div> <div class="ql-code-block"> console.log(Object.prototype) </div> <div class="ql-code-block"> console.log(Object.prototype.__proto__) </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> function Person() { </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> const ldh = new Person() </div> <div class="ql-code-block"> // console.log(ldh.__proto__ === Person.prototype) </div> <div class="ql-code-block"> // console.log(Person.prototype.__proto__ === Object.prototype) </div> <div class="ql-code-block"> console.log(ldh instanceof Person) </div> <div class="ql-code-block"> console.log(ldh instanceof Object) </div> <div class="ql-code-block"> console.log(ldh instanceof Array) </div> <div class="ql-code-block"> console.log([1, 2, 3] instanceof Array) </div> <div class="ql-code-block"> console.log(Array instanceof Object) </div> <div class="ql-code-block"> </script> </div> <div class="ql-code-block"> </body> </div> </div> <p><br></p> <p>① 当访问一个对象的属性(包括方法)时,首先查找这个对象自身有没有该属性。</p> <p><br></p> <p>② 如果没有就查找它的原型(也就是 <strong>proto</strong>指向的 prototype 原型对象)</p> <p><br></p> <p>③ 如果还没有就查找原型对象的原型(Object的原型对象)</p> <p><br></p> <p>④ 依此类推一直找到 Object 为止(null)</p> <p><br></p> <p>⑤ <strong>proto</strong>对象原型的意义就在于为对象成员查找机制提供一个方向,或者说一条路线</p> <p><br></p> <p>⑥ 可以使用 instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上</p> <p><br></p> <p><br></p> </div> </body> </html>
JavaScript进阶ES6学习第二天
<html> <head></head> <body> <div class="content ql-editor"> <p><br></p> <p><br></p> <p><br></p> <h1>JavaScript 进阶 - 第1天</h1> <p><br></p> <p><br></p> <p><br></p> <p>学习作用域、变量提升、闭包等语言特征,加深对 JavaScript 的理解,掌握变量赋值、函数声明的简洁语法,降低代码的冗余度。</p> <p><br></p> <p><br></p> <ol> <li data-list="bullet"><span class="ql-ui"></span>理解作用域对程序执行的影响</li> <li data-list="bullet"><span class="ql-ui"></span>能够分析程序执行的作用域范围</li> <li data-list="bullet"><span class="ql-ui"></span>理解闭包本质,利用闭包创建隔离作用域</li> <li data-list="bullet"><span class="ql-ui"></span>了解什么变量提升及函数提升</li> <li data-list="bullet"><span class="ql-ui"></span>掌握箭头函数、解析剩余参数等简洁语法</li> </ol> <p><br></p> <p><br></p> <h2>作用域</h2> <p><br></p> <p><br></p> <p><br></p> <p>了解作用域对程序执行的影响及作用域链的查找机制,使用闭包函数创建隔离作用域避免全局变量污染。</p> <p><br></p> <p><br></p> <p>作用域(scope)规定了变量能够被访问的“范围”,离开了这个“范围”变量便不能被访问,作用域分为全局作用域和局部作用域。</p> <p><br></p> <p><br></p> <h3>局部作用域</h3> <p><br></p> <p><br></p> <p>局部作用域分为函数作用域和块作用域。</p> <p><br></p> <p><br></p> <h4>函数作用域</h4> <p><br></p> <p><br></p> <p>在函数内部声明的变量只能在函数内部被访问,外部无法直接访问。</p> <p><br></p> <div class="ql-code-block-container"> <div class="ql-code-block"> <script> </div> <div class="ql-code-block"> // 声明 counter 函数 </div> <div class="ql-code-block"> function counter(x, y) { </div> <div class="ql-code-block"> // 函数内部声明的变量 </div> <div class="ql-code-block"> const s = x + y </div> <div class="ql-code-block"> console.log(s) // 18 </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> // 设用 counter 函数 </div> <div class="ql-code-block"> counter(10, 8) </div> <div class="ql-code-block"> // 访问变量 s </div> <div class="ql-code-block"> console.log(s)// 报错 </div> <div class="ql-code-block"> </script> </div> </div> <p><br></p> <p>总结:</p> <p><br></p> <ol> <li data-list="ordered"><span class="ql-ui"></span>函数内部声明的变量,在函数外部无法被访问</li> <li data-list="ordered"><span class="ql-ui"></span>函数的参数也是函数内部的局部变量</li> <li data-list="ordered"><span class="ql-ui"></span>不同函数内部声明的变量无法互相访问</li> <li data-list="ordered"><span class="ql-ui"></span>函数执行完毕后,函数内部的变量实际被清空了</li> </ol> <p><br></p> <p><br></p> <h4>块作用域</h4> <p><br></p> <p><br></p> <p>在 JavaScript 中使用 {} 包裹的代码称为代码块,代码块内部声明的变量外部将【有可能】无法被访问。</p> <p><br></p> <div class="ql-code-block-container"> <div class="ql-code-block"> <script> </div> <div class="ql-code-block"> { </div> <div class="ql-code-block"> // age 只能在该代码块中被访问 </div> <div class="ql-code-block"> let age = 18; </div> <div class="ql-code-block"> console.log(age); // 正常 </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> </div> <div class="ql-code-block"> // 超出了 age 的作用域 </div> <div class="ql-code-block"> console.log(age) // 报错 </div> <div class="ql-code-block"> </div> <div class="ql-code-block"> let flag = true; </div> <div class="ql-code-block"> if(flag) { </div> <div class="ql-code-block"> // str 只能在该代码块中被访问 </div> <div class="ql-code-block"> let str = 'hello world!' </div> <div class="ql-code-block"> console.log(str); // 正常 </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> </div> <div class="ql-code-block"> // 超出了 age 的作用域 </div> <div class="ql-code-block"> console.log(str); // 报错 </div> <div class="ql-code-block"> </div> <div class="ql-code-block"> for(let t = 1; t <= 6; t++) { </div> <div class="ql-code-block"> // t 只能在该代码块中被访问 </div> <div class="ql-code-block"> console.log(t); // 正常 </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> </div> <div class="ql-code-block"> // 超出了 t 的作用域 </div> <div class="ql-code-block"> console.log(t); // 报错 </div> <div class="ql-code-block"> </script> </div> </div> <p><br></p> <p>JavaScript 中除了变量外还有常量,常量与变量本质的区别是【常量必须要有值且不允许被重新赋值】,常量值为对象时其属性和方法允许重新赋值。</p> <p><br></p> <div class="ql-code-block-container"> <div class="ql-code-block"> <script> </div> <div class="ql-code-block"> // 必须要有值 </div> <div class="ql-code-block"> const version = '1.0.0'; </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> // 不能重新赋值 </div> <div class="ql-code-block"> // version = '1.0.1'; </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> // 常量值为对象类型 </div> <div class="ql-code-block"> const user = { </div> <div class="ql-code-block"> name: '小明', </div> <div class="ql-code-block"> age: 18 </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> // 不能重新赋值 </div> <div class="ql-code-block"> user = {}; </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> // 属性和方法允许被修改 </div> <div class="ql-code-block"> user.name = '小小明'; </div> <div class="ql-code-block"> user.gender = '男'; </div> <div class="ql-code-block"> </script> </div> </div> <p><br></p> <p>总结:</p> <p><br></p> <ol> <li data-list="ordered"><span class="ql-ui"></span>let 声明的变量会产生块作用域,var 不会产生块作用域</li> <li data-list="ordered"><span class="ql-ui"></span>const 声明的常量也会产生块作用域</li> <li data-list="ordered"><span class="ql-ui"></span>不同代码块之间的变量无法互相访问</li> <li data-list="ordered"><span class="ql-ui"></span>推荐使用 let 或 const</li> </ol> <p><br></p> <p>注:开发中 let 和 const 经常不加区分的使用,如果担心某个值会不小被修改时,则只能使用 const 声明成常量。</p> <p><br></p> <p><br></p> <h3>全局作用域</h3> <p><br></p> <p><br></p> <p><script> 标签和 .js 文件的【最外层】就是所谓的全局作用域,在此声明的变量在函数内部也可以被访问。</p> <p><br></p> <div class="ql-code-block-container"> <div class="ql-code-block"> <script> </div> <div class="ql-code-block"> // 此处是全局 </div> <div class="ql-code-block"> </div> <div class="ql-code-block"> function sayHi() { </div> <div class="ql-code-block"> // 此处为局部 </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> // 此处为全局 </div> <div class="ql-code-block"> </script> </div> </div> <p><br></p> <p>全局作用域中声明的变量,任何其它作用域都可以被访问,如下代码所示:</p> <p><br></p> <div class="ql-code-block-container"> <div class="ql-code-block"> <script> </div> <div class="ql-code-block"> // 全局变量 name </div> <div class="ql-code-block"> const name = '小明' </div> <div class="ql-code-block"> </div> <div class="ql-code-block"> // 函数作用域中访问全局 </div> <div class="ql-code-block"> function sayHi() { </div> <div class="ql-code-block"> // 此处为局部 </div> <div class="ql-code-block"> console.log('你好' + name) </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> // 全局变量 flag 和 x </div> <div class="ql-code-block"> const flag = true </div> <div class="ql-code-block"> let x = 10 </div> <div class="ql-code-block"> </div> <div class="ql-code-block"> // 块作用域中访问全局 </div> <div class="ql-code-block"> if(flag) { </div> <div class="ql-code-block"> let y = 5 </div> <div class="ql-code-block"> console.log(x + y) // x 是全局的 </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> </script> </div> </div> <p><br></p> <p>总结:</p> <p><br></p> <ol> <li data-list="ordered"><span class="ql-ui"></span>为 window 对象动态添加的属性默认也是全局的,不推荐!</li> <li data-list="ordered"><span class="ql-ui"></span>函数中未使用任何关键字声明的变量为全局变量,不推荐!!!</li> <li data-list="ordered"><span class="ql-ui"></span>尽可能少的声明全局变量,防止全局变量被污染</li> </ol> <p><br></p> <p>JavaScript 中的作用域是程序被执行时的底层机制,了解这一机制有助于规范代码书写习惯,避免因作用域导致的语法错误。</p> <p><br></p> <p><br></p> <h3>作用域链</h3> <p><br></p> <p><br></p> <p>在解释什么是作用域链前先来看一段代码:</p> <p><br></p> <div class="ql-code-block-container"> <div class="ql-code-block"> <script> </div> <div class="ql-code-block"> // 全局作用域 </div> <div class="ql-code-block"> let a = 1 </div> <div class="ql-code-block"> let b = 2 </div> <div class="ql-code-block"> // 局部作用域 </div> <div class="ql-code-block"> function f() { </div> <div class="ql-code-block"> let c </div> <div class="ql-code-block"> // 局部作用域 </div> <div class="ql-code-block"> function g() { </div> <div class="ql-code-block"> let d = 'yo' </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> </script> </div> </div> <p><br></p> <p>函数内部允许创建新的函数,f 函数内部创建的新函数 g,会产生新的函数作用域,由此可知作用域产生了嵌套的关系。</p> <p><br></p> <p>如下图所示,父子关系的作用域关联在一起形成了链状的结构,作用域链的名字也由此而来。</p> <p><br></p> <p>作用域链本质上是底层的变量查找机制,在函数被执行时,会优先查找当前函数作用域中查找变量,如果当前作用域查找不到则会依次逐级查找父级作用域直到全局作用域,如下代码所示:</p> <p><br></p> <div class="ql-code-block-container"> <div class="ql-code-block"> <script> </div> <div class="ql-code-block"> // 全局作用域 </div> <div class="ql-code-block"> let a = 1 </div> <div class="ql-code-block"> let b = 2 </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> // 局部作用域 </div> <div class="ql-code-block"> function f() { </div> <div class="ql-code-block"> let c </div> <div class="ql-code-block"> // let a = 10; </div> <div class="ql-code-block"> console.log(a) // 1 或 10 </div> <div class="ql-code-block"> console.log(d) // 报错 </div> <div class="ql-code-block"> </div> <div class="ql-code-block"> // 局部作用域 </div> <div class="ql-code-block"> function g() { </div> <div class="ql-code-block"> let d = 'yo' </div> <div class="ql-code-block"> // let b = 20; </div> <div class="ql-code-block"> console.log(b) // 2 或 20 </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> </div> <div class="ql-code-block"> // 调用 g 函数 </div> <div class="ql-code-block"> g() </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> console.log(c) // 报错 </div> <div class="ql-code-block"> console.log(d) // 报错 </div> <div class="ql-code-block"> </div> <div class="ql-code-block"> f(); </div> <div class="ql-code-block"> </script> </div> </div> <p><br></p> <p>总结:</p> <p><br></p> <ol> <li data-list="ordered"><span class="ql-ui"></span>嵌套关系的作用域串联起来形成了作用域链</li> <li data-list="ordered"><span class="ql-ui"></span>相同作用域链中按着从小到大的规则查找变量</li> <li data-list="ordered"><span class="ql-ui"></span>子作用域能够访问父作用域,父级作用域无法访问子级作用域</li> </ol> <p><br></p> <p><br></p> <h3>闭包</h3> <p><br></p> <p><br></p> <p>闭包是一种比较特殊和函数,使用闭包能够访问函数作用域中的变量。从代码形式上看闭包是一个做为返回值的函数,如下代码所示:</p> <p><br></p> <div class="ql-code-block-container"> <div class="ql-code-block"> <body> </div> <div class="ql-code-block"> <script> </div> <div class="ql-code-block"> // 1. 闭包 : 内层函数 + 外层函数变量 </div> <div class="ql-code-block"> // function outer() { </div> <div class="ql-code-block"> // const a = 1 </div> <div class="ql-code-block"> // function f() { </div> <div class="ql-code-block"> // console.log(a) </div> <div class="ql-code-block"> // } </div> <div class="ql-code-block"> // f() </div> <div class="ql-code-block"> // } </div> <div class="ql-code-block"> // outer() </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> // 2. 闭包的应用: 实现数据的私有。统计函数的调用次数 </div> <div class="ql-code-block"> // let count = 1 </div> <div class="ql-code-block"> // function fn() { </div> <div class="ql-code-block"> // count++ </div> <div class="ql-code-block"> // console.log(`函数被调用${count}次`) </div> <div class="ql-code-block"> // } </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> // 3. 闭包的写法 统计函数的调用次数 </div> <div class="ql-code-block"> function outer() { </div> <div class="ql-code-block"> let count = 1 </div> <div class="ql-code-block"> function fn() { </div> <div class="ql-code-block"> count++ </div> <div class="ql-code-block"> console.log(`函数被调用${count}次`) </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> return fn </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> const re = outer() </div> <div class="ql-code-block"> // const re = function fn() { </div> <div class="ql-code-block"> // count++ </div> <div class="ql-code-block"> // console.log(`函数被调用${count}次`) </div> <div class="ql-code-block"> // } </div> <div class="ql-code-block"> re() </div> <div class="ql-code-block"> re() </div> <div class="ql-code-block"> // const fn = function() { } 函数表达式 </div> <div class="ql-code-block"> // 4. 闭包存在的问题: 可能会造成内存泄漏 </div> <div class="ql-code-block"> </script> </div> <div class="ql-code-block"> </body> </div> </div> <p><br></p> <p>总结:</p> <p><br></p> <p>1.怎么理解闭包?</p> <p><br></p> <ol> <li data-list="bullet"><span class="ql-ui"></span>闭包 = 内层函数 + 外层函数的变量</li> </ol> <p><br></p> <p>2.闭包的作用?</p> <p><br></p> <ol> <li data-list="bullet"><span class="ql-ui"></span>封闭数据,实现数据私有,外部也可以访问函数内部的变量</li> <li data-list="bullet"><span class="ql-ui"></span>闭包很有用,因为它允许将函数与其所操作的某些数据(环境)关联起来</li> </ol> <p><br></p> <p>3.闭包可能引起的问题?</p> <p><br></p> <ol> <li data-list="bullet"><span class="ql-ui"></span>内存泄漏</li> </ol> <p><br></p> <p><br></p> <h3>变量提升</h3> <p><br></p> <p><br></p> <p>变量提升是 JavaScript 中比较“奇怪”的现象,它允许在变量声明之前即被访问,</p> <p><br></p> <div class="ql-code-block-container"> <div class="ql-code-block"> <script> </div> <div class="ql-code-block"> // 访问变量 str </div> <div class="ql-code-block"> console.log(str + 'world!'); </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> // 声明变量 str </div> <div class="ql-code-block"> var str = 'hello '; </div> <div class="ql-code-block"> </script> </div> </div> <p><br></p> <p>总结:</p> <p><br></p> <ol> <li data-list="ordered"><span class="ql-ui"></span>变量在未声明即被访问时会报语法错误</li> <li data-list="ordered"><span class="ql-ui"></span>变量在声明之前即被访问,变量的值为 undefined</li> <li data-list="ordered"><span class="ql-ui"></span>let 声明的变量不存在变量提升,推荐使用 let</li> <li data-list="ordered"><span class="ql-ui"></span>变量提升出现在相同作用域当中</li> <li data-list="ordered"><span class="ql-ui"></span>实际开发中推荐先声明再访问变量</li> </ol> <p><br></p> <p>注:关于变量提升的原理分析会涉及较为复杂的词法分析等知识,而开发中使用 let 可以轻松规避变量的提升,因此在此不做过多的探讨,有兴趣可<a href="https://segmentfault.com/a/1190000013915935" target="_blank">查阅资料</a>。</p> <p><br></p> <p><br></p> <h2>函数</h2> <p><br></p> <p><br></p> <p><br></p> <p>知道函数参数默认值、动态参数、剩余参数的使用细节,提升函数应用的灵活度,知道箭头函数的语法及与普通函数的差异。</p> <p><br></p> <p><br></p> <p><br></p> <h3>函数提升</h3> <p><br></p> <p><br></p> <p>函数提升与变量提升比较类似,是指函数在声明之前即可被调用。</p> <p><br></p> <div class="ql-code-block-container"> <div class="ql-code-block"> <script> </div> <div class="ql-code-block"> // 调用函数 </div> <div class="ql-code-block"> foo() </div> <div class="ql-code-block"> // 声明函数 </div> <div class="ql-code-block"> function foo() { </div> <div class="ql-code-block"> console.log('声明之前即被调用...') </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> // 不存在提升现象 </div> <div class="ql-code-block"> bar() // 错误 </div> <div class="ql-code-block"> var bar = function () { </div> <div class="ql-code-block"> console.log('函数表达式不存在提升现象...') </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> </script> </div> </div> <p><br></p> <p>总结:</p> <p><br></p> <ol> <li data-list="ordered"><span class="ql-ui"></span>函数提升能够使函数的声明调用更灵活</li> <li data-list="ordered"><span class="ql-ui"></span>函数表达式不存在提升的现象</li> <li data-list="ordered"><span class="ql-ui"></span>函数提升出现在相同作用域当中</li> </ol> <p><br></p> <p><br></p> <h3>函数参数</h3> <p><br></p> <p><br></p> <p>函数参数的使用细节,能够提升函数应用的灵活度。</p> <p><br></p> <p><br></p> <h4>默认值</h4> <p><br></p> <p><br></p> <div class="ql-code-block-container"> <div class="ql-code-block"> <script> </div> <div class="ql-code-block"> // 设置参数默认值 </div> <div class="ql-code-block"> function sayHi(name="小明", age=18) { </div> <div class="ql-code-block"> document.write(`<p>大家好,我叫${name},我今年${age}岁了。</p>`); </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> // 调用函数 </div> <div class="ql-code-block"> sayHi(); </div> <div class="ql-code-block"> sayHi('小红'); </div> <div class="ql-code-block"> sayHi('小刚', 21); </div> <div class="ql-code-block"> </script> </div> </div> <p><br></p> <p>总结:</p> <p><br></p> <ol> <li data-list="ordered"><span class="ql-ui"></span>声明函数时为形参赋值即为参数的默认值</li> <li data-list="ordered"><span class="ql-ui"></span>如果参数未自定义默认值时,参数的默认值为 undefined</li> <li data-list="ordered"><span class="ql-ui"></span>调用函数时没有传入对应实参时,参数的默认值被当做实参传入</li> </ol> <p><br></p> <p><br></p> <h4>动态参数</h4> <p><br></p> <p><br></p> <p>arguments 是函数内部内置的伪数组变量,它包含了调用函数时传入的所有实参。</p> <p><br></p> <div class="ql-code-block-container"> <div class="ql-code-block"> <script> </div> <div class="ql-code-block"> // 求生函数,计算所有参数的和 </div> <div class="ql-code-block"> function sum() { </div> <div class="ql-code-block"> // console.log(arguments) </div> <div class="ql-code-block"> let s = 0 </div> <div class="ql-code-block"> for(let i = 0; i < arguments.length; i++) { </div> <div class="ql-code-block"> s += arguments[i] </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> console.log(s) </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> // 调用求和函数 </div> <div class="ql-code-block"> sum(5, 10)// 两个参数 </div> <div class="ql-code-block"> sum(1, 2, 4) // 两个参数 </div> <div class="ql-code-block"> </script> </div> </div> <p><br></p> <p>总结:</p> <p><br></p> <ol> <li data-list="ordered"><span class="ql-ui"></span>arguments 是一个伪数组</li> <li data-list="ordered"><span class="ql-ui"></span>arguments 的作用是动态获取函数的实参</li> </ol> <p><br></p> <p><br></p> <h4>剩余参数</h4> <p><br></p> <p><br></p> <div class="ql-code-block-container"> <div class="ql-code-block"> <script> </div> <div class="ql-code-block"> function config(baseURL, ...other) { </div> <div class="ql-code-block"> console.log(baseURL) // 得到 'http://baidu.com' </div> <div class="ql-code-block"> console.log(other) // other 得到 ['get', 'json'] </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> // 调用函数 </div> <div class="ql-code-block"> config('http://baidu.com', 'get', 'json'); </div> <div class="ql-code-block"> </script> </div> </div> <p><br></p> <p>总结:</p> <p><br></p> <ol> <li data-list="ordered"><span class="ql-ui"></span>... 是语法符号,置于最末函数形参之前,用于获取多余的实参</li> <li data-list="ordered"><span class="ql-ui"></span>借助 ... 获取的剩余实参,是个真数组</li> </ol> <p><br></p> <p><br></p> <h3>箭头函数</h3> <p><br></p> <p><br></p> <p>箭头函数是一种声明函数的简洁语法,它与普通函数并无本质的区别,差异性更多体现在语法格式上。</p> <p><br></p> <div class="ql-code-block-container"> <div class="ql-code-block"> <body> </div> <div class="ql-code-block"> <script> </div> <div class="ql-code-block"> // const fn = function () { </div> <div class="ql-code-block"> // console.log(123) </div> <div class="ql-code-block"> // } </div> <div class="ql-code-block"> // 1. 箭头函数 基本语法 </div> <div class="ql-code-block"> // const fn = () => { </div> <div class="ql-code-block"> // console.log(123) </div> <div class="ql-code-block"> // } </div> <div class="ql-code-block"> // fn() </div> <div class="ql-code-block"> // const fn = (x) => { </div> <div class="ql-code-block"> // console.log(x) </div> <div class="ql-code-block"> // } </div> <div class="ql-code-block"> // fn(1) </div> <div class="ql-code-block"> // 2. 只有一个形参的时候,可以省略小括号 </div> <div class="ql-code-block"> // const fn = x => { </div> <div class="ql-code-block"> // console.log(x) </div> <div class="ql-code-block"> // } </div> <div class="ql-code-block"> // fn(1) </div> <div class="ql-code-block"> // // 3. 只有一行代码的时候,我们可以省略大括号 </div> <div class="ql-code-block"> // const fn = x => console.log(x) </div> <div class="ql-code-block"> // fn(1) </div> <div class="ql-code-block"> // 4. 只有一行代码的时候,可以省略return </div> <div class="ql-code-block"> // const fn = x => x + x </div> <div class="ql-code-block"> // console.log(fn(1)) </div> <div class="ql-code-block"> // 5. 箭头函数可以直接返回一个对象 </div> <div class="ql-code-block"> // const fn = (uname) => ({ uname: uname }) </div> <div class="ql-code-block"> // console.log(fn('刘德华')) </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> </script> </div> <div class="ql-code-block"> </body> </div> </div> <p><br></p> <p>总结:</p> <p><br></p> <ol> <li data-list="ordered"><span class="ql-ui"></span>箭头函数属于表达式函数,因此不存在函数提升</li> <li data-list="ordered"><span class="ql-ui"></span>箭头函数只有一个参数时可以省略圆括号 ()</li> <li data-list="ordered"><span class="ql-ui"></span>箭头函数函数体只有一行代码时可以省略花括号 {},并自动做为返回值被返回</li> </ol> <p><br></p> <p><br></p> <h4>箭头函数参数</h4> <p><br></p> <p><br></p> <p>箭头函数中没有 arguments,只能使用 ... 动态获取实参</p> <p><br></p> <div class="ql-code-block-container"> <div class="ql-code-block"> <body> </div> <div class="ql-code-block"> <script> </div> <div class="ql-code-block"> // 1. 利用箭头函数来求和 </div> <div class="ql-code-block"> const getSum = (...arr) => { </div> <div class="ql-code-block"> let sum = 0 </div> <div class="ql-code-block"> for (let i = 0; i < arr.length; i++) { </div> <div class="ql-code-block"> sum += arr[i] </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> return sum </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> const result = getSum(2, 3, 4) </div> <div class="ql-code-block"> console.log(result) // 9 </div> <div class="ql-code-block"> </script> </div> </div> <p><br></p> <p><br></p> <h4>箭头函数 this</h4> <p><br></p> <p><br></p> <p>箭头函数不会创建自己的this,它只会从自己的作用域链的上一层沿用this。</p> <p><br></p> <div class="ql-code-block-container"> <div class="ql-code-block"> <script> </div> <div class="ql-code-block"> // 以前this的指向: 谁调用的这个函数,this 就指向谁 </div> <div class="ql-code-block"> // console.log(this) // window </div> <div class="ql-code-block"> // // 普通函数 </div> <div class="ql-code-block"> // function fn() { </div> <div class="ql-code-block"> // console.log(this) // window </div> <div class="ql-code-block"> // } </div> <div class="ql-code-block"> // window.fn() </div> <div class="ql-code-block"> // // 对象方法里面的this </div> <div class="ql-code-block"> // const obj = { </div> <div class="ql-code-block"> // name: 'andy', </div> <div class="ql-code-block"> // sayHi: function () { </div> <div class="ql-code-block"> // console.log(this) // obj </div> <div class="ql-code-block"> // } </div> <div class="ql-code-block"> // } </div> <div class="ql-code-block"> // obj.sayHi() </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> // 2. 箭头函数的this 是上一层作用域的this 指向 </div> <div class="ql-code-block"> // const fn = () => { </div> <div class="ql-code-block"> // console.log(this) // window </div> <div class="ql-code-block"> // } </div> <div class="ql-code-block"> // fn() </div> <div class="ql-code-block"> // 对象方法箭头函数 this </div> <div class="ql-code-block"> // const obj = { </div> <div class="ql-code-block"> // uname: 'pink老师', </div> <div class="ql-code-block"> // sayHi: () => { </div> <div class="ql-code-block"> // console.log(this) // this 指向谁? window </div> <div class="ql-code-block"> // } </div> <div class="ql-code-block"> // } </div> <div class="ql-code-block"> // obj.sayHi() </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> const obj = { </div> <div class="ql-code-block"> uname: 'pink老师', </div> <div class="ql-code-block"> sayHi: function () { </div> <div class="ql-code-block"> console.log(this) // obj </div> <div class="ql-code-block"> let i = 10 </div> <div class="ql-code-block"> const count = () => { </div> <div class="ql-code-block"> console.log(this) // obj </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> count() </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> obj.sayHi() </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> </script> </div> </div> <p><br></p> <p><br></p> <h2>解构赋值</h2> <p><br></p> <p><br></p> <p><br></p> <p>知道解构的语法及分类,使用解构简洁语法快速为变量赋值。</p> <p><br></p> <p><br></p> <p>解构赋值是一种快速为变量赋值的简洁语法,本质上仍然是为变量赋值,分为数组解构、对象解构两大类型。</p> <p><br></p> <p><br></p> <h3>数组解构</h3> <p><br></p> <p><br></p> <p>数组解构是将数组的单元值快速批量赋值给一系列变量的简洁语法,如下代码所示:</p> <p><br></p> <div class="ql-code-block-container"> <div class="ql-code-block"> <script> </div> <div class="ql-code-block"> // 普通的数组 </div> <div class="ql-code-block"> let arr = [1, 2, 3] </div> <div class="ql-code-block"> // 批量声明变量 a b c </div> <div class="ql-code-block"> // 同时将数组单元值 1 2 3 依次赋值给变量 a b c </div> <div class="ql-code-block"> let [a, b, c] = arr </div> <div class="ql-code-block"> console.log(a); // 1 </div> <div class="ql-code-block"> console.log(b); // 2 </div> <div class="ql-code-block"> console.log(c); // 3 </div> <div class="ql-code-block"> </script> </div> </div> <p><br></p> <p>总结:</p> <p><br></p> <ol> <li data-list="ordered"><span class="ql-ui"></span>赋值运算符 = 左侧的 [] 用于批量声明变量,右侧数组的单元值将被赋值给左侧的变量</li> <li data-list="ordered"><span class="ql-ui"></span>变量的顺序对应数组单元值的位置依次进行赋值操作</li> <li data-list="ordered"><span class="ql-ui"></span>变量的数量大于单元值数量时,多余的变量将被赋值为 undefined</li> <li data-list="ordered"><span class="ql-ui"></span>变量的数量小于单元值数量时,可以通过 ... 获取剩余单元值,但只能置于最末位</li> <li data-list="ordered"><span class="ql-ui"></span>允许初始化变量的默认值,且只有单元值为 undefined 时默认值才会生效</li> </ol> <p><br></p> <p>注:支持多维解构赋值,比较复杂后续有应用需求时再进一步分析</p> <p><br></p> <p><br></p> <h3>对象解构</h3> <p><br></p> <p><br></p> <p>对象解构是将对象属性和方法快速批量赋值给一系列变量的简洁语法,如下代码所示:</p> <p><br></p> <div class="ql-code-block-container"> <div class="ql-code-block"> <script> </div> <div class="ql-code-block"> // 普通对象 </div> <div class="ql-code-block"> const user = { </div> <div class="ql-code-block"> name: '小明', </div> <div class="ql-code-block"> age: 18 </div> <div class="ql-code-block"> }; </div> <div class="ql-code-block"> // 批量声明变量 name age </div> <div class="ql-code-block"> // 同时将数组单元值 小明 18 依次赋值给变量 name age </div> <div class="ql-code-block"> const {name, age} = user </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> console.log(name) // 小明 </div> <div class="ql-code-block"> console.log(age) // 18 </div> <div class="ql-code-block"> </script> </div> </div> <p><br></p> <p>总结:</p> <p><br></p> <ol> <li data-list="ordered"><span class="ql-ui"></span>赋值运算符 = 左侧的 {} 用于批量声明变量,右侧对象的属性值将被赋值给左侧的变量</li> <li data-list="ordered"><span class="ql-ui"></span>对象属性的值将被赋值给与属性名相同的变量</li> <li data-list="ordered"><span class="ql-ui"></span>对象中找不到与变量名一致的属性时变量值为 undefined</li> <li data-list="ordered"><span class="ql-ui"></span>允许初始化变量的默认值,属性不存在或单元值为 undefined 时默认值才会生效</li> </ol> <p><br></p> <p>注:支持多维解构赋值</p> <p><br></p> <div class="ql-code-block-container"> <div class="ql-code-block"> <body> </div> <div class="ql-code-block"> <script> </div> <div class="ql-code-block"> // 1. 这是后台传递过来的数据 </div> <div class="ql-code-block"> const msg = { </div> <div class="ql-code-block"> "code": 200, </div> <div class="ql-code-block"> "msg": "获取新闻列表成功", </div> <div class="ql-code-block"> "data": [ </div> <div class="ql-code-block"> { </div> <div class="ql-code-block"> "id": 1, </div> <div class="ql-code-block"> "title": "5G商用自己,三大运用商收入下降", </div> <div class="ql-code-block"> "count": 58 </div> <div class="ql-code-block"> }, </div> <div class="ql-code-block"> { </div> <div class="ql-code-block"> "id": 2, </div> <div class="ql-code-block"> "title": "国际媒体头条速览", </div> <div class="ql-code-block"> "count": 56 </div> <div class="ql-code-block"> }, </div> <div class="ql-code-block"> { </div> <div class="ql-code-block"> "id": 3, </div> <div class="ql-code-block"> "title": "乌克兰和俄罗斯持续冲突", </div> <div class="ql-code-block"> "count": 1669 </div> <div class="ql-code-block"> }, </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> ] </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> // 需求1: 请将以上msg对象 采用对象解构的方式 只选出 data 方面后面使用渲染页面 </div> <div class="ql-code-block"> // const { data } = msg </div> <div class="ql-code-block"> // console.log(data) </div> <div class="ql-code-block"> // 需求2: 上面msg是后台传递过来的数据,我们需要把data选出当做参数传递给 函数 </div> <div class="ql-code-block"> // const { data } = msg </div> <div class="ql-code-block"> // msg 虽然很多属性,但是我们利用解构只要 data值 </div> <div class="ql-code-block"> function render({ data }) { </div> <div class="ql-code-block"> // const { data } = arr </div> <div class="ql-code-block"> // 我们只要 data 数据 </div> <div class="ql-code-block"> // 内部处理 </div> <div class="ql-code-block"> console.log(data) </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> render(msg) </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> // 需求3, 为了防止msg里面的data名字混淆,要求渲染函数里面的数据名改为 myData </div> <div class="ql-code-block"> function render({ data: myData }) { </div> <div class="ql-code-block"> // 要求将 获取过来的 data数据 更名为 myData </div> <div class="ql-code-block"> // 内部处理 </div> <div class="ql-code-block"> console.log(myData) </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> } </div> <div class="ql-code-block"> render(msg) </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> </script> </div> </div> <p><br></p> <p><br></p> <h2>综合案例</h2> <p><br></p> <p><br></p> <p><br></p> <h3>forEach遍历数组</h3> <p><br></p> <p><br></p> <p>forEach() 方法用于调用数组的每个元素,并将元素传递给回调函数</p> <p><br></p> <p><br></p> <p>注意:</p> <p></p> <p>1.forEach 主要是遍历数组</p> <p></p> <p>2.参数当前数组元素是必须要写的, 索引号可选。</p> <p><br></p> <p><br></p> <div class="ql-code-block-container"> <div class="ql-code-block"> <body> </div> <div class="ql-code-block"> <script> </div> <div class="ql-code-block"> // forEach 就是遍历 加强版的for循环 适合于遍历数组对象 </div> <div class="ql-code-block"> const arr = ['red', 'green', 'pink'] </div> <div class="ql-code-block"> const result = arr.forEach(function (item, index) { </div> <div class="ql-code-block"> console.log(item) // 数组元素 red green pink </div> <div class="ql-code-block"> console.log(index) // 索引号 </div> <div class="ql-code-block"> }) </div> <div class="ql-code-block"> // console.log(result) </div> <div class="ql-code-block"> </script> </div> <div class="ql-code-block"> </body> </div> </div> <p><br></p> <p><br></p> <h3>filter筛选数组</h3> <p><br></p> <p><br></p> <p>filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素</p> <p><br></p> <p>主要使用场景: 筛选数组符合条件的元素,并返回筛选之后元素的新数组</p> <p><br></p> <div class="ql-code-block-container"> <div class="ql-code-block"> <body> </div> <div class="ql-code-block"> <script> </div> <div class="ql-code-block"> const arr = [10, 20, 30] </div> <div class="ql-code-block"> // const newArr = arr.filter(function (item, index) { </div> <div class="ql-code-block"> // // console.log(item) </div> <div class="ql-code-block"> // // console.log(index) </div> <div class="ql-code-block"> // return item >= 20 </div> <div class="ql-code-block"> // }) </div> <div class="ql-code-block"> // 返回的符合条件的新数组 </div> <div class="ql-code-block"><br> </div> <div class="ql-code-block"> const newArr = arr.filter(item => item >= 20) </div> <div class="ql-code-block"> console.log(newArr) </div> <div class="ql-code-block"> </script> </div> <div class="ql-code-block"> </body> </div> </div> <p><br></p> <p><br></p> </div> </body> </html>
#资源# #JavaScript# 分享 js高级手写知识点下 bat tmd职级对应 「610」https://www.aliyundrive.com/s/HD29RVJMZu9 点击链接保存,或者复制本段内容,打开「阿里云盘」APP ,无需下载极速在线查看,视频原画倍速播放。
#分享# #资源# #JavaScript# 「33个常用js函数封装」https://www.aliyundrive.com/s/KqPkpx2kzMm 点击链接保存,或者复制本段内容,打开「阿里云盘」APP ,无需下载极速在线查看,视频原画倍速播放。
#资源# 阅读 js红宝书 本书是 JavaScript 经典图书的新版。第 4 版涵盖 ECMAScript 2019,全面、深入地介绍了 JavaScript 开发者必须掌握的前端开发技术,涉及 JavaScript 的基础特性和高级特性。书中详尽讨论了 JavaScript 的各个方面,从 JavaScript 的起源开始,逐步讲解到新出现的技术,其中重点介绍 ECMAScript 和 DOM 标准。 在此基础上,接下来的各章揭示了 JavaScript 的基本概念,包括类、期约、迭代器、代理,等等。另外,书中深入探讨了客户端检测、事件、动画、表单、错误处理及 JSON。本书同时也介绍了近几年来涌现的重要新规范,包括 Fetch API、模块、工作者线程、服务线程以及大量新 API。
