JS高级---set, this指向 & ES6-class

123 阅读3分钟

set新对象

      // 1. set对象是es6才推出的  主要的功能是去重处理
      // 2. set 是一个对象 不是一个数组

      // 有时候需要先设置一个初始数组
      const arr = [5, 3, "a", "b"];
      // 1. set 对象需要被new出来
      const set = new Set(arr); // 数组转成set对象

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

      // 3. set 转成 数组(map、forEach等)
      const arr1 = [...set];

this指向

对于普通函数,大部分情况,this 等于这个函数的调用者(例外 - bind、call、apply)

对于箭头函数,大部分情况this 等于window,例外(面向对象用法),如果箭头函数和this 一起用的话,要慎用!!

call

      const obj = {
        name: "小明",
        eat() {
          console.log(this.name + "吃午饭");
        },
      };

      const person = {
        name: "小刚",
      };
	  // 修改 this指向
	  obj.eat.call(person); // 输出 小刚吃午饭
	  // 传递参数
	  obj.eat.call(person, "吃午饭")  // 输出 小刚吃午饭

apply

      const obj = {
        name: "小明",
        eat() {
          console.log(this.name + "吃午饭");
        },
      };

      const person = {
        name: "小刚",
      };
	  // 修改 this指向
      obj.eat.apply(person); // 输出 小刚吃午饭
	  // 传递参数
	  obj.eat.call(person, ["吃午饭"])  // 输出 小刚吃午饭

bind

      const obj = {
        name: "小明",
        eat() {
          console.log(this.name + "吃午饭");
        },
      };

      const person = {
        name: "小刚",
      };
      // bind 不会直接调用skill函数 而是 返回一个新的函数 需要我们主动的调用新的函数- 调用skill()
	  // 定义一个变量来接收修改后的this指向
      const func = obj.eat.bind(person);
      func();  // 输出 小刚吃午饭
	  // 传递参数
      const func = obj.eat.bind(person);
      func("吃午饭");  // 输出 小刚吃午饭

es6 class

面向对象

      class Person {
        // 方法 constructor 构造函数 会在 new Person的时候触发
        constructor(name) {
          // 对象的属性都写在constructor里面
          this.name = name;
        }

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

      const p1 = new Person("悟饭");
      p1.say(); // 输出  say方法被调用 悟饭

属性/方法继承

      class Person {
        constructor(name) {
          this.name = name;
        }

        say() {
          console.log("say what?");
        }
        filing() {
          console.log("I know you");
        }
      }

      // extends 直接就实现了继承父亲的属性和方法
      class Student extends Person {
        constructor(name, color) {
          // super() 继承父亲的属性
          super(name, color);
          this.color = color;
        }
        // extends已经继承父亲的方法 若不想使用父亲的方法 直接另写一个覆盖掉即可
        // say(){
        //   console.log('say something');
        // }
      }

      const p1 = new Student("八神", "red");
      console.log(p1); // 输出 {name: '八神', color: 'red'}

      // 直接调用父亲 Person 的方法
      p1.filing(); // 输出 I know you
      p1.say(); // 输出 say what?

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

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

es5 原型链

介绍

一个对象,它可以通过prototype来找到被它继承父亲的方法,如果一个对象从底层触发,可以通过 prototype 一层一层往上找到继承的关系,这就是原型链

作用

如果需要给某个数据 (字符串、数组、对象) 统一添加一个方法 ,那么这时可以直接在原型上添加

      function Person() {}
      const p1 = new Person();

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

      // js内置的Array数据
      Array.prototype.show = function () {
        console.log("自定义的数组方法");
      };

      // 数组创建方式2:数组也是可以被new出来的
      const arr = new Array("a", "b", "c");
      // const arr = ['a', 'b', 'c'];
      // arr.show(); // 输出 自定义的数组方法

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

      // 对象的创建也分两种情况

      // const ojb={};// 字面量 常用 直接 简单
      // 利用构造函数的方式来创建对象
      const obj = new Object();

      Object.prototype.show = function () {
        console.log("对象 自己的show方法");
      };

      obj.show(); // 输出 对象 自己的show方法