箭头函数

理解:一种简洁的函数简写
重点
()=>{
}

  1. <script>
  2. //普通函数--匿名
  3. let func = function () {
  4. console.log("456")
  5. }
  6. func()
  7. //🔥箭头函数 简写 更简单 简洁
  8. //🎃箭头不能拆开
  9. let fun = () => {
  10. console.log('123')
  11. }
  12. fun()
  13. //🌈传递参数个数是一个时,小括号才可以被省略;其他都不行
  14. //传递参数为0个,小括号不能省略
  15. let fun1 = (a) => {
  16. console.log(a)
  17. }
  18. fun1(12)
  19. let fun3 = a => {
  20. console.log(a)
  21. }
  22. fun3(2)
  23. let fun2 = (a, b) => {
  24. console.log(a, b)
  25. }
  26. fun2(7, 8)
  27. // let fun4 = => {
  28. // console.log(c)
  29. // }
  30. // fun4() 报错
  31. //💥当箭头函数,函数体中只有一行代码的时候:
  32. //1. 大括号可以省略;其他不行
  33. //2. 默认返回 这行代码的运行结果🔥 (默认添加return)
  34. let func4 = () => { console.log('098') }
  35. func4()
  36. let fun4 = () => console.log('098')
  37. fun4()
  38. //console.log()没有返回值,是undefined
  39. let fun5 = () => { console.log('110') }
  40. let fun6 = () => fun5()
  41. console.log(fun6()) //结果显示 undefined
  42. let fun7 = () => 110
  43. let fun8 = () => fun7()
  44. let result = fun8()
  45. console.log(result) //结果显示110
  46. //🌈箭头函数 🔥返回类型
  47. let fun9 = () => 11; //返回值类型 数字 11
  48. console.log(fun9())
  49. let fun10 = () => "11"; //返回值类型 字符串 11
  50. console.log(fun10())
  51. let fun11 = () => [11, 10]; //返回值类型 数组 [11,10]
  52. console.log(fun11())
  53. 🎃let fun12 = () => { }; //返回值类型 undefined
  54. console.log(fun12())
  55. //因为JS中 {} 意思不同
  56. //两种意思:
  57. // 大括号 对象 符号 返回类型对象
  58. // 大括号 在函数内 包含==函数体==结构 符号 undefined 浏览器解析正解
  59. //想要实现函数体 返回对象类型 🌈要加小括号
  60. let func1 = () => ({ a: 1 })
  61. console.log(func1()) //返回值 { a: 1 } 类型:对象
  62. </script>

解构

释义:获取数据的简写

可对复杂数据类型:数组,对象,函数(形参)简写

  1. <script>
  2. //高级写法
  3. //查数组💥
  4. const arr = ['a', 'b', 'c']
  5. // const [str0,str1,str3] = arr
  6. // console.log(str0,str1,str3) //结果 a b c
  7. const [str1, str3] = arr //不是下标,[]里面变量任意命名,
  8. //---------------------------按数组顺序查出
  9. console.log(str1, str3) //结果 a b
  10. //交换变量🔥
  11. //传统 :两值交换 ,需要设置第三值 来交换
  12. //高级:
  13. let a = 100
  14. let b = 200; //加分号 ,否则会报错
  15. [a, b] = [b, a]
  16. console.log(a, b)
  17. //对象解构🎃
  18. const obj = {
  19. name: "金角",
  20. height: 180
  21. }
  22. const { name, height } = obj; //获取属性
  23. console.log(name, height) //得到属性值
  24. //函数 形参
  25. function fun1({ username }) {
  26. console.log(username)
  27. }
  28. fun1({ username: '银角' })
  29. </script>

简写

  1. <script>
  2. //对象简写🔥 常用
  3. const username = '迪克'
  4. const obj2 = {
  5. username, /🔥/username=uaername 简写username
  6. // 对象体 内 --函数简写
  7. say() {
  8. console.log("我是大魔王")
  9. } //函数这样写在外面会报错
  10. };
  11. console.log(username);//==访问的是 obj2里面的username
  12. console.log(obj2.username);
  13. // 普通写法
  14. function sing() {
  15. console.log('我是小仙女')
  16. }
  17. sing();
  18. // function show(a) {
  19. // // if判断
  20. // //三元
  21. // a === undefined ? console.log('你好') : console.log('你很好')
  22. // }
  23. //突然感觉 赋传值很强大
  24. function show(aa = "你好") { //默认值 你好
  25. console.log(aa)
  26. }
  27. show();//你好
  28. show("你很好")//你很好
  29. </script>

… 运算符

通过 ...符号来获取剩下的参数

剩余运算符

  1. <script>
  2. //剩余运算符 ...
  3. /*对象🚀*/
  4. const obj = { a: 1 }
  5. const { a, ...b } = obj //a取a的值,b取除a以外的值
  6. console.log(a) // 1
  7. console.log(b) // 没有剩余的值,返回是空对象
  8. //有值的话,返回的是带属性值的对象
  9. // 数组同上
  10. /*函数🍄 获取的 都是数组 */
  11. function calc(...arr) {
  12. console.log(arr) //返回值数组 [1,2]
  13. }
  14. calc(1, 2)
  15. /* ...单独放,或者放后面*/
  16. </script>

拓展、延展、展开运算符

  1. //复杂类型传的是地址🎃
  2. //... 是复制数据值
  3. const list = [1, 2, 3, 4, 5, 6]
  4. const newList = [...list] //复制数据
  5. newList.push(7, 8)
  6. console.log(list)
  7. console.log(newList)
  8. const obj1 = {
  9. name: "大圣",
  10. age: 180
  11. }
  12. //对象
  13. // const obj2 = obj1
  14. // obj2.height = "5000px"
  15. // console.log(obj1)
  16. // console.log(obj2) //obj1和obj2值一样
  17. const obj2 = { ...obj1 }
  18. obj2.height = 5000
  19. console.log(obj1)
  20. console.log(obj2)//obj1和obj2值不同
  21. //数组合并
  22. const list1 = [1, 2, 3]
  23. const list2 = [4, 5, 6]
  24. const list3 = [...list1, ...list2]
  25. //对象-----注意:合并中
  26. // 🌸🍁相同的属性名只能有一个,否则后面同名会覆盖前面的属性名
  27. const obj3 = {
  28. name: '八戒',
  29. age: 200
  30. }
  31. const obj4 = {
  32. name: '悟空',
  33. height: 800
  34. }
  35. const obj6 = { ...obj3, ...obj4 }
  36. console.log(obj6)
  37. //{name: '悟空', age: 200, height: 800} 同名name属性被覆盖掉了

数组方法

方法 描述
every() 检测数值元素的每个元素是否都符合条件。
filter() 检测数值元素,并返回符合条件所有元素的数组。
find() 返回符合传入测试(函数)条件的数组元素。
findIndex() 返回符合传入测试(函数)条件的数组元素索引。
forEach() 数组每个元素都执行一次回调函数。
includes() 判断一个数组是否包含一个指定的值。
indexOf() 搜索数组中的元素,并返回它所在的位置。
isArray() 判断对象是否为数组。
join() 把数组的所有元素放入一个字符串。
map() 通过指定函数处理数组的每个元素,并返回处理后的数组。
reduce() 将数组元素计算为一个值(从左到右)。
reverse() 反转数组的元素顺序。
some() 检测数组元素中是否有元素符合指定条件。
sort() 对数组的元素进行排序。

forEach()

遍历数组元素,两个值:值,下标

  1. /* forEach 遍历 和for 遍历 功能很相似
  2. forEach 遍历数组,接收一个回调函数;并且会在每一次遍历被使用
  3. 2.回调函数 会接收两个参数
  4. 1. 参数 被循环的元素
  5. 2. 参数 被循环的元素的下标 索引
  6. 3. 回调函数 修改为箭头函数 简洁
  7. 4. for循环 可以被break打断 被终止
  8. break 不能打断forEach或终止
  9. */
  10. const arr = ['a', 'b', 'c', 'd']
  11. arr.forEach((item, index) => {
  12. console.log(`元素本身${item} 下标${index}`)
  13. })

some()

检测满足条件的元素,只有有一个满足,后面的就不在检测

  1. //检测数组元素中是否有元素符合指定条件。
  2. //找到一个满足条件,剩下的就不再遍历
  3. // some() 🛕
  4. /*
  5. 1 数组的方法 some 会遍历 数组
  6. 2 some 会接收 一个回调函数
  7. 3 回调函数 接收两个参数
  8. 1 参数一 元素本身
  9. 2 参数二 元素下标
  10. 4 some方法 就会返回 寻找的结果 true 或false🔥
  11. 如果我们在回调函数中 return 了 true => 找到满足条件的元素
  12. */
  13. const arr1 = [
  14. '绿色',
  15. '绿色',
  16. '绿色',
  17. '红色',
  18. '绿色'
  19. ];
  20. let result = arr1.some((item, index) => {
  21. console.log(index, item)
  22. if (item === "红色") {
  23. return true;
  24. } else {
  25. return false;
  26. }
  27. });
  28. //根据判断条件进行简写,
  29. //分析 判断一个值,传一个值,小括号可以缩写;
  30. // 自带 返回值是=> 后面的;只有一行代码的时候,大括号也省略
  31. let result2 = arr1.some(item => item === "红色")
  32. //判断 有没有找到
  33. if (result) {
  34. console.log("找到红衣人")
  35. } else {
  36. console.log("安全")
  37. }

every()

检测每个元素是否满足条件,全部满足返回true

  1. //every 💢💥 检测每一个元素是否符合条件
  2. /*
  3. 1 数组的方法 some 会遍历 数组
  4. 2 some 会接收 一个回调函数
  5. 3 回调函数 接收两个参数
  6. 1 参数一 元素本身
  7. 2 参数二 元素下标
  8. 4 some方法 就会返回 寻找的结果 true 或false🔥
  9. 如果我们在回调函数中 return 了 true => 找到满足条件的元素
  10. */
  11. const arr2 = [
  12. '绿色',
  13. '绿色',
  14. '绿色',
  15. '红色',
  16. '绿色'
  17. ];
  18. let result1 = arr2.every((item, index) => {
  19. console.log(index, item)
  20. if (item === "绿色") {
  21. return true;
  22. } else {
  23. return false;
  24. }
  25. });
  26. if (result1) {
  27. //全部通过
  28. console.log('安全')
  29. } else {
  30. console.log('有问题')
  31. }

join()

把数组转换成字符串

  1. const arr = ['a', 'b', 'c']
  2. let res = arr.map(item => `<p>${item}</p>`);
  3. console.log(res)
  4. let html1 = res.join('')
  5. document.querySelector('div').innerHTml = html1

map()

数组改造成新数组
遍历通过指定函数处理数组的每个元素,重新返回处理后的新数组

  1. 1 数组的方法 map 会遍历 数组
  2. 2 map 会接收 一个回调函数
  3. 3 回调函数 接收两个参数
  4. 1 参数一 元素本身
  5. 2 参数二 元素下标
  6. 3 回调函数中 都需要返回一个改造好的元素
  7. 4 map函数会返回一个新数组 改元素中每一个元素 等于 回调函数中每一个返回的元素

JS高级 - 图1

**trim()** 方法

会从一个字符串的两端删除空白字符 ;当判断输入框是否为空的时候,可以用用

filter()方法

过滤符合条件的每一项,必须要return true或false 表示当前元素是否满足你的要求

filter 本身存在返回值 ,数组中存放满足条件的元素

find()方法

查找目标值
返回符合条件的目标值

findIndex()方法

查找目标值
找到返回索引值
找不到返回-1

includes()方法

判断是否包含指定的值

例如:在输入框中搜索 同姓 的人
JS高级 - 图2

  1. <script>
  2. /*
  3. filter 检测数值元素,并返回符合条件所有元素的数组🔥
  4. 1. 会遍历每一个数组元素
  5. 2. filter 接收 回调函数
  6. 3. 回调函数 有两个参数
  7. 参数一 元素本身 元素下标
  8. 必须要return true或false 表示当前元素是否满足你的要求💥
  9. filter 本身存在返回值 ,数组中存放满足条件的元素💥
  10. */
  11. // const list = [19, 29, 39, 49, 59, 60, 80, 90, 88, 89, 83]
  12. // const newList = list.filter((item) => item > 80)
  13. // console.log(newList)
  14. const list = ['王五', '贺一', '王四', '王三', '李子', '王二', '梅子', '王一'];
  15. const inputs = document.querySelector('input')
  16. const ul = document.querySelector('ul')
  17. //input 事件 输入框发生变化 都会触发
  18. //change事件 输入框发生变化,而且失去焦点,才会触发
  19. inputs.addEventListener('input', function () {
  20. //输入框 两边不能删除空白符的时候,为空的时候
  21. if (!this.value.trim()) {
  22. ul.innerHTML = '';
  23. return
  24. }
  25. render()
  26. })
  27. function render() {
  28. const value = inputs.value
  29. //默认值 item.includes(value) 包含value值的
  30. const filterList = list.filter((item) => item.includes(value));
  31. const html = filterList.map((item) => `<li>${item}</li>`).join("")
  32. ul.innerHTML = html
  33. }
  34. </script>

Set 对象

理解

不会有重复对象的元素 不是数组,但当成数组使用

  1. const s=new Set()

Set也是一个构造函数

Set对象转为数组

  1. const set = new Set([1, 5, 3, 4]); //将数组转成对象
  2. set.add(5);
  3. set.add(5);
  4. console.log(set); //结果 Set(4) {1, 5, 3, 4} 对象类型,添加重复对象无效
  5. const arr = [...set];// 再将set对象转数组 ...剩余运算符
  6. console.log(arr);

例子

JS高级 - 图3

  1. <body>
  2. <input type="text" />
  3. <ul></ul>
  4. <script>
  5. const input = document.querySelector('input');
  6. const ul = document.querySelector('ul');
  7. let arr = ['西瓜', '苹果'];
  8. const renderHTML = () => {
  9. let html = '';
  10. arr.forEach((value) => (html += `<li>${value}</li>`));
  11. ul.innerHTML = html;
  12. };
  13. renderHTML(); //基础渲染数据
  14. //判断输入
  15. input.addEventListener('keyup', function (event) {
  16. // 按下回车
  17. if (event.key === 'Enter') {
  18. const arrs = new Set(arr) //筛选重复 对象
  19. arrs.add(input.value) //加入对象
  20. arr = [...arrs]
  21. renderHTML();
  22. }
  23. });
  24. </script>
  25. </body>

面向对象

ES5

ES6

概念

项目级别,代码封装,代码设计的思想

特点

封装:

  1. 方便维护代码 ,实现业务需求

继承

多态

而在js中,面对对象只体现 封装 继承

对象在内存中的分配🔥

可看构造函数的应用

0606-03.png

复杂数据类型 在栈中 存储的是地址

创建对象

字面量

理解看图 右边的设值 就是字面量

  • 简单方便 用在小案例 复用代码
  • 不适合创建多个同样类型的对象的场景
  • 不好维护

JS高级 - 图5

工厂函数

  1. 容易理解 ;但是打印代码的时候,分不清出这个对象是属于谁,失去所属亲缘关系
  2. 无法复用功能;无法实现面对对象的两大特征:封装与继承

了解console.dir()

console.dir()是在控制台中查看指定JavaScript对象的所有属性的方法,开发人员可以通过它轻松获取对象的属性。

JS高级 - 图6

构造函数

理解:

制定了一种创建对象的模板;方便

  1. 本质是一个函数
  2. 命名 首字母大写
  3. 必须使用new 创建(实例化)对象,否则没意义

结合代码理解:

  <script>
        function Person() {    //普通函数

            //this  代表后面定义声明出来的 实例:p、s、n
              this选中属性 赋值
            this.name = "大圣"
        }
        const p = new Person() //new后 变成构造函数 首字母大写  使用new 
        //----------------通过构造函数所创建出来的这些实例--属性等 一模一样
        const s = new Person()
        const n = new Person()
        console.log(p) // p变量是实例💥

        // 个人理解 new 实例化对象
    </script>

应用

 <script>
        function Render(username, height) {
            this.name = username;
            this.height = height
        }
        const p = new Render('11', 110)
        const s = new Render('22', 220)

        const w = new Render()//undefined;没有值或者只要一个值传递的时候,
                                 缺少的属性值为undefined

        console.log(p)
        console.log(s)
        console.log(w)
    </script>

JS高级 - 图7

须知

  • 笔试题比较常见

构造函数复用的时候,调用的是地址,所有在判断 内置对象中方法是否相等时,结果为true
代码

 <script>
      function Person(username, height) {
        this.username = username;
      }
      const p1 = new Person('八戒1');
      // const p2 = new Person('八戒2');

      // 判断 p1 和 p2 在内存中 是否共用一个地址
      // console.log(p1 === p2); false

      const p3 = p1;
      //判断 p1 和 p2 在内存中是否 共用一个地址
      // console.log(p1 === p3);  true
      p3.username="悟空";
      console.log(p1);
    </script>

工作原理:

  1. 创建一个空对象,把它的地址赋值给this
  2. 把一些属性和方法添加到this上
  3. 把this的proto指向 构造函数的prototype
  4. 把this指向实例

构造函数的弊端

  • 不同实例调用同一个方法,都会在栈中开辟一个空间,存储对应的数据地址;
    🌈地址则指向放在堆中的方法属性,值等;
    🔥这也就造成了内存消耗,复用一次方法,就占用一个新内存

代码:

function createStudent(name, age) {
      this.name = name;
      this.age = age;
      this.say = function () {       构造函数中 有方法say
        console.log(this.name);
      }
    }
    const obj = new createStudent("悟能1", 83);
    const obj1 = new createStudent("悟能2", 84); 
    一个 实例化 调用一次;多个调用多次,占用多个内存
    console.log(obj.say === obj1.say); // false不是同一say方法 浪费了内存

JS高级 - 图8

解决内存消耗

将方法函数 写在构造函数体外面;可以理解为一个单独的个体,方法函数多次调用,存放地址不变

  • 也造成了污染全局变量的问题
 // 提前将say 声明好,单独写出来
    function say() {  // 污染全局变量
      console.log(this.name);
    }
    function createStudent(name, age) {
      this.name = name;
      this.age = age;
      this.say = say
    }
    const obj = new createStudent("悟能1", 83);
    const obj1 = new createStudent("悟能2", 84);

    console.log(obj.say === obj1.say); // true

JS高级 - 图9

原型技术

在构造函数的原型上 存放函数方法
同时解决了浪费内存问题和污染全局变量问题

prototype🔥

理解

  • 原型的单词是 prototype, 原型的这个名字是行业内共同认可的名字。
  • 原型本质是一个对象,理解为 JavaScript 自动帮我们添加的
  • 原型是 JavaScript 自动帮我们在定义构造函数的时候添加的
  • 所有构造函数的实例,共享一个原型,内置原型prototype,可添加
  • 原型上一般是挂载函数

` JS高级 - 图10

通用代码设计
    <script>
       通用代码 的设计
       function Person() {
            //💥在构造函数内部,只会定义一些 非函数类型的属性🔥(普通属性)
                 也就是实例.普通属性 都用this
            this.name = '斑马';
             this.height = 180
             this.color = '白色'
         }
        //🌈方法 函数(行为) 全部定义在  构造函数的原型上🌸
       Person.prototype.say = function () {
          console.log('say 函数');
        };
         Person.prototype.toggle = function () {
             console.log('toggle');
        };
       const p1 = new Person()
        console.log(p1)


        function Person(username, height) {
            this.username = username
            this.height = height
        }
        //原型上的方法也可以通过 this 来访问实例的属性

        Person.prototype.sayName = function () {
            console.log(this.username)
        }
        const p1 = new Person('wu空', 180)
        const p2 = new Person('八戒', 180)
        p1.sayName()
        p1.sayHeight()
        // console.log(p1)
        // console.log()
        // p1.toString() 原型--原型内置的函数
        p2.sayName()
        p2.sayHeight()
    </script>

小整合代码

将以往正常实现功能需求的代码,利用构造函数封装起来,简化升级

思维养成!!!构思!!!

敲代码
实现:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        div {
            width: 100px;
            height: 100px;
            background-color: red;
            margin: 100px 0 0 100px;
        }
    </style>
</head>
<body>
    <button>按钮一:点击一下出现div效果</button>
    <button>按钮二:点击一下div效果放大</button>
    <script>
        //使用构造函数  将实现功能封装起来

        //获取button
        const btn1 = document.querySelector('button:nth-Child(1)')
        const btn2 = document.querySelector('button:nth-Child(2)')

        //构造函数
        function Drr() {
            //实例.属性=。。。。。。
            this.dom = document.createElement("div")
        }
        //避免消耗内存和污染全局变量,,使用原型prototype
        // 构造函数名.原型.函数名 =  function () {}
        Drr.prototype.appendChild = function () {
            //(插入的位置).appendChild(元素)
            document.body.appendChild(this.dom)
        }
        Drr.prototype.scale = function () {
            this.dom.style.transform = "scale(2)"
            this.dom.style.transition = "3s"
        }

        //构造函数封装  功能函数
        const a = new Drr()
        //绑定点击事件
        btn1.addEventListener('click', function () {
            a.appendChild()
        })
        btn2.addEventListener('click', function () {
            a.scale()
        })
    </script>

</body>
</html>

原型链继承

call()借调

借用别人的函数,给自己使用
可以修改this指向

a.方法.call(b)     b调用了a的方法

体验

子类继承父类

   <script> 
      function Parent(name, color, height, weight) {
        // 本来 this的指向 =  Parent 的实例!! 
        this.name = name;
        this.color = color;
        this.height = height;
        this.weight = weight;
      }
      function Son(name, color, height, weight, money) {
        // Son   this 指向 Son的实例!! 
        // call()    ehis借用了Parent方法  来给Son的实例 赋值!!! 
        🔥Parent.call(this, name, color, height, weight); 
          // 儿子 继承了父亲的属性
        this.money = money;
      }
      Parent.prototype.say = function () {
        console.log('这个是父亲的行为');
      };
      🔥Son.prototype.say = Parent.prototype.say; 
             // 儿子 继承 了父亲的行为 方法//下面有升级
      const s= new Son(1,2,3,4,5);
      console.log(s);
    </script>
  </body>
</html>

es5使用-面对对象

构造函数+原型+call来实现;

目前主流浏览器都通用;难
代码理解

<body>
    <script>
        function Parent(name, color, height) {
            this.name = name;
            this.color = color;
            this.height = height;
        }
        Parent.prototype.say = function () {
            console.log("这个是父亲的行为")
        }//父类  可以有多种不同的方法

        Parent.prototype.say = function () {
            console.log("这个是父亲的行为")
        }

        function Son(name, color, height) {
            //父亲的值  借调
            Parent.call(this, name, color, height);
            this.money = money
        }

        //子原型方法say=父原型方法say
        // Son.prototype.say = Parent.prototype.say //一种方法,这样写可以,多种父方法继承就比较繁琐

        // Son.prototype=Parent.prototype //子  继承父的原型链;但如果在子上添加方法,这样写也会增加父  的方法

        //所以使用  剩余运算符...
        Son.prototype = { ...Parent.prototype }
        Son.prototype.a = function () { }  //满足继承,又不影响父 的原型

        console.log(Parent.prototype)
        console.log(Son.prototype)
        const s = new Son(1, 2, 3)
        console.log(s)

    </script>
</body>

案例优化体验:

 <body>
    <script>
      // 父亲 共有 构造函数
      function Element(tagName) {
        // 创建元素
        this.dom = document.createElement(tagName);
      }

      Element.prototype.appendBody = function () {
        document.body.appendChild(this.dom);
      };
      // 儿子1
      function DivElement(content) {
        // this.dom = document.createElement('div');
        💥Element.call(this, 'div');
        this.dom.innerText = content;
      }
      💥DivElement.prototype = { ...Element.prototype };

      // 儿子2
      function ImgElement(src) {
        Element.call(this, 'img');
        this.dom.src = src;
      }
      ImgElement.prototype = { ...Element.prototype };

      const divElement = new DivElement('这个是div的 内容');

      setTimeout(() => {
        divElement.appendBody();
      }, 1000);

      const imgElement = new ImgElement('./images/1.jpg');
      setTimeout(() => {
        imgElement.appendBody();
      }, 2000);
    </script>
  </body>
</html>

es6 -面对对象

使用class类

很常用;简单

同时解决了内存消耗和污染全局变量的 问题

继承写法:
//class 首字母大写
class Parent{
    //构造器🌸
    constructor{
        //super()写在构造器内部  //需要继承父类的话,可添加super()
        super()🍄  //相当于调用父级的构造函数
    }
//方法函数写构造器外面🎃
   say(){

   }
}

Code example理解

 <script>
     //简单常规写法
        class DivElement {
            🍁constructor(text) {
                this.dom = document.createElement('div')
                this.dom.innerHTML = text
            }
            //函数简写
            appendBody() {
                document.body.appendChild(this.dom)
            }
        }
        console.dir(DivElement)
        const divElement = new DivElement('添加成功')
        setTimeout(() => {
            divElement.appendBody()
        }, 1000)
    </script>

使用class类 继承

    <script>
        //父类
        class Parent {
            constructor(username) {
                console.log("父类的构造器")
                this.username = username
            }
            sau() {
                console.log('父类中的方法')
            }
        }
        //子类 extends  继承父类:
        //1.不写构造器constructor,默认自己加构造器+并调用调用super(),===默认调用父类的构造器

        //  2. 写构造器  里面调用super();
        //  理解为父类的构造器===Person.call(this)
        class Son extends Parent {
            constructor(username, height) {
                super(username) //使用super()就是调用父类的构造器constructor
                this.height = height // 子类添加 新属性
            }
            fly() {   // 子类添加 新方法
                console.log('我会飞')
            }
        }
        const s = new Son('儿子', 200) //new Son()就代表调用 构造器
        console.log(s)
        console.dir(Parent)
    </script>

再次优化案例

    <script>
        //共有 父类
        class Parent {
            constructor(tagName) {
                this.dom = document.createElement(tagName)

            }
            appendBody() {
                document.body.appendChild(this.dom)
            }
            scale(rate) {
                this.dom.style.transition = '1s'
                setTimeout(() => {
                    this.dom.style.transform = `scale(${rate})`
                }, 500)

            }
        }

        class DivElement extends Parent {
            constructor(text) {
                super("div");
                //调用父类的构造器
                this.dom.innerHTML = text
            }
        }

        class ImgElement extends Parent {
            constructor(src) {
                super('img');
                this.dom.src = src
            }
        }

        const divElement = new DivElement('div添加成功')
        setTimeout(() => {
            divElement.appendBody()
        }, 1000)
        const imgElement = new ImgElement('./images/1.png')
        setTimeout(() => {
            imgElement.scale(.3)
            imgElement.appendBody()
        }, 2000)
    </script>

call bind apply

共同点与区别;面试常问

<script>
        /*
        call   bind   apply
        1. 共同点:都可以修改 this 的指向
          写法:1.1  call  apply  直接使用 ; bind不能直接使用
                    obj.say.call(newObj)
                    obj.say.apply(newObj)
               1.2 bind被使用的时候,不会直接调用原来函数的方法say,
                    而是会返回一个新函数,需要我们自己去调用
        */
     /*  2. call 和 apply 区别   传递参数的写法 不同!! 
           1 obj.say.call(newObj,1,2);  在实例后面直接写值,逗号隔开

           2 obj.say.apply(newObj,[1,2]); apply传递的是数组,需要用[]包裹值

           3 (obj.say.bind(newObj))(1,2); bind在调用成功后,
             (obj.say.bind(newObj,1,2))();   值写在后面的小括号,或者和实例中的括号里,都可以比较随意
       */
        const obj = {
            username: "八戒",
            say(a, b) {
                console.log(this)
                console.log(a, b)
            }
        };
        const newObj = {
            username: '悟空'
        }
        obj.say.call(newObj)
        obj.say.apply(newObj)

          obj.say.bind(newObj)❌❌❌  
         💛const newSay = obj.say.bind(newObj); // newObj
         newSay();    可以使用或者下一写法
         🧡(obj.say.bind(newObj))(); // newObj

        // obj.say.call(newObj,1,2);// 传参
        // obj.say.apply(newObj,[1,2]);// 传参 数组
        (obj.say.bind(newObj))(1,2); 

    </script>

检测数据类型

typeof--检测简单(基础)数据类型


instanceof---检测复杂数据类型(引用);
             同时可以判断实例和构造函数的关系,
             是通过new()出来的构造函数,返回true;
             不是,返回false
 <script>
        //复杂数据类型  instanceof
        function Person() {
        }
        function Pe() {
        }
        const p1 = new Person()
        const p2 = new Pe()  
        console.log(p1 instanceof Person)  //true
        console.log(p1 instanceof Pe)    //false
    </script>

箭头函数没有 this指向

JS高级 - 图11

原型链

 <script>
      /* 
      原型链   一层关系  多个对象 可以通过 原型 技术 层层的关联 
      prototype  构造函数点出来
      __proto__  实例点
       */
      // const div=document.querySelector("div")
      // console.dir(div)

      function Person() {}

      const p1 = new Person();
      // console.log(Person.prototype === p1.__proto__);
      p1._
    </script>

可参考 js高级