手写 Es5 和 Es6 构造函数 & 继承 (的区别)

120 阅读2分钟

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

此篇内容:手写或者口述Es5 和 Es6 闭包 和 继承

首先我们得知道构造函数是什么,怎么书写,才能知道他们的区别是什么

构造函数时是用来干什么的?

用来创建实例对象

构造函数的规则?

new 关键字来调用
用this来构造他的属性记方法
首字母一般大写(约定俗成)

声明构造函数

function Zhangsan (name) {
    this.name = name  // 为示例对象添加属性
}

Zhangsan.prototype.run = function() {   // 为示例对象添加方法
    console.log('张三在跑步')  
}

接下来我们再声明一个叫做李四的构造函数,然后让他继承张三的属性和方法

function Lisi (name) {
    this.name = name  // 为示例对象添加属性
}

Lisi.prototype.run = function() {   // 为示例对象添加方法
    console.log('李四在跑步')  
}

接下来是实现继承的关键代码,我会一一注释并解释的(此部分代码如有疑问可以逐行打印)

var zhangsan1 = new Zhangsan('张三1')   // 构造出一个叫做张三的对象
Lisi.prototype = zhangsan1   // 让lisi这个构造函数的prototype指向叫做张三的构造函数
var lisi1 = new Lisi('李四1')   // 构造出一个叫做李四的对象

到这一步就算是实现了继承,现在lisi1这个对象既可以拿到本身的属性,也可以拿到张三的属性,(方法也是一样,直接用.取就可以),

实现这种继承方式的主要代码是lisi.prototype = zhangsan1 ,将父类的实例作为子类的原型,这种的是最基本的继承方式(本篇只写这种简单的继承方式,有兴趣可以取了解一下别的),其他的继承都是从这种继承方式演变而来的

这种继承也有一定的缺点 :父类构造函数里的属性值改变的话,所有子类构造函数的值都会改变,代码如下:

var lisi2 = new Lisi('李四2') // 构造出一个叫做李四的对象
lisi1.name = '李四改变了'

这个时候你再去打印就会发现lisi2也会变(想要解决可以取具体搜一下)

--------------------------------------------------分割线,下边是Es6------------------------------------------------

声明构造函数

class Zhangsan {
    constructor(name) { this.name = name }
    say() { console.log(this.name) }
}

Zhangsan.prototype.run = function() {   // 为示例对象添加方法
    console.log('张三在跑步')  
}

接下来我们再声明一个叫做李四的构造函数,然后让他继承张三的属性和方法

class Lisi extends Zhangsan {
        constructor(name, id) {
            super(name);  // 必须使用super,具体可以百度
            this.id = id;
        }
        say1() { console.log(this.name, this.id) }
    }
let zhangsan = new Zhangsan('name', 1)
let lisi = new Lisi('name', 2)
zhangsan.name = 'change'
console.log(zhangsan)
console.log(lisi)