set去重,bind-call-apply修改this指向和传递参数,箭头函数-this指向,es6的面向对象和继承加案例,es6-class和箭头函数

114 阅读2分钟

es6-三种定义方法的写法-对比最优,加原型链和数组的原型链的还要 自定义方法

1.set数组去重

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no"
    />
    <title>01-set数组去重.html</title>
    <style>
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }
    </style>
  </head>
  <body>
    <script>
      /* 
      1 set对象 是es6 才推出 
      2 主要的功能 去重处理  
         set.add(1);
      3 set是一个对象,不是一个数组!! 
      4 实现 使用set转成数组的时候,需要考虑 (set对象转-数组    数组 - 转成对象)
        数组 - 转成对象  new Set(beforeArr)
        set对象转-数组   const arr=[...set];

       */


      //  0 有时候 先设置一个初始数组 里面已经存在一些数据
      // 在创建set的对象的时候,把数组传给它
      const beforeArr=['a','b',3,4];

      //  1 set对象 需要被new 出来
      const set = new Set(beforeArr);// 数组转成set对象

      // 2 给set添加数据的时候 使用 add方法  
      set.add(1);
      set.add(2);
      set.add(2);// 发现有重复数据了,自己内部过滤
      set.add(2);// 发现有重复数据了,自己内部过滤
      set.add(2);// 发现有重复数据了,自己内部过滤
      set.add(2);// 发现有重复数据了,自己内部过滤

      // 3 打印set 看一下
      console.log(set);

      // 4 set 转成 数组(map、forEach。。。)
      const arr=[...set];
      console.log(arr);

    </script>
  </body>
</html>

2.set数组去重案例

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport"
        content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no" />
    <title>02-set去重案例</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
    </style>
</head>

<body>
    <input type="text" />
    <ul></ul>
    <script>
        const input = document.querySelector('input');
        const ul = document.querySelector('ul');
        let arr = ['a', 'b'];
        render();
        input.addEventListener('keydown', function (event) {
            if (event.key === 'Enter') {
                // 去重处理
                arr.push(this.value);
                let set = new Set(arr)
                set.add(this.value)
                 arr = [...set]
                render();
            }
        });
        function render() {
            const html = arr.map((value) => `<li>${value}</li>`).join('');
            ul.innerHTML = html;
        }
    </script>
</body>

</html>

3.bind-call-apply修改this指向

1650765620711.png

1 bind call apply 都可以实现修改this指向

​ 2 代码写法上有区别

​ 1 obj.skill.call(person);

​ 2 obj.skill.apply(person);

​ 3 const func = obj.skill.bind(person);

​ func();

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no"
    />
    <title>04-bind-call-apply修改this指向.html</title>
    <style>
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }
    </style>
  </head>
  <body>
    <script>
      /* 
      1 bind call apply 都可以修改this的指向  

      2 分别演示 修改this指向
        call  obj.skill.call(person)
        apply obj.skill.apply(person)
        bind  
         const func = obj.skill.bind(person);
         func(); 

      3 传递参数的时候不同写法上 (下一节课再来讲解)

       */

      const obj = {
        name: '老王',
        skill() {
          console.log(this.name + '  翻墙');
        },
      };

      const person = {
        name: '大郎',
      };

      // call 方式来修改this的指向
      // obj.skill.call(person);// 大郎 借用老王的方法

      // apply 方式来修改this的指向
      // obj.skill.apply(person); // 大郎 借用老王的方法

      // bind 方式来修改this指向
      // bind 不会直接调用skill函数 而是 返回一个新的函数
      // 需要我们主动的调用新的函数- 调用skill()
      const func = obj.skill.bind(person);
      func();
    </script>
  </body>
</html>

4.bind-call-apply传递参数

传递参数

​ 1 obj.skill.call(person,参数1,参数2)

​ 2 obj.skill.apply(person,[参数1,参数2])

​ 3 const func = obj.skill.bind(person);

​ func(参数1,参数2)

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport"
        content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no" />
    <title>04-bind-call-apply修改this指向.html</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
    </style>
</head>

<body>
    <script>
        /* 
        1 传递参数的时候不同写法上 (下一节课再来讲解)
         */

        const obj = {
            name: '老王',
            skill(a, b) {
                console.log(this.name + ' ' + a + ' ' + b);
            },
        };

        const person = {
            name: '大郎',
        };

        // obj.skill.call(person,1,2);// 传参
        // obj.skill.apply(person, [1, 2]); // 数组

        // 在早些时候 我们是这样来计算 数组最大值和最小值

        // const max = Math.max(1, 2, 3, 4);
        // console.log(max);
        // const arr=[1,2,3,4];
        // 借用 Math.max方法 目的不是修改this指向
        // 而是 计算数组最大值

        // const max = Math.max.apply(null,arr);


        // 这种
        // const arr=[1,2,3,4];
        // console.log(Math.max(...arr));

        const func = obj.skill.bind(person);
        func(1, 2);


        /*
        1 bind call  apply 都可以实现修改this指向
        2 代码写法上有区别
          1 obj.skill.call(person);
          2 obj.skill.apply(person);
          3 const func = obj.skill.bind(person);
            func();
        3 传递参数
          1 obj.skill.call(person,参数1,参数2)
          2 obj.skill.apply(person,[参数1,参数2])
          3 const func = obj.skill.bind(person);
            func(参数1,参数2)
        
         */
    </script>
</body>

</html>

5.-箭头函数-this指向

大部分情况,对于普通函数,this 等于这个函数的调用者 (例外 - bind、call、apply) 大部分情况,对于箭头函数,this 等于window 箭头函数和this 一起用的话,要慎用!! 例外(面向对象用法,)

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport"
        content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no" />
    <title>06-箭头函数-this指向.html</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
    </style>
</head>

<body>
    <button>点击我 我就改变颜色</button>
    <script>
        // 在js中,顶级的对象 就是window

        // 定义一个函数 形式是箭头函数的
        // const func = () => {
        //   console.log(this);
        // };

        // func();

        // const obj = {
        //   name: '悟空',
        //   say: () => {
        //     console.log(this);
        //   },
        // };
        // obj.say(); // window

        // const obj1 = {
        //   name: '悟空1',
        //   obj2: {
        //     name: '悟空2',
        //     say: () => {
        //       console.log(this);
        //     },
        //   },
        // };
        // obj1.obj2.say();

        const button = document.querySelector('button');
        // button.addEventListener('click', function () {
        //   console.log(this); // this = button
        // });
        button.addEventListener('click', () => {
            console.log(this);// this = 谁 
        });

        /*
        大部分情况,对于普通函数,this 等于这个函数的调用者
          (例外 - bind、call、apply)
        大部分情况,对于箭头函数,this 等于window
          箭头函数和this 一起用的话,要慎用!! 
          例外(面向对象用法,)
         */
    </script>
</body>

</html>

6.es6的面向对象

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no"
    />
    <title>08-es6的面向对象.html</title>
    <style>
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }
      body {
        background-color: aqua;
      }
    </style>
  </head>
  <body>
    <script>
      // es6 面向对象 引出新的语法 类 class
      class Person {
        // 方法 constructor 在es6 构造函数
        // constructor 会在 new Person的时候触发
        constructor(name) {
          // console.log("开始创建对象啦");
          this.name = name;
        }

        // 直接写行为
        say() {
          console.log('say方法被调用啦 ' + this.name);
        }
      }

      // 一样new一个对象
      const p1 = new Person('悟空1');
      const p2 = new Person('悟空2');
      // console.log(p1);

      // p1.say();

      console.log(p1.say === p2.say);

      // 属性
      // 行为

      class SuperMan {
        constructor() {
          // 对象有什么属性都写在 这里
          this.name = '超人';
          this.color = 'blue';
        }
        // 行为
        say() {
          console.log('说话');
        }
        fly() {
          console.log('会飞');
        }
        sing() {
          console.log('唱歌');
        }
      }
    </script>
  </body>
</html>

7.es6的继承

1 如果你写了 extends 而且还写了 constructor 那你必须要在 constructor 调用了方法 super(); 2 如果你只写了 extends 但是你没有写constructor 不需要管super

继承要继承父亲的属性和父亲的行为 1 只实现了继承父亲的行为 还没有实现继承父亲的属性 (super 表示可以继承父亲的属性)

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no"
    />
    <title>10-es6-继承.html</title>
    <style>
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }
    </style>
  </head>
  <body>
    <script>
      class Person {
        constructor(name) {
          this.name = name;
        }
        say() {
          console.log('say方法我调用啦 ' + this.name);
        }
        fly() {
          console.log('父亲的起飞');
        }
      }

      // 表示学生要继承父亲
      // extends 直接就实现了继承父亲的方法
      class Student extends Person {
        //
        constructor(name, color) {
          super(name); // 父亲的构造函数 =es5   Person.call(this,name);
          this.color = color;
        }
        // fly(){
        //   console.log("儿子 起飞");
        // }
        // fly = null; // 用儿子的新的null 去覆盖父亲的fly没有父亲的fly
      }

      const s1 = new Student('学生', 'red');
      s1.say();
      s1.fly();
      /* 
      Must call super constructor in derived class before accessing 'this' or returning from derived constructor
      1 如果你写了 extends 而且还写了 constructor 那你必须要在 constructor 调用了方法 super();
      2 如果你只写了 extends 但是你没有写constructor 不需要管super 

      继承要继承父亲的属性和父亲的行为
      1 只实现了继承父亲的行为  还没有实现继承父亲的属性 (super 表示可以继承父亲的属性)
      

       */
    </script>
  </body>
</html>

8.es6继承案例

就是es5的改一下

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport"
        content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no" />
    <title>12-继承的案例</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
    </style>
</head> 
<body>
    <script>
        //  父亲
        class Element {
            constructor(tagName) {
                const dom = document.createElement(tagName);
                this.dom = dom;
            }
            append(parentSelector) {
                document.querySelector(parentSelector).appendChild(this.dom);
            }
        }
        // 儿子1
        class ElementDouble extends Element {

            constructor(tagName, content) {
                super(tagName);// 继承 - 父亲的属性
                this.dom.innerText = content;
            }
        }
        // 儿子2
        class ElementSingle extends Element {
            constructor(tagName, src) {
                super(tagName);
                this.dom.src = src;
            }
        }
        //儿子1
        const divModel = new ElementDouble('div', '这个是div');
        //父亲的方法
        divModel.append('body');

        const imgModel = new ElementSingle('img', './18.jpg');
        imgModel.append('div');
    </script>
</body>

</html>

9.es6-class和箭头函数

es6 属性的定义 写法有两种

  1. 直接在构造函数内 constructor this.name=name
  2. 可以写在 大括号内
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no"
    />
    <title>12-es6-class和箭头函数.html</title>
    <style>
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }
    </style>
  </head>
  <body>
    <script>
      // es6 属性的定义 写法有两种
      // 1 直接在构造函数内  constructor  this.name=name
      // 2 可以写在 大括号内

      // 3 方法 三种写法

      class Person {
        // color = 'yellow';
        // height = 180;
        // weight = 200;
        constructor(name) {
          this.name = name;
          // this.color = 'yellow';
          // this.height = 180;
          // this.weight = 200;
        }
        // 写法一
        // say() {
        //   console.log('say 方法被调用了 ' + this.name);
        // }
        // 写法二
        // say = function () {
        //   console.log('say 方法被调用了 ' + this.name);
        // };
        // // 写法三
        say =  ()=> {
          // 箭头函数中的this , 绝大部分指向  window
          // 例外 用在 es6的class 充当 方法  this 指向 p1 实例 
          console.log('say 方法被调用了 ' + this.name);
        };
      }
      const p1 = new Person('悟空');
      p1.say();
      // console.log(p1);
    </script>
  </body>
</html>

10.es6-三种定义方法的写法-最优

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport"
        content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no" />
    <title>13-es6-三种定义方法的写法-最优.html</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
    </style>
</head>

<body>
    <script>
        class Person {
            // 性能最好 推荐方式!! 
            say1() {
                console.log('say1');
            }
            say2 = function () {
                console.log('s2');
            };
            say3 = () => {
                console.log('s3');
            };
        }
        const p1 = new Person();
        const p2 = new Person();

        console.log(p1.say1 === p2.say1); // true p1 和 p2 say1方法是同一个-节省内存
        console.log(p1.say2 === p2.say2); // false  p1 和 p2 say2方法不是同一个-性能不好
        console.log(p1.say3 === p2.say3); // false  p1 和 p2 say3方法不是同一个-性能不好
    </script>
</body>

</html>

11.原型链-1

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no"
    />
    <title>14-es5-原型链.html</title>
    <style>
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }
    </style>
  </head>
  <body>
    <script>
      // 1 创建数组的方式 有两种
      // const arr = ['a', 'b', 'c']; // 字面量 常用-直接和简单的写法

      // 2 数组 也是可以被new
      // const arr = new Array('a', 'b', 'c');
      // console.log(arr);

      function Person() {}
      const p1 = new Person();
      // 在 Person的原型上添加一个方法
      Person.prototype.show = function () {
        console.log('自己添加的方法');
      };
      // p1.show();

      // 给js内置的Array数据 原型也添加一个方法试试
      Array.prototype.show = function () {
        console.log('自定义的数组方法');
      };

      const arr = new Array('a', 'b', 'c');
      // const arr = ['a', 'b', 'c'];
      // arr.show();

      // 利用原型对象的方式,在任意的构造函数上添加想要的行为
      // 任意的构造函数 包括 自己定义的构造函数
      // 也包括 js中 -内置就有的构造函数 Array

      // arr.forEach
      // arr.push()
      // arr.map()
      // arr.filter

      // 对象的创建也分两种清空
      // const ojb={};// 字面量 常用 直接 简单
      const obj = new Object(); // 利用构造函数的方式来创建对象
      Object.prototype.show = function () {
        console.log('对象 自己的show方法');
      };
      obj.show();
    </script>
  </body>
</html>

12.原型链-2

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport"
        content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no" />
    <title>15-es5-原型链</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
    </style>
</head>

<body>
    <div></div>
    <script>

        /* 
        原型链
        一个对象 它可以通过 prototype 来 找到被它继承父亲的方法
        如果一个对象从底层触发 可以通过 prototype 一层一层往上找到 继承的关系 =  原型链 
  
        // 作用
        1 如果我需要给 某个数据 (字符串、数组、对象) 统一添加一个方法 ,可以直接在原型上添加 
        2 初学者 不要乱在原型上定义方法 - 影响巨大  
        
         */
        // const obj = {
        //   username: '悟空',
        //   say() {
        //     console.log('这个是say方法');
        //   },
        // };

        // //  万物皆对象
        // Object.prototype.show = function () {
        //   console.log('这个是原型上的show方法');
        // };

        // // 你看要 dom对象  大哥大
        // console.dir(document.querySelector("div"));

        // const arr = [];
        // console.log(arr);
        // arr.show();

        // console.log();
        // Math.show()

        // const str="123";
        // console.dir(str.show);
        // str.show();

        //  console.log(obj);// 直接看到定义在自己身上的属性和方法 看不见定义在 原型对象上的属性和方法
        //  console.log([]);
        // const arr=[];
        // arr.push
        // console.log(arr);
        // obj.say();
        // obj.show();
        // const arr1=[];
        // const arr2=[];
        // const arr3=[];

        // js 真垃圾 !!

        // DNA 存在于你整个家族 不只是父亲和儿子



        Array.prototype.forEach = function () {
            console.log("老子罢工了");
        }
        Array.prototype.map = function () {
            console.log("老子罢工了");
        }
        const arr = [1, 2, 3];
        arr.forEach(); // forEach 循环 到了你这个项目 这个知识用不了 
      // 对于新入门小小员工来说  毁灭性的打击
      // 10多年代码 用不上 心态。。。。

      // arr.map()// 以前我学都是啥 想不开   你要有责任!! 

    </script>
</body>

</html>