js实现类

139 阅读3分钟

js如何实现类?

方法一:(es5没有class)使用原型

function Dog(name) {
  this.name = name;
  this.leg = 4;
}
Dog.prototype.kind = ‘狗’
Dog.prototype.say = function() {
  console.log(‘汪’)
}
const d1 = new Dog(‘哮天犬’);
Dog函数就是一个类。

最好不要写成下面这种
Dog.prototype = {
  kind: ‘狗’,
  say: function() {
   console.log(‘汪’)
}
}

因为prototype本身会有一个内置的属性 Dog.prototype.constructor = Dog;

即任何一个函数的prototype的constructor属性的值都是这个函数本身,不管这个函数什么,箭头函数没有这个。如果按照上面的写法的话,那么constructor 就被改掉了,不知道其构造函数时啥了。

方法二:使用class

属性: 自身属性和共有属性 把所有的自身属性写在构造函数中

class Dog {
  static kind = ‘小狗’
  kind2= ’小猴’ //等价于在constructor里面写this.kind2 = ‘小猴’
// 加上static 的话 会被声明在构造函数Dog上,实例访问不到kind这个属性,只有Dog才能访问到,可以打印出来看到 如果不加static的话,会成为实例的私有属性,可以访问到。
  constructor(name) {
    //这里写的就是自身属性
    this.name = name;
}
//以下这里是共有属性 也就是原型上的属性
say() {
  console.log(‘xxx’)
}
run() {
  console.log(‘xxx’)
}
}
const d1 = new Dog(‘哮天犬’)

如果使用的是ts的话,就使用class. class没有提供方法以直接在prototype上添加非函数的属性的方式, 比如上面的kind, 只能变成实例的属性上,或者是成为构造函数的属性 而不会成为prototype的属性。

JS如何实现继承?

继承是类和类之间的关系,一个类继承了另外一个类,所以需要写两个类然后让这两个类产生联系,需要解决自身属性的继承和共有属性的继承。

方法一:使用原型链(es5没有class的情况下)

function Animal(legNums) {
  this.legs = legNums;
}
Animal.prototype.eat = function (){ console.log(‘xxx’)}
  1. 继承私有属性 function Dog() { Animal.call(this, 4) //这里是继承Animal的自身属性变成dog的自身属性 this.name = name; }

  2. 继承原型 或许你会想Dog.prototype.proto = Animal.prototype //被ban掉了 但是以上方法是不能用的,因为并不是所有的地方都是以__proto__作为对象名的,有的可能是[[proto]], 不是统一都是__proto__

那么我们可以使用以下的方法

新建一个空函数,让他的prototype指向Animal.prototype

var emptyAnimal = function(){};
emptyAnimal.prototype = Animal.prototype; 
然后将Dog的prototype属性指向 new emptyAnimal();
Dog.prototype = new emptyAnimal ();

这样就可以实现Dog.prototype的原型指向了Animal.prototype 因为new的功能就是 会帮我创建一个临时对象,并且绑定这个临时对象的原型。

为什么不直接用Dog.prototype = new Animal(),而是还要新建一个空的函数呢? 因为如果Animal构造函数下还有自身属性 legs, 这个还是会被带入进来。这个我们并不需要,我们只想要继承Animal的原型。最终就是Dog.prototype的原型(或许是__proto__属性,或许是其他名字的属性)会被指向Animal.prototype.

var f= function(){}
f.prototype = Animal.prototype;
Dog.prototype = new f();

方法二:es6使用class

class Animal {
  constructor(legs) {
    this.legs = legs;
}
run(){
  xxxx
}
}

class Dog extends Animal { //必须使用extends 来继承,只要写了extends就会继承原型
   constructor(name) {
     super(4) //使用super()来继承私有属性legs,super必须写在上面,不然会报错
     this.name = name;
}
say(){
  xxxx
}
}

要实现继承 就使用class了。