北仑网站建设网站,汝州网站制作,wordpress用户名密码加密方式,南昌那个公司做网站好「写在前面」 本文为 b 站黑马程序员 pink 老师 JavaScript 教程的学习笔记。本着自己学习、分享他人的态度#xff0c;分享学习笔记#xff0c;希望能对大家有所帮助。推荐先按顺序阅读往期内容#xff1a; 1. JavaScript 学习笔记#xff08;Day1#xff09; 2. JavaSc… 「写在前面」 本文为 b 站黑马程序员 pink 老师 JavaScript 教程的学习笔记。本着自己学习、分享他人的态度分享学习笔记希望能对大家有所帮助。推荐先按顺序阅读往期内容 1. JavaScript 学习笔记Day1 2. JavaScript 学习笔记Day2 3. JavaScript 学习笔记Day3 4. JavaScript 学习笔记Day4 5. JavaScript 学习笔记Day5 6. JavaScript 学习笔记WEB APIs Day1 7. JavaScript 学习笔记WEB APIs Day2 8. JavaScript 学习笔记WEB APIs Day3 9. JavaScript 学习笔记WEB APIs Day4 10. JavaScript 学习笔记WEB APIs Day5 11. JavaScript 学习笔记WEB APIs Day6 目录 1 作用域 2 函数进阶 3 解构赋值 4 综合案例 JavaScript进阶阶段安排: P152https://www.bilibili.com/video/BV1Y84y1L7Nn?p152 1 作用域 1.1 局部作用域 P153https://www.bilibili.com/video/BV1Y84y1L7Nn?p153 作用域scope规定了变量能够被访问的“范围”离开了这个“范围”变量便不能被访问 作用域分为 局部作用域 全局作用域 局部作用域分为函数作用域和块作用域。 1. 函数作用域 在函数内部声明的变量只能在函数内部被访问外部无法直接访问。 script function getSum() { // 函数内部是函数作用域属于局部变量 const num 10 } console.log(num) // 此处报错函数外部不能使用局部作用域变量/script 总结 函数内部声明的变量在函数外部无法被访问 函数的参数也是函数内部的局部变量 不同函数内部声明的变量无法互相访问 函数执行完毕后函数内部的变量实际被清空了 2. 块作用域 在 JavaScript 中使用 { } 包裹的代码称为代码块代码块内部声明的变量外部将【有可能】无法被访问。 for ( let t 1; t 6; t) { // t 只能在该代码块中被访问 console.log(t) // 正常}// 超出了 t 的作用域console.log(t) // 报错 总结 let 声明的变量会产生块作用域var 不会产生块作用域 const 声明的常量也会产生块作用域 不同代码块之间的变量无法互相访问 推荐使用 let 或 const 1.2 全局作用域 script 标签 和 .js 文件 的最外层就是所谓的全局作用域在此声明的变量在函数内部也可以被访问。 全局作用域中声明的变量任何其它作用域都可以被访问 script // 全局作用域下声明了num变量 const num 10 function fn() { // 函数内部可以使用全局作用域的变量 console.log(num) }/script 注意 为 window 对象动态添加的属性默认也是全局的不推荐 函数中未使用任何关键字声明的变量为全局变量不推荐 尽可能少的声明全局变量防止全局变量被污染 1.3 作用域链 作用域链本质上是底层的变量查找机制。 在函数被执行时会 优先查找当前函数作用域中查找变量 如果当前作用域查找不到则会依次 逐级查找父级作用域直到全局作用域 总结 嵌套关系的作用域串联起来形成了作用域链 相同作用域链中按着从小到大的规则查找变量 子作用域能够访问父作用域父级作用域无法访问子级作用域 1.4 JS垃圾回收机制 P154https://www.bilibili.com/video/BV1Y84y1L7Nn?p154 1. 什么是垃圾回收机制 垃圾回收机制(Garbage Collection) 简称 GCJS中内存的分配和回收都是自动完成的内存在不使用的时候会被垃圾回收器自动回收。 2.内存的生命周期 JS环境中分配的内存, 一般有如下生命周期 内存分配当我们声明变量、函数、对象的时候系统会自动为他们分配内存 内存使用即读写内存也就是使用变量、函数等 内存回收使用完毕由 垃圾回收器自动回收不再使用的内存 说明 全局变量一般不会回收(关闭页面回收) 一般情况下 局部变量的值, 不用了, 会被 自动回收掉 内存泄漏程序中分配的内存由于某种原因程序未释放或无法释放叫做内存泄漏 堆栈空间分配区别 栈操作系统: 由 操作系统自动分配释放函数的参数值、局部变量等基本数据类型放到栈里面。 堆操作系统: 一般由程序员分配释放若程序员不释放由 垃圾回收机制回收。 复杂数据类型放到堆里面。 两种常见的浏览器垃圾回收算法: 引用计数法 标记清除法 现代浏览器通用的大多是基于标记清除算法的某些改进算法 核心 标记清除算法将“不再使用的对象”定义为“ 无法达到的对象”。 就是从 根部在JS中就是全局对象出发定时扫描内存中的对象。 凡是能从 根部到达的对象都是还 需要使用的。 那些 无法由根部出发触及到的 对象被标记为不再使用稍后进行 回收。 1.5 闭包 P155https://www.bilibili.com/video/BV1Y84y1L7Nn?p155 闭包概念一个函数对周围状态的引用捆绑在一起内层函数中访问到其外层函数的作用域 简单理解闭包 内层函数 外层函数的变量 闭包作用封闭数据提供操作外部也可以访问函数内部的变量 闭包的基本格式: function outer() { let i 1 function fn() { console.log(i) } return fn}const fun outer()fun() // 1// 外层函数使用内部函数的变量 // 简约写法function outer() { let i 1 return function () { console.log(i) }}const fun outer()fun() // 调用fun 1// 外层函数使用内部函数的变量 闭包应用实现数据的私有 比如我们要做个统计函数调用次数函数调用一次就 let count 1function fn() { count console.log(函数被调用${count}次)}fn() // 2fn() // 3 但是这个count 是个全局变量很容易被修改 function fn() { let count 1 function fun() { count console.log(函数被调用${count}次) } return fun}const result fn()result() // 2result() // 3 这样实现了数据私有无法直接修改 count 1.6 变量提升 P156https://www.bilibili.com/video/BV1Y84y1L7Nn?p156 变量提升是 JavaScript 中比较“奇怪”的现象它允许在变量声明之前即被访问仅存在于var声明变量 console.log(str world!) // undefined world!var str hello 注意 变量在未声明即被访问时会报语法错误 变量在var声明之前即被访问变量的值为 undefined let/const 声明的变量不存在变量提升 变量提升出现在相同作用域当中 实际开发中推荐先声明再访问变量 2 函数进阶 2.1 函数提升 函数提升与变量提升比较类似是指函数在声明之前即可被调用。 // 1.会把所有函数声明提升到当前作用域的最前面fn() // 函数能调用 function fn() { console.Log(函数提升)}// 2. 函数表达式不存在提升的现象fun() // 报错var fun function () { console.log(函数表达式)} 总结 函数提升能够使函数的声明调用更灵活 函数表达式不存在提升的现象 函数提升出现在相同作用域当中 2.2 函数参数 P157https://www.bilibili.com/video/BV1Y84y1L7Nn?p157 1. 动态参数 arguments 是函数内部内置的伪数组变量它包含了调用函数时传入的所有实参 function getSum() { // arguments 动态参数,只存在于函数里面,是伪数组 let sum 0 for (let i 0; i arguments.length; i){ sum arguments[i] } console.log(sum)}getSum(1,2) // 3getSum(1,2,3) // 6 2. 剩余参数 ... 是语法符号置于最末函数形参之前用于获取 多余的实参 借助 ... 获取的剩余实参是个 真数组 function getSum(a, b, ...arr) { console.log(arr)}getSum(2, 3) // []getSum(1, 2, 3, 4, 5) // [3, 4, 5] 开发中还是提倡多使用剩余参数。 3.展开运算符 展开运算符(…),将一个数组进行展开不会修改原数组 典型运用场景 求数组最大值(最小值)、合并数组等 const arr [1, 2, 3]// 展开运算符可以展开数组console.log(...arr) // 1 2 3// 1. 求数组最大值// 数组没办法用max()需要用...展开console.Log(Math.max(1,2,3)) // 3console.log(Math.max(...arr)) // 3console.log(Math.min(...arr)) // 1// 2. 合并数组const arr1 [1, 2, 3]const arr2 [3, 4, 5]const arr [...arr1, ...arr2]console.log(arr) // [1, 2, 3, 4, 5] 2.3 箭头函数 P158https://www.bilibili.com/video/BV1Y84y1L7Nn?p158 1. 基本语法 语法1基本写法 // 普通函数const fn function () { console.log(我是普通函数)}fn() // 箭头函数const fn () { console.log(我是箭头函数)} 语法2只有一个参数可以省略小括号 // 普通函数const fn function (x) { return x x}console.log(fn(1)) // 2 // 箭头函数const fn x { return x x}console.log(fn(1)) // 2 语法3如果函数体只有一行代码可以写到一行上并且无需写 return 直接返回值 // 普通函数const fn function (x, y) { return x y}console.log(fn(1, 2)) // 3 // 箭头函数const fn (x, y) x yconsole.log(fn(1, 2)) // 3 // 更简洁的语法const form document.queryselector(form)form.addEventListener(click, ev ev.preventDefault()) 语法4加括号的函数体返回对象字面量表达式 const fn1 uname ({ uname: uname })console.log(fn1(pink老师)) // {uname: pink老师} 2.箭头函数参数 普通函数有arguments 动态参数 箭头函数没有 arguments 动态参数但是有剩余参数 ...args const getSum (...args) { let sum 0 for (let i 0; i args.length; i) { sum args[i] } return sum // 注意函数体有多行代码需要return}console.log(getSum(1, 2, 3)) // 6 3.箭头函数 this 普通函数根据它是被 如何调用的来定义这个函数的this值 箭头函数 不会创建自己的this,它只会从自己的作用域链的 上一层沿用this。 // 普通函数console.log(this) // 此处为 windowconst sayHi function () { console.log(this) // 普通函数指向调用者,此处为 window}btn.addEventListener(click, function () { console.log(this) // 当前 this 指向 btn}) // 箭头函数console.log(this) // 此处为window// 箭头函数const sayHi () { console.log(this) // 箭头函数此处为window}btn.addEventListener(click, () { console.log(this) // 当前this指向window}) 在开发中【使用箭头函数前需要考虑函数中 this 的值】事件回调函数使用箭头函数时this 为全局的 window因此DOM事件回调函数为了简便还是不太推荐使用箭头函数 // DOM 节点const btn document.queryselector(.btn)// 箭头函数此时 this 指向了 windowbtn.addEventListener(click, () { console.log(this)})// 普通函数此时 this 指向了 DOM 对象btn.addEventListener(click, function () { console.log(this)}) 3 解构赋值 3.1 数组解构 P159https://www.bilibili.com/video/BV1Y84y1L7Nn?p159 数组解构是将数组的单元值快速批量赋值给一系列变量的简洁语法 基本语法 赋值运算符 左侧的 [] 用于批量声明变量右侧数组的单元值将被赋值给左侧的变量 变量的顺序对应数组单元值的位置依次进行赋值操作 // 普通的数组const arr [1, 2, 3]// 批量声明变量 a b c// 同时将数组单元值 1 2 3 依次赋值给变量 a b cconst [a, b, c] arrconsole.log(a) // 1console.log(b) // 2console.log(c) // 3 典型应用交换2个变量 let a 1let b 3; // 这里必须有分号[b, a] [a, b]console.log(a) // 3console.log(b) // 1 js 前面必须加分号情况 // 1. 立即执行函数要加(function () {})();(function () {})();// 2. 使用数组的时候const str pink;[1, 2, 3].map(function (item) { console.log(item)}) 1.变量多单元值少的情况 变量的数量大于单元值数量时多余的变量将被赋值为 undefined // 变量多单元值少const [a, b, c, d] [小米, 苹果, 华为]console.log(a) // 小米console.log(b) // 苹果console.log(c) // 华为console.log(d) // undefined 2. 变量少单元值多的情况 // 变量少单元值多const [a, b, c] [小米, 苹果, 华为, 格力]console.log(a) // 小米console.log(b) // 苹果console.log(c) // 华为 3.利用剩余参数解决变量少单元值多的情况 剩余参数返回的还是一个数组 // 利用剩余参数解决变量少单元值多的情况const [a, b, ...tel] [小米, 苹果, 华为, 格力, vivo]console.log(a) // 小米console.log(b) // 苹果console.log(tel) // [华为, 格力, vivo] 4. 防止有undefined传递单元值的情况可以设置默认值 允许初始化变量的默认值且只有单元值为 undefined 时默认值才会生效 const [a 手机, b 华为] [小米]console.log(a) // 小米console.log(b) // 华为 5. 按需导入忽略某些返回值 // 按需导入忽略某些值const [a, , c, d] [小米, 苹果, 华为格力]console.log(a) // 小米console.log(c) // 华为console.log(d) // 格力 6. 支持多维数组的结构 const [a, b] [苹果, [小米, 华为]]console.log(a) // 苹果console.log(b) // [小米, 华为]// 想要拿到小米和华为怎么办?const [a, [b,c]] [苹果, [小米, 华为]]console.log(a) // 苹果console.log(b) // 小米console.log(c) // 华为 3.2 对象解构 P160https://www.bilibili.com/video/BV1Y84y1L7Nn?p160 对象解构是将对象属性和方法快速批量赋值给一系列变量的简洁语法 1. 基本语法 赋值运算符 左侧的 {} 用于批量声明变量右侧对象的属性值将被赋值给左侧的变量 对象属性的值将被赋值给与属性名 相同的变量 注意解构的变量名不要和外面的变量名冲突否则报错 4.对象中找不到与变量名一致的属性时变量值为 undefined // 普通对象const user { name: 小明, age: 18};// 批量声明变量 name age// 同时将数组单元值 小明 18 依次赋值给变量 name ageconst {name, age} userconsole.log(name) // 小明console.log(age) // 18 2.给新的变量名赋值 可以从一个对象中提取变量并同时修改新的变量名 // 普通对象const user { name: 小明, age: 18};// 把原来的 name 变量重新命名为 unameconst { name: uname, age } userconsole.log(uname) // 小明console.log(age) // 18 冒号表示“什么值赋值给谁” 3. 数组对象解构 const pig [ { name: 佩奇, age: 6 }]const [{ name, age }] pigconsole.log(name) // 佩奇console.log(age) // 6 4.多级对象解构 // 依次打印家庭成员const pig { name: 佩奇, family: { mother: 猪妈妈, father: 猪爸爸, sister: 乔治 }, age: 6}const { name, family: { motherfather, sister } } pigconsole.log(name) // 佩奇console.log(mother) // 猪妈妈console.log(father) // 猪爸爸console.log(sister) // 乔治 const people [ { name: 佩奇, family: { mother: 猪妈妈, father: 猪爸爸, sister: 乔治 }, age: 6 }]const [{ name, family: { mother, father, sister }}] peopleconsole.log(name) // 佩奇console.log(mother) // 猪妈妈console.log(father) // 猪爸爸console.log(sister) // 乔治 遍历数组 forEach 方法 P161https://www.bilibili.com/video/BV1Y84y1L7Nn?p161 forEach() 方法用于调用数组的每个元素并将元素传递给回调函数 语法 被遍历的数组.forEach(function (当前数组元素当前元素索引号){ // 函数体}) 注意 forEach 主要是遍历数组 参数 当前数组元素是必须要写的 索引号可选。 例 const arr [red , green, pink]arr.forEach(function (item,index) { console.log(item) // 数组元素 red green pink console.log(index) // 索引号 0 1 2) 筛选数组 filter 方法 filter() 方法创建一个新的数组新数组中的元素是通过检查指定数组中符合条件的所有元素 主要使用场景 筛选数组符合条件的元素并返回筛选之后元素的新数组 语法 被遍历的数组.filter(function (currentValue, index) { return 筛选条件}) 例 // 筛选数组中大于30的元素const score [10, 50, 3, 40, 33]const re score.filter(function (item) { return item 30})console.log(re) // [50, 40, 33] 返回值返回数组包含了符合条件的所有元素。如果没有符合条件的元素则返回空数组 参数currentValue 必须写 index 可选 因为返回新数组所以不会影响原数组 4 综合案例 P162https://www.bilibili.com/video/BV1Y84y1L7Nn?p162 P163https://www.bilibili.com/video/BV1Y84y1L7Nn?p163 「结束」 本文由 mdnice 多平台发布