JS中的继承

1.基于原型的继承

            function Person() {
                this.name = 'zhangsan';
            }

            function Woman(age) {
                this.age = age;
            }
            Woman.prototype = new Person();
            var woman1 = new Woman(18);
            console.log(woman1); //Woman {age: 18}age: 18__proto__: Personname: "zhangsan"__proto__: Object

通过原型链,将子类构造函数的原型对象(prototype)重写,赋值为一个父类的实例,因为每个实例都会有一个proto指针指向自身的原型对象,而另一个父类的原型对象在次被重写,定义为一个实例,层层嵌套,就形成了原型的继承
缺点:不能传递参数,实例会共享所有引用类型的原型属性

2.借用构造函数的继承

            function Person (name) {
                this.name = name;
            }

            function Woman (name,age) {
                Person.call(this,name);
                this.age = age;
            }
            var woman1 = new Woman('zhangsan',18);
            console.log(woman1);        //Woman {name: "zhangsan", age: "zhangsan"}

将父类的构造函数在子类的上下文环境下调用,因为函数只是在特定环境下执行的对象,上面的代码中使用call(apply也是可以的),在要通过Woman方法新创建实例的时候,在实例环境下调用了Person的构造函数,这个时候因为执行上下文环境是在Woman中,this的指向是在Woman的实例,所以Woman的每个实例就会有name属性
缺点:函数都在构造函数中定义,函数无法复用

3.组合继承

            function Person (name) {
                this.name = name;
            }
            Person.prototype.test = function () {
                console.log(1);
            }

            function Woman (name,age) {
                Person.call(this,name);
                this.age = age;
            }
            Woman.prototype = new Person();
            Woman.prototype.test1 = function () {
                console.log(2);
            }
            var woman1 = new Woman('zhangsan',18);
            console.log(woman1);    //Woman {name: "zhangsan", age: 18}
            woman1.test();    //1

将原型链和借用构造函数继承组合到一起,通过原型链使用对方法和属性的继承,又能传递参数,实现对实例属性的继承
缺点:会调用两个超类型的构造函数,一次是在创建子类原型的时候,一次是在子类型构造函数的内部,第一次调用父类的构造函数,Woman的原型会得到一个属性(name),他们是父类的实例属性,只不过现在是位于Woman的原型对象上,当调用Woman的构造函数时,又会调用一次父类的构造函数,这一次是在实例对象上创建了实例属性name,这个name会屏蔽原型中的name

4.原型式继承

            function obj (o) {
                function F() {};
                F.prototype = o;
                return new F();
            }
            var obj1 = {
                name: 'zhangsan',
                age: 18
            }
            var obj2 = obj(obj1);
            console.log(obj2.name);        //zhangsan

原型式继承必须有一个对象作为另一个对象的基础,相当于对obj1进行了一次浅复制,这里可以看着对F的构造函数进行了重写,将o(一个实例化对象)赋值给了F的原型对象,然后返回的是一个F的实例,着和原型链的继承方式和类似

5.寄生式继承

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

            function createAnother(o) {
                var clone = obj(o);
                clone.test = function() {
                    console.log(1);
                };
                return clone;
            }
            var obj1 = {
                name: 'zhangsan',
                age: 18
            }
            var obj2 = createAnother(obj1);
            obj2.test();    //1
            console.log(obj2);

6.寄生组合式继承

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

            function AnotherObj(Woman, Person) {
                var prototype = obj(Person.prototype);
                prototype.constructor = Woman;
                Woman.prototype = prototype;
            }

            function Person(name) {
                this.name = name;
                this.sex = 'nan';
            }
            Person.prototype.test = function() {
                console.log(1);
            }

            function Woman(name, age) {
                Person.call(this, name);
                this.age = age;
            }
           AnotherObj(Woman, Person);
            Woman.prototype.test1 = function() {
                console.log(2);
            }

            var woman1 = new Woman('zhangsan', 18);
            console.log(woman1); //Woman {name: "zhangsan", age: 18}
            woman1.test(); //1

优点:只调用了一次父类的构造函数(Person),并且避免了在子类的原型对象上面创建不必要的、多余的属性,而且子类的原型链可以保持不变,是理想型的继承实现的方式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值