ES6之类(class)和继承

原来我们写面向对象编程,都是在通过构造函数,然后在原型上写的,比如:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <title></title>
  <link rel="stylesheet" href="">
</head>
<body>
</body>
<script>
  Person.prototype.getName = function () {
    return this.name;
  }
  Person.prototype.getAge = function () {
    return this.age;
  }
  function Person (name, age) {
    this.name = name;
    this.age = age;
  }
  let person = new Person ('ReSword', 21);
  console.log(person.getName(), person.getAge());
</script>
</html>

当然我们也可以通过Object.assign方法

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <title></title>
  <link rel="stylesheet" href="">
</head>
<body>
</body>
<script>
  // Person.prototype.getName = function () {
  //   return this.name;
  // }
  // Person.prototype.getAge = function () {
  //   return this.age;
  // }
  Object.assign(Person.prototype, {
    getName () {
      return this.name;
    },
    getAge () {
      return this.age;
    }
  });
  function Person (name, age) {
    this.name = name;
    this.age = age;
  }
  let person = new Person ('ReSword', 21);
  console.log(person.getName(), person.getAge());
</script>
</html>

这样也是可以的

接下里介绍ES6中新增的class方法

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <title></title>
  <link rel="stylesheet" href="">
</head>
<body>
</body>
<script>
  class Person {
    constructor (name, age) { //构造方法(函数),调用new,自动执行
      console.log(name, age);
    }
  }

  let person = new Person('ReSword', 21);
</script>
</html>

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <title></title>
  <link rel="stylesheet" href="">
</head>
<body>
</body>
<script>
  class Person {
    constructor (name, age) { //构造方法(函数),调用new,自动执行
      this.name = name;
      this.age = age;
    }
    getName () {
      return this.name;
    }
    getAge () {
      return this.age;
    }
  }
  console.log(typeof(Person));
  let person = new Person('ReSword', 21);
  console.log(person.getName(), person.getAge());
</script>
</html>

上面的Person使用的函数声明的方式,也可以是使用函数变量的方式来使用calss

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <title></title>
  <link rel="stylesheet" href="">
</head>
<body>
</body>
<script>
  const Person = class {
    constructor (name, age) { //构造方法(函数),调用new,自动执行
      this.name = name;
      this.age = age;
    }
    getName () {
      return this.name;
    }
    getAge () {
      return this.age;
    }
  }
  console.log(typeof(Person));
  let person = new Person('ReSword', 21);
  console.log(person.getName(), person.getAge());
</script>
</html>

这种方式也是可以的

--------------------------------------------------------------------------------------------

下面说明class中的方法名可以使用变量来代替

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <title></title>
  <link rel="stylesheet" href="">
</head>
<body>
</body>
<script>
  let AAA = 'BBB';
  const Person = class {
    constructor (name, age) { //构造方法(函数),调用new,自动执行
      this.name = name;
      this.age = age;
    }
    getName () {
      return this.name;
    }
    getAge () {
      return this.age;
    }
    AAA () {
      return 'AAA-function';
    }
  }
  let person = new Person('ReSword', 21);
  console.log(person.AAA());
</script>
</html>

这样子我们去访问AAA 是有这函数的

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <title></title>
  <link rel="stylesheet" href="">
</head>
<body>
</body>
<script>
  let AAA = 'BBB';
  const Person = class {
    constructor (name, age) { //构造方法(函数),调用new,自动执行
      this.name = name;
      this.age = age;
    }
    getName () {
      return this.name;
    }
    getAge () {
      return this.age;
    }
    [AAA]() {
      return 'AAA-function';
    }
  }
  let person = new Person('ReSword', 21);
  console.log(person.BBB());
</script>
</html>

在我们加了 [] 之后,再去看

他会提示你AAA不是一个函数

我们去Person.prototype中查看

所以我们改成BBB

在我们改成BBB之后,

就可以运行到函数了

这其实就是JS的基础,我们知道后缀点和方括号都可以调用属性,但是后缀点是不能跟变量的,但是方括号可以

--------------------------------------------------------------------------------------------

还有就是class没有预解析,即下面这种写法是错误的

-------------------------------------------------------------------------------------

下面说明class中this指向的问题

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <title></title>
  <link rel="stylesheet" href="">
</head>
<body>
</body>
<script>
  class Person {
    constructor (name, age) {
      this.name = name;
      this.age = age;
    }
    getName () {
      console.log('this: ', this);
      return this.name;
    }
  }
  let person = new Person ('ReSword', 21);
  let {getName} = person;
  console.log(getName());
</script>
</html>

这里是因为你将Person中方法提取了出来,那么这里的this就会指向运行环境,所以造成运行失败

解决方法1:

调用bind方法,将getName绑定到对象上

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <title></title>
  <link rel="stylesheet" href="">
</head>
<body>
</body>
<script>
  class Person {
    constructor (name, age) {
      this.name = name;
      this.age = age;
      this.getName = this.getName.bind(this);
    }
    getName () {
      console.log('this: ', this);
      return this.name;
    }
  }
  let person = new Person ('ReSword', 21);
  let {getName} = person;
  console.log(getName());
</script>
</html>

解决方法2:

使用箭头函数

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <title></title>
  <link rel="stylesheet" href="">
</head>
<body>
</body>
<script>
  class Person {
    constructor (name, age) {
      this.name = name;
      this.age = age;
      this.getName = () => {
        console.log('this: ', this);
        return this.name;
      }
    }
  }
  let person = new Person ('ReSword', 21);
  let {getName} = person;
  console.log(getName());
</script>
</html>

------------------------------------------------------------------------------------------------

class里面还新增了两个函数getter和setter

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <title></title>
  <link rel="stylesheet" href="">
</head>
<body>
</body>
<script>
  class Person {
    constructor (name, age) {
      this.name = name;
      this.age = age;
    }
    get work () {
      return 'gettter'
    }
    set work (value) {
      console.log('setter: ' + value);
    }
  }
  let person = new Person ('ReSword', 21);
  person.work = 'student';//调用set
  console.log(person.work);//调用get
</script>
</html>

get和set一般用于封装底层框架

-------------------------------------------------------------------------------------------------

class里的静态方法:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <title></title>
  <link rel="stylesheet" href="">
</head>
<body>
</body>
<script>
  class Person {
    constructor (name, age) {
      this.name = name;
      this.age = age;
    }
    static fun () {
      return 'this is a static function';
    }
  }
  console.log(Person.fun());
</script>
</html>

----------------------------------------------------------------------------------------------

class里面的继承

我们先来看原JS的继承方法(即原型链)

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <title></title>
  <link rel="stylesheet" href="">
</head>
<body>
</body>
<script>
  Person.prototype.getName = function () {
    return this.name;
  }
  function Person (name, work) {
    this.name = name;
    this.work = work;
  }
  Student.prototype = new Person ();//继承方法
  function Student (name, work, grade) {
    Person.call(this, name, work);//继承属性
    this.grade = grade;
  }
  let student = new Student ('ReSword', 'Student', 'Junior');
  console.log(student.work);
  console.log(student.getName());
</script>
</html>

再来看class通过extends关键字的继承

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <title></title>
  <link rel="stylesheet" href="">
</head>
<body>
</body>
<script>
  class Person {
    constructor (name, work) {
      this.name = name;
      this.work = work;
    }
    getName () {
      return this.name;
    }
  }
  class Student extends Person {
    constructor (name, work, grade) {
      super(name, work);
      this.grade = grade;
    }
  }
  let student = new Student('ReSword', 'Student', 'Junior');
  console.log(student.work);
  console.log(student.getName());
</script>
</html>

注意点:

1,

等同于

2,必须要在super之后才能使用this,这是因为子类的创建是基于父类的,只有super方法才能调用父类实例

3,父类的静态方法也会被子类所继承

上面只是父类的属性调用,下面是讲父类的方法调用:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <title></title>
  <link rel="stylesheet" href="">
</head>
<body>
</body>
<script>
  class Person {
    constructor (name, work) {
      this.name = name;
      this.work = work;
    }
    getName () {
      return `This is father's function ${this.name}`;
    }
  }
  class Student extends Person {
    constructor (name, work, grade) {
      super(name, work);
      this.grade = grade;
    }
    getName () {
      console.log(super.getName());
      return `This is son's function ${this.name}`;
    }
  }
  let student = new Student('ReSword', 'Student', 'Junior');
  console.log(student.work);
  console.log(student.getName());
</script>
</html>

注意点:

如果直接在子类中写和父类相同名字函数,那么其实际上只会执行子类的函数,

如果想要执行父类的函数,请使用super

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值