es5和es6创建与使用构造函数,写给自己

这篇笔记是单纯的用来加深自己写构造函数和使用构造函数的,但是我要是在工作中大脑又宕机了,也可以自己来复习一下。

es5

先贴下es5最基础的创建与使用的代码吧,这个不能忘记吧,这要是忘了,就可以转行了!

// 创建一个构造函数,这里本质上就是一个类
function People (name, age) {
    this.name = name
    this.age = age
}

// 这里给类添加一个方法,在他的原型链上添加,这样每个实例出来的对象都会拥有这个方法,这是继承
People.prototype.getMyName = function(){
    console.log('这是一个实例方法')
    console.log('我的名字叫'+this.name)
}

// 使用构造函数来获得一个实例化对象
let p1 = new People('wilson', 28)     
console.log(p1)     
// {age: 28,name: "wilson"}
p1.getMyName()  // 继承方法的使用方式
// 这是一个实例方法
// 我的名字叫wilson

这里为啥在prototype里来创建方法呢?懒得说,听自己一句劝,这个要是忘了真别干了。

说到实例方法,还有一个静态方法,可以直接添加到构造函数上,上代码

// 除了在原型链上添加,在构造函数的本身也可以添加,但是这里的this指向就是构造函数了,而且也不需要使用实例化的对象,这里我们称为静态方法
People.getMyName = function(name){
    console.log('这是一个静态方法,不需要创建实例,谁都可以调用哦~')
    console.log('我的名字叫'+name)
}

People.getMyName('nameless')   // 静态方法的使用方式

// 这是一个静态方法,不需要创建实例,谁都可以调用哦~
// 我的名字叫nameless

这个用的最多的就是Math了,比如Math.max(5,9)获取最大值,想起来了吧?静态方法可以直接使用,和实例对象没啥关系,两码事。

好了,主要说的是继承,上面的例子已经实现了实例对象对原型中实例方法的继承,那么,如果有两个类,一个父类,一个子类,子类创建了一个实例对象,怎么让当前实例对象既有子类的属性方法,又有父类的集成方法呢?

举一个例子,父类是动物,动物都有名字,年龄,但不一定都有毛,所以我们把毛这一独特属性放在子类里,比如子类是狗吧。然后我们实例出一条狗看看。

// 这是父类动物类
function Animal(name, age) {
    this.name = name
    this.age = age
}
// 这是子类狗类
function Dog(name, age, hairColor) {
    Animal.call(this,name,age)
    this.hairColor = hairColor
}
let g1 = new Dog('dahuang', 2, 'yellow')

console.log(g1)

// {name:'dahuang', age: 2, hairColor: 'yellow'}

可以看到,这里利用了call方法改变了this的指向,让Dog使用了Animal的方法,这样就实现了继承类的属性,而独特属性就由子类自己实例化。但是实例方法并不能因此继承,现在我在原先的代码基础上加上方法继承,看好了

// 这是父类动物类
function Animal(name, age) {
    this.name = name
    this.age = age
}
Animal.prototype.getMyName = function(){
    console.log('我的名字叫' + this.name)
}
// 这是父类动物类
function Dog(name, age, hairColor) {
    Animal.call(this,name,age)
    this.hairColor = hairColor
}

Dog.prototype = new Animal()   // 让子类prototype指向父类的原型实例,这样就可以使用父类的实例方法了
Dog.prototype.constructor = Dog // 这里需要把prototype的constructor指回自己的原型,避免原型链的紊乱。这样就简单的完成了子类继承父类的方法继承。
let g1 = new Dog('dahuang', 2, 'yellow')
g1.getMyName()

// 我的名字叫dahuang

看到了吧,getMyName方法是父类的,子类创建的实例可以使用父类的实例方法,备注写的清清楚楚了,不描述了。如果你还看不懂,说明你需要把原型链再复习一遍了。

es6

有空了再帮你回忆。。。

现在是2023/2/7 晚上20:48,现在开始整理一下es6怎样写构造函数,在es6中,他叫类,也有了自己的语法糖——class!

// 首先我要创建一个父类,就叫People吧
class People {
    // 然后这里是类的属性,使用constructor关键字
    constructor(name, age){
        this.name = name
        this.age = age
    }
    // 这里定义类的方法
    getMyName(){
        console.log('我的名字叫' + this.name)
    }
}

let p1 = new People('wilson', 28)
console.log(p1)  //{name: 'wilson', age: 28}
p1.getMyName()  // 我的名字叫wilson

es6真的简写了好多啊,可读性也变高了。总结一下,属性放在constructor里,方法直接在类里创建,简单熬。接下来我们看一个东西

class People {
    constructor(name, age, sex = '--'){
        this.name = name
        this.age = age
        this.sex = sex
    }
}
let p1 = new People('wilson', 28)
p1.sex = '男'
console.log(p1.sex) // 男

这里我们再定义一个sex属性,可以看到我们直接给属性赋值是可以改变的,但是这样在业务逻辑中太草率了,其实class中提供了更优雅的方式。

get和set

class People {
    constructor(name, age, sex = '这是默认性别'){
        this.name = name
        this.age = age
        this._sex = sex
    }
    get sex(){
        return this._sex
    }
}
let p1 = new People('wilson', 28)
console.log(p1.sex)  // 这是默认性别
p1.sex = '女'  // error,这里就已经报错了
console.log(p1.sex)  

使用get可以使我们的sex成为只读属性,虽然sex后面有个括号,但是在使用时,他只是个属性,直接使用,不要加括号,然后在看一下set

class People {
    constructor(name, age, sex = '这是默认性别'){
        this.name = name
        this.age = age
        this._sex = sex
    }
    get sex(){
        return this._sex
    }
    set sex(val){
        this._sex = val
    }
}
let p1 = new People('wilson', 28)
console.log(p1.sex)  // 这是默认性别
p1.sex = '女'
console.log(p1.sex)  // 女

使用set,给_sex赋值,这样sex成了既可读又可修改的属性。但是注意了,我操作的_sex都是带着下划线的_sex我们不能直接操作set,必须有个新的变量来接受和修改,因为我们直接修改,会进入死循环,你修改sex,然后调用sex的set,给自己赋值,然后他又调用,又赋值,死循环了。

那么问题来了,我他妈是不是有病,直接用直接赋值不得了,为什么这么费劲多写这么多代码,不是说更优雅吗?

其实在业务场景中,后端更多的返回是一个字段的枚举,比如:1代表男,0代表女;也有可能会返回空字符串或者null,这样的话set和get就会体现出数据拦截和数据预处理的作用。举个例子,当前这个对象是一个user数据,status代表他的状态,0代表工作中,1代表请假

class People {
    constructor(name, age, status){
        this.name = name
        this.age = age
        this._status = status
    }
    get status(){
        if(this._status == 0){
            return '工作中'
        }else if(this._status == 1){
            return '请假'
        }else{
            return '暂无状态'
        }
    }
    set status(val){
        if(val == 0 || val == 1){
            this._status = val
        }
    }
}
let p1 = new People('wilson', 28)
console.log(p1.status) // 暂无状态
// 这里假装ajax获取到了最新的user状态
let res = 1
p1.status = res
console.log(p1.status) // 请假

首先get帮助了我们将status默认为"暂无状态",然后我们赋值时,set帮助了我们过滤了非0和1的值,最后再次取值的时候get帮我们把值匹配了对应的字符串“请假”上。

那么es6怎样继承呢

class People {
    constructor(name, age, status) {
        this.name = name
        this.age = age
        this._status = status
    }
    get status() {
        if (this._status == 0) {
            return '工作中'
        } else if (this._status == 1) {
            return '请假'
        } else {
            return '暂无状态'
        }
    }
    set status(val) {
        if (val == 0 || val == 1) {
            this._status = val
        }
    }
    getMyName() {
        console.log('我的名字叫' + this.name)
    }
}
// 上面的例子保留,我们给People创建一个子类,叫Niuma
class Niuma extends People {    // 这里用了一个关键词,extends就是继承的意思
    // 同样是用constructor来构造属性
    constructor(name, age, status, sex) {
        // 需要继承的属性用super关键词,
        super(name, age, status)
        this.sex = sex
    }
}
// 创建一个牛马
let n1 = new Niuma('wilson', 28, 0, '男')
console.log(n1) // {name: 'wilson', age: 28, _status: '', sex: '男'}
// 连stuts和方法都可以继承
console.log(n1.status) // 工作中
n1.getMyName()  // 我的名字叫wilson

是不是一看就懂。啥都不用操作,直接extends一键继承。

然后看看静态属性和静态方法

class People {
    static sayHello(){
        console.log('hello world')
    }
}
People.count = 3
People.sayHello()   // hello world
console.log(People.count)   // 3

既然是静态方法就不用创建实例,直接调用就可以了。需要注意的是静态方法需要static关键词打头,写在class里面,而静态属性和es5写法一样。

(写的差不多了,看的头疼就算了,反正你工作中也用不到)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值