JavaScript 定义类的 4 种方法以及实现继承的 3 种方法

251 阅读2分钟

「这是我参与11月更文挑战的第10天,活动详情查看:2021最后一次更文挑战

JavaScript 定义类的 4 种方法

1.工厂方法:

//工厂方法
function creatCar(name){
    var obj = new Object();
    obj.name = name;
    obj.sayName =function(){
        console.log(this.name);
    }
    return obj
}
var i = creatCar("leilei")
var b = creatCar("leileilei")
i.sayName()
b.sayName()

显然工厂就行车间嘛,这样书写可以很方便创建多个相同的类

2.构造函数方法:

//构造函数方法
function Person(name, age){
    this.name = name;
    this.age = age;
    this.sayName = function(){
        console.log(this.name);
    };
}
var i = new Person("leilei", 12);
i.sayName()

3.原型方法:

//原型方法
function Person(){}
Person.prototype = {
    constructor:Person,
    name: "Ning",
    age:23,
    sayName: function(){
        console.log(this.name);
    }
};
var i = new Person();
i.sayName()

4.组合使用构造函数和原型方法:

function Person(name, age) {
    this.name = name;
    this.age = age;
}
Person.prototype = {
    constructor:Person,
    sayName: function(){
        console.log(this.name);
    }
}
var i = new Person("leilei",23);
i.sayName()

实现继承的 3 种方法

首先我们先定义一个父类

// 定义一个动物类
function Animal(name) {
    // 属性
    this.name = name || 'Animal';
    // 实例方法
    this.sleep = function () {
        console.log(this.name + '正在睡觉!');
    }
}
// 原型方法
Animal.prototype.eat = function (food) {
    console.log(this.name + '正在吃:' + food);
};
var i = new Animal("老虎")
i.eat("肉")

1、原型链继承

核心: 将父类的实例作为子类的原型

    
function Cat() {}
Cat.prototype = new Animal();
Cat.prototype.name = 'cat';

// Test Code
var cat = new Cat();
console.log(cat.name);
cat.eat('fish');
cat.sleep();
console.log(cat instanceof Animal); //true 
console.log(cat instanceof Cat); //true

特点:

非常纯粹的继承关系,实例是子类的实例,也是父类的实例

父类新增原型方法/原型属性,子类都能访问到

简单,易于实现

缺点:

要想为子类新增属性和方法,必须要在new Animal()这样的语句之后执行,不能放到构造器中 无法实现多继承

来自原型对象的引用属性是所有实例共享的

创建子类实例时,无法向父类构造函数传参

推荐指数:★★(3、4两大致命缺陷)

2、构造继承

核心:使用父类的构造函数来增强子类实例,等于是复制父类的实例属性给子类(没用到原型

function Cat(name) {
    Animal.call(this);
    this.name = name || 'Tom';
}

// Test Code
var cat = new Cat();
console.log(cat.name);
cat.sleep();
console.log(cat instanceof Animal); // false
console.log(cat instanceof Cat); // true

特点:

解决了1中,子类实例共享父类引用属性的问题

创建子类实例时,可以向父类传递参数

可以实现多继承(call多个父类对象)

缺点:

实例并不是父类的实例,只是子类的实例

只能继承父类的实例属性和方法,不能继承原型属性/方法

无法实现函数复用,每个子类都有父类实例函数的副本,影响性能

推荐指数:★★(缺点3)

3、实例继承

核心:为父类实例添加新特性,作为子类实例返回

function Cat(name){
  var instance = new Animal();
  instance.name = name || 'Tom';
  return instance;
}
 
// Test Code
var cat = new Cat();
console.log(cat.name);
console.log(cat.sleep());
console.log(cat instanceof Animal); // true
console.log(cat instanceof Cat); // false

特点:

不限制调用方式,不管是new 子类()还是子类(),返回的对象具有相同的效果

缺点:

实例是父类的实例,不是子类的实例

不支持多继承

推荐指数:★★