01-JavaScript 高级进阶 第三天

1.今日目标

  1. 箭头函数(重点)

  2. instanceof 和 constructor

  3. es6 class 和 继承

  4. 闭包

2.箭头函数 重点

格式—定义语法

  1. // 箭头函数是匿名函数,一般做为参数传递
  2. // let test = function (a,b){
  3. // let sum = a + b
  4. // return sum
  5. // }
  6. // let test = (参数) => {函数体}
  7. // 几个小细节
  8. // 1.如果函数体只有一句,那么可以省略{},同时默认会返回函数体的结果,不能写return
  9. // 2.如果只有一个参数,那么可以省略()
  10. // 3.如果没有参数,()也不能省略
  11. // let test = (a,b) => a + b // 不能有大括号
  12. let test = a => a + 10
  13. let res = test(100)
  14. console.log(res)

特性

  1. // 箭头函数自己没有this
  2. // 箭头函数的this是确定的,况且永远不变
  3. // 箭头函数中的this指向 创建这个箭头函数所在对象 的上下文
  4. let obj = {
  5. name: 'jack',
  6. say: function () {
  7. return () => {
  8. console.log(this) // obj
  9. }
  10. }
  11. }
  12. let fn = obj.say()
  13. fn() // obj {name: "jack", say: ƒ}
  14. let newobj = {}
  15. newobj.fun = fn
  16. newobj.fun() // obj {name: "jack", say: ƒ}
  17. let rose = {
  18. name: 'rose'
  19. }
  20. fn.call(rose) // obj {name: "jack", say: ƒ} 无法改变

3.instanceof 和 constructor

判断一个实例是否属于某个构造函数

  1. // 构造函数
  2. function Person() {
  3. }
  4. const p1 = new Person();
  5. console.log(p1 instanceof Person);
  6. console.log(p1.__proto__.constructor === Person);

4.es6 class(重点)

es6的class 的出现 基本上可以替代了es5的构造函数和原型,使之代码结构上更加简洁。

关键字

  1. class
  2. 属性
  3. 方法
  4. 继承 extends
  5. 构造函数 constructor
  6. 方法重写 override:子类方法覆盖父类,super.父类方法()
  7. 父类的构造函数 super :子类有构造方法且使用this前,必须使用super()

完整代码体验

  1. class Person {
  2. // 构造方法
  3. constructor(name) {
  4. // 属性
  5. this.name = name;
  6. }
  7. // 方法
  8. say() {
  9. console.log(this.name);
  10. }
  11. }
  12. // 继承
  13. class Student extends Person{
  14. constructor(name,height){
  15. // console.log(this); // 语法错误:必须先调用super()才能使用this
  16. super(name);
  17. this.height=height;
  18. }
  19. }
  20. const s1=new Student("八神",180);
  21. s1.say(); // 八神
  22. class Saler extends Person{
  23. constructor(name,age){
  24. super(name);
  25. this.age = age;
  26. }
  27. // 覆盖(重写)
  28. say(){
  29. // 访问父类方法
  30. super.say(); // 马云
  31. console.log(this.age);
  32. }
  33. }
  34. const s2 = new Saler('马云',50);
  35. s2.say(); // 50

Tab栏切换

  1. <!DOCTYPE html>
  2. <html>
  3. <head lang="en">
  4. <meta charset="UTF-8">
  5. <title>tab栏切换</title>
  6. <style>
  7. * {
  8. margin: 0;
  9. padding: 0;
  10. }
  11. ul {
  12. list-style: none;
  13. }
  14. .box {
  15. width: 400px;
  16. height: 300px;
  17. border: 1px solid #ccc;
  18. margin: 100px auto;
  19. }
  20. .hd {
  21. height: 45px;
  22. }
  23. .hd span {
  24. display: inline-block;
  25. /*将行内元素转换成行内块元素,宽高才起作用*/
  26. width: 90px;
  27. background-color: pink;
  28. line-height: 45px;
  29. text-align: center;
  30. cursor: pointer;
  31. }
  32. .hd span.current {
  33. /*交集选择器,标签指定式选择器*/
  34. background-color: purple;
  35. /*紫色*/
  36. }
  37. .bd li {
  38. height: 255px;
  39. background-color: purple;
  40. display: none;
  41. /*设置隐藏*/
  42. }
  43. .bd li.current {
  44. display: block;
  45. /*显示*/
  46. }
  47. </style>
  48. <script src="js/TabExchange.js"></script>
  49. </head>
  50. <body>
  51. <div class="box" id="box">
  52. <div class="hd">
  53. <span class="current">体育</span>
  54. <span>娱乐</span>
  55. <span>新闻</span>
  56. <span>综合</span>
  57. </div>
  58. <div class="bd">
  59. <ul id="list">
  60. <li class="current">我是体育模块</li>
  61. <li>我的娱乐模块</li>
  62. <li id="li3">我是新闻模块</li>
  63. <li>我是综合模块</li>
  64. </ul>
  65. </div>
  66. </div>
  67. <script>
  68. let tab = new TabExchange('box', 'current');
  69. console.dir(tab);
  70. </script>
  71. </body>
  72. </html>
  1. class TabExchange {
  2. // 构造函数
  3. constructor(id, className) {
  4. // 获取id对应的元素:规范,属于最外层
  5. this.id = document.querySelector(`#${id}`)
  6. // 规定内部有两层解构:div>span
  7. this.hd = this.id.querySelectorAll('div>span')
  8. // 规范内部有两层解构:div>ul>li
  9. this.bd = this.id.querySelectorAll('div>ul>li')
  10. // 保存当前要处理的样式类
  11. this.style = className;
  12. // 调用自己的tabClick 方法处理点击事件
  13. this.tabClick();
  14. }
  15. // 绑定点击事件
  16. tabClick() {
  17. // 因为接下来要绑定事件,事件里面也会出现this,所以先定义变量that来保存当前TabExchange对象的this
  18. let that = this
  19. // 循环遍历,绑定事件,并进行事件处理
  20. this.hd.forEach(function (item, key) {
  21. // item就是span,key就是span的下标
  22. item.addEventListener('click', function () {
  23. // 排他:清空hd全部样式
  24. that.hd.forEach(function (item1) {
  25. item1.classList.remove(that.style)
  26. })
  27. // 清空bd的所有样式
  28. that.bd.forEach(function (item2) {
  29. item2.classList.remove(that.style)
  30. })
  31. // 给当前事件元素添加样式
  32. that.hd[key].classList.add(that.style)
  33. that.bd[key].classList.add(that.style)
  34. })
  35. })
  36. }
  37. }

元素创建继承

  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>Document</title>
  7. </head>
  8. <style>
  9. .element {
  10. width: 200px;
  11. height: 200px;
  12. border-radius: 50%;
  13. border: 10px solid #00ffff;
  14. text-align: center;
  15. font-size: 30px;
  16. line-height: 200px;
  17. overflow: hidden;
  18. float: left;
  19. }
  20. </style>
  21. <body>
  22. <script>
  23. // 创建一个类:可以创建普通元素,并且可以实现将元素挂到指定父元素下
  24. class CreateElement {
  25. // 构造函数,传入标签名,文本内容,和元素默认类名
  26. constructor(element, text, className = 'element') {
  27. // 1.创建元素
  28. const node = document.createElement(element)
  29. // 2.添加类名
  30. node.classList.add(className)
  31. // 3.添加文本内容(双标签有效,单标签无效)
  32. node.innerText = text
  33. // 4.将创建的元素节点存入到属性node
  34. this.node = node
  35. }
  36. // 将当前创建的元素 添加到指定父元素下
  37. appendTo(selector) {
  38. // 获取父元素
  39. const parent = document.querySelector(selector)
  40. // 添加子元素
  41. parent.appendChild(this.node)
  42. }
  43. }
  44. // 直接创建一个普通元素
  45. const div = new CreateElement('div', '做人开心就好')
  46. div.appendTo('body')
  47. // 图片标签不适用于普通元素创建(有属性src),但是想使用默认的样式和创建过程
  48. // 创建子类 继承 父类
  49. class CreateImg extends CreateElement {
  50. // 自己的构造函数:只需要传入图片
  51. constructor(src, className = 'element') {
  52. // 父类构造函数
  53. super('img', '', className)
  54. // 给创建的元素增加src属性
  55. this.node.src = src
  56. }
  57. }
  58. // 改变了创建的内容,但是可以直接应用父类继承的方法
  59. const img = new CreateImg('images/02.jpg')
  60. img.appendTo('body')
  61. </script>
  62. </body>
  63. </html>

5.闭包

概念

计算机科学中,闭包(英语:Closure),又称词法闭包(Lexical Closure)或函数闭包(function closures),只要出现引用了外部变量的函数,那么这个现象就叫做闭包

作用

  1. 让数据变得更加的安全
  2. 优化代码
  3. 函数内返回了另外一个函数

使用闭包前

  1. <body>
  2. <button>自增</button>
  3. <h1></h1>
  4. <script>
  5. const btn = document.querySelector("button");
  6. const h1 = document.querySelector("h1");
  7. let num = 0;
  8. let arr = [{ name: "金" }, { name: "木" }, { name: "水" }, { name: "火" }, { name: "土" }];
  9. h1.innerText = arr[num].name;
  10. btn.onclick = function () {
  11. num++;
  12. if (num >= arr.length) {
  13. num = 0;
  14. }
  15. h1.innerText = arr[num].name;
  16. }
  17. </script>
  18. </body>

使用闭包后

  1. <body>
  2. <button>自增</button>
  3. <h1></h1>
  4. <script>
  5. const btn = document.querySelector("button");
  6. const h1 = document.querySelector("h1");
  7. function setElements() {
  8. let num = -1;
  9. let arr = [{ name: "金" }, { name: "木" }, { name: "水" }, { name: "火" }, { name: "土" }];
  10. return function () {
  11. num++;
  12. if (num >= arr.length) {
  13. num = 0;
  14. }
  15. return arr[num].name;
  16. }
  17. }
  18. const getElement=setElements();
  19. h1.innerText = getElement();
  20. btn.onclick = function () {
  21. h1.innerText = getElement();
  22. }
  23. </script>
  24. </body>