讲讲JS中的类、继承和单例

本篇分别通过 ES5 和 ES6 讲述JS中的类、静态方法、继承和单例

ES5 类和静态方法

1、构造函数里面的方法和属性与原型链上的方法和属性都叫做:实例方法。要调用必须通过实例化构造函数(Person类),静态方法直接通过构造函数(类名)进行调用

2、原型链上的属性和方法可以被多个实例共享,而构造函数里面的方法和属性不会被多个实例共享

 // 通过构造函数来定义类
 function Person(name, age) {
     // 构造函数里面的方法和属性
     this.name = name;
     this.age = age;
     this.run = function() {
         console.log(`${this.name} - ${this.age}`)
     }
 }

 // 构造函数原型链上的属性和方法
 Person.prototype.sex = '男';
 Person.prototype.work = function() {
     console.log(`${this.name} - ${this.age} - ${this.sex}`)
 }

 // 静态方法
 Person.setName = function() {
    console.log('静态方法')
 }

 // 实例方法是通过实例化来调用的
 var p = new Person('zhangsan', '20');
 p.run()
 p.work()

 // 静态方法是通过类名直接调用
 Person.setName()

ES5 继承

原型链继承和对象冒充继承:

  • 对象冒充继承:可以实现将参数传递到父类,但是没法继承原型链上的属性和方法
  • 原型链继承:可以继承构造函数里面以及原型链上面的属性和方法,但是实例化子类的时候没法给父类传参

所以平时都是两者结合起来实现继承

function Person(name, age) {
    this.name = name;
    this.age = age;
    this.run = function() {
        console.log(this.name + '-' + this.age);
    }
}

Person.prototype.work = function() {
    console.log('work')
}

function Web(name, age) {
    // 通过 call(),能够使用属于另一个对象的方法。
    // 此处相当于 Web 函数去调用Person类,并传值name,age
    Person.call(this, name, age) // 对象冒充实现继承,可以实现将参数传递到父类
}

Web.prototype = new Person() // 原型链继承,但是原型链继承在实例化时没法将参数传递到父类里面
var w = new Web('李四', 20)
w.run() // 测试调用构造函数里面的方法
w.work() // 测试调用原型链上的方法

ES6 类

class Person {
    constructor(name, age) { // 类的构造方法,实例化的时候执行,new的时候执行
        this._name = name;
        this._age = age;
    }
    // 定义方法,注意:es6里面方法之间没有逗号(,)
    getName() {
        console.log(this._name)
    }
    setName() {
        this._name = name
    }
}
var p = new Person('张三', '20')
p.setName('李四')
p.getName()

ES6 继承

class Person {
    constructor(name, age) {
        this.name = name
        this.age = age
    }
    getInfo() {
        console.log(`姓名:${this.name} - 年龄:${this.age}`)
    }
    run() {
        console.log('run')
    }
}
class Web extends Person {
    constructor(name, age ,sex) {
        super(name, age) // 实例化子类的时候把子类的数据传给父类
        this.sex = sex
    }
    print() {
        console.log(this.sex)
    }
}
var w = new Web('张三', '30', '男')
w.print() // 调用自己的方法
w.getInfo() // 调用父类方法

ES6 静态方法

class Person {
    constructor(name) { // 属性
        this._name = name
    }
    run() { // 实例方法
        console.log(this._name)
    }
    static work() { // 静态方法
        console.log('这是es6中的静态方法')
    }
}

// 或者通过这种方式定义类的静态方法
Person.instance = '这是一个静态方法的属性'

var p = new Person('张三')
p.run()
Person.work() // 通过类名来调用静态方法
console.log(Person.instance)

ES6 单例

使用场景:nodejs连接mongodb数据库,只连接成功一次,然后之后每次操作数据库都使用本次连接后的实例,不用每次都重新连接

class DB {
    static getInstance() { // 单例
        if (!DB.instance) {
            DB.instance = new DB()
        }
        return DB.instance
    }
    constructor() {
        console.log('实例化会触发构造函数')
        this.connect()
    }
    connect() {
        console.log('连接数据库')
    }
    find() {
        console.log('查询数据库')
    }
}
var myDb1 = new DB()
var myDb2 = new DB() // 验证发现:每次实例化都会执行构造函数重新进行连接数据库。 所以对性能产生影响,采用单例模式进行处理

var myDb3 = DB.getInstance() // 单例实例化:实例化多次但只会调用一次构造函数,然后各自调用实例方法互不影响
myDb3.find()
var myDb4 = DB.getInstance()
myDb4.find()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值