面向对象

面向对象

类与实例

类的声明

生成实例

类与继承

继承的本质就是原型链

如何实现继承

继承的几种方式

源码

oop.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>面向对象</title>
</head>
<body>
<script type="text/javascript">

    //类的声明
    function Animal(){
        this.name = 'name';
    }

    //ES6中的class声明
    class Animal2{
        constructor() {
            this.name = name;
        }
    }

    //实例化一个类的对象
    console.log(new Animal(), new Animal2());

    //类的继承

    //1.借助构造函数实现继承:原型链没有被继承,仅实现部分继承
    function Parent1() {
        this.name = 'parent1';
    }

    //Parent1.prototype.say = function() {};没有被继承
    function Child1() {
        Parent1.call(this);//apply 将父级的构造函数this的指向子级构造函数的实例,实现继承
        this.type = 'child1';
    }

    console.log(new Child1());

    //2.原型链实现
    function Parent2(){
        this.name = 'parent2';
        this.play = [1,2,3];
    }
    function Child2() {
        this.type = 'child2';
    }
    Child2.prototype = new Parent2();//函数具有prototype属性 ,是一个对象 可任意赋值 -父级的实例
    console.log(new Child2());

    var S1 = new Child2();
    var S2 = new Child2();
    console.log(S1.play, S2.play);//
    S1.play.push(4);//缺点:原型链中的原型对象是共用的,所以实例改变其值,其他实例对应的属性也会变

    //3.组合方式继承 缺点:父级的构造函数执行了两次,并把父类的constructor也继承了
    function Parent3() {
        this.name = 'parent3';
        this.play = [1,2,3];
    }
    function Child3() {
        Parent3.call(this);
        this.type = 'child3';
    }

    Child3.prototype = new Parent3();
    var S3 = new Child3();
    var S4 = new Child3();
    S3.play.push(4);
    console.log(S3.play, S4.play);

    //组合继承优化1 缺点:把父类的constructor也继承了
    function Parent4() {
        this.name = 'parent4';
        this.play = [1,2,3];
    }
    function Child4() {
        Parent4.call(this);
        this.type = 'child4';
    }

    Child4.prototype = Parent4.prototype;//引用同一个对象
    var S5 = new Child4();
    var S6 = new Child4();
    console.log(S5, S6);

    console.log(S5 instanceof Child4, S5 instanceof Parent4);
    console.log(S5.constructor); //Parent4

    //组合继承优化2 原理是通过Object.create方法创建一个中间对象,参数是该对象的原型对象,然后把子类的构造函数赋值为该子类
    function Parent5() {
        this.name = 'parent5';
        this.play = [1,2,3];
    }
    function Child5() {
        Parent5.call(this);
        this.type = 'child5';
    }

    Child5.prototype = Object.create(Parent5.prototype);//达到了父类和子类的隔离 .__proto__ 

    Child5.prototype.constructor = Child5;

    var S7 = new Child5();
    console.log(S7 instanceof Child5, S7 instanceof Parent5);
    console.log(S7.constructor);

</script>
</body>
</html>