js 实现继承的6种方式(逐渐优化)

<!DOCTYPE html>
<html lang="zh">

    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <meta http-equiv="X-UA-Compatible" content="ie=edge" />
        <title>实现继承的5种方式(逐渐优化)</title>
    </head>

    <body>

        <script type="text/javascript">
            //方法1 使用构造函数
            function Parent1(name) {
                this.name = name || 'meng';
            }

            function Child1(age) {
                Parent1.call(this)
                this.age = age;
            }
            let c1 = new Child1(20)
            console.log(c1)
            //方法2 使用原型
            function Parent2(name) {
                this.name = name || 'meng';
                // 对于这种是有问题的,因为子类共用一个原型
                this.friend = [1, 2, 3]
            }

            function Child2(age) {
                this.age = age;
            }
            //不能使用Parent2.prototype,否则c2.friend.push会报错,因为Parent2.prototype的原型上没有friend属性
            //Child2.prototype = Parent2.prototype
            Child2.prototype = new Parent2()
            let c2 = new Child2(21)
            let c3 = new Child2(22)
            c2.friend.push(4)
            console.log(c2)
            console.log(c3)
            //组合继承
            function Parent3(name) {
                this.name = name || 'meng';
                this.friend = [1, 2, 3]
            }

            function Child3(age) {
                Parent3.call(this)
                this.age = age;
            }
            Child3.prototype = new Parent3()
            let c4 = new Child3(21)
            let c5 = new Child3(22)
            c4.friend.push(4)
            console.log(c4)
            console.log(c5)
            //组合继承优化1 只调用一次构造函数
            function Parent4(name) {
                this.name = name || 'meng';
                this.friend = [1, 2, 3]
            }

            function Child4(age) {
                Parent4.call(this)
                this.age = age;
            }
            Child4.prototype = Parent4.prototype
            let c6 = new Child4(21)
            let c7 = new Child4(22)
            c6.friend.push(4)
            console.log(c6)
            console.log(c7)
            //组合继承优化2 使用Object.create
            function Parent5(name) {
                this.name = name || 'meng';
                this.friend = [1, 2, 3]
            }

            function Child5(age) {
                Parent4.call(this)
                this.age = age;
            }
            Child5.prototype = Object.create(Parent5.prototype)
            Child5.prototype.constructor = Child5
            let c8 = new Child5(21)
            let c9 = new Child5(22)
            c8.friend.push(4)
            console.log(c8)
            console.log(c9)
            //es6
            class Parent6 {
                constructor(name) {
                    this.name = name || 'meng'
                    this.friend = [1, 2, 3]
                }
            }

            class Child6 extends Parent6 {
                constructor(name, age) {
                    super(name);
                    this.age = age
                }
            }
            let c10 = new Child6(21)
            let c11 = new Child6(22)
            c10.friend.push(4)
            console.log(c10)
            console.log(c11)
        </script>
    </body>

</html>

 其中第五种方法:

Object.create这种方式实现了将父类和子类的的原型完美分隔 。双方不会互相影响,也就是说这是确实可行较好的继承实现方式。

原文地址:https://www.cnblogs.com/mengfangui/p/10220537.html