JavaScript面向对象之继承(下)

版权声明:刘家军 https://blog.csdn.net/qq_42911663/article/details/85502719

原型式继承

这种继承方式没有使用严格意义上的构造函数,借助原型还可以基于已有的对象创建新对象,同时还不必因此创建自定义类型

function object(o) {
    function Fun() {}
    Fun.prototype = o;
    return new Fun();
}

在object函数内部,先创建一个临时性的构造函数Fun,然后将传入的对象作为这个构造函数的原型,最后返回这个临时类型的一个新实例。
本质上来说,object对传入其中的对象执行了一次浅复制。

function object(o) {
function Fun() {}
Fun.prototype = o
return new Fun()
}
const Person = {
    name: "姓名",
    hobby: ["旅游","电影"]
}

const LJJ = object(Person)
LJJ.name =  "刘家军"
LJJ.hobby.push("敲代码")

const YH = object(Person)
YH.name = "袁姮"
YH.hobby.push("购物")

console.log(LJJ);
console.log(YH);
console.log(Person);

输出:
在这里插入图片描述
ES5新增Object.create规范了原型式继承

Object.create

Object.create()这个方法我在写js原型和原型链时简单介绍过了,如果还有什么不了解查看js权威文档MDN(Object.create)
看下面三种创建对象的方法

console.log(Object.create(null))
console.log(new Object())
console.log({})

输出:
在这里插入图片描述
可以看出第一种创建方法最干净;
我们继续看代码:

const Person = {
    name: "姓名",
    hobby: ["旅游","看电影"]
};
const LJJ = Object.create(Person, {
    private : {
        value: "私有的", // private 属性值
        writable:true // 属性可写
    }
});
LJJ.name = "刘家军"
LJJ.hobby.push("唱歌")
LJJ.private = "敲代码"
console.log(LJJ.private) // 敲代码
//--------------------------------------
const Person = {
    name: "姓名",
    hobby: ["旅游","看电影"]
};
const YH = Object.create(Person, {
    private : {
        value: "私有的", // private 属性值
        writable: false // 属性不可写
    }
});
YH.name = "袁姮"
YH.hobby.push("美食")
YH.private = "购物"
console.log(YH.private) // 私有的

private 的属性还有很多 详细请看js权威文档 MDN

区别

1.Object.cerate()继承指定对象
2.new Object() 继承内置对象Object
3.可以通过Object.create(null) 创建一个干净的对象,也就是没有原型,而 new Object() 创建的对象是 Object的实例,原型永远指向Object.prototype。

寄生式继承

寄生式继承是与原型式继承紧密相关的一种思路,它创造一个仅用于封装继承过程的函数,在函数内部以某种方式增强对象,最后再返回对象。

function object(o) {
    function F() {}
    F.prototype = o;
    return new F();
}

function clone(params) {
    const proto= object(params) //通过调用函数创建一个新对象
    return proto
}
const Person = {
    name: "姓名",
    hobby: ["旅游","看电影"]
}
const LJJ = clone(Person);
LJJ.name = "刘家军"
LJJ.hobby.push("敲代码")
console.log(LJJ)

输出:
在这里插入图片描述
寄生式继承和原型式继承,方法接近

寄生组合式继承

组合继承有个弊端就是会调用两次被继承者的构造函数,解决方法就是使用寄生组合式继承。这又是什么呢?这个相对之前的比较复杂,但是高效的一点是只调用一次被继承者构造函数,原理就是通过寄生方式创建一个被继承者的副本,副本和被继承者共用一个prototype,这样就解决了之前的问题

function object(o) {
    function F() {}
    F.prototype = o;
    return new F();
}
function clone(Children, Person) {
    const proto = object(Person.prototype) // 返回Person的一个副本
    proto.constructor= Children // 设置constructor指向, 因为新副本的原型对象被重写
    Children.prototype = proto // 副本作为Children的原型对象
}

function Person() {
    this.name = "姓名"
}
Person.prototype.sayName = function() {
console.log(this.name)
}
function Ljj() {
    Person.call(this)
    this.name = "刘家军"
}

function Yh() {
    Person.call(this)
    this.name = "袁姮"
}
clone(Ljj, Person)
clone(Yh, Person)
const LJJ = new Ljj()
const YH = new Yh()
LJJ.sayName() // 刘家军
YH.sayName() // 袁姮

猜你喜欢

转载自blog.csdn.net/qq_42911663/article/details/85502719