zoukankan      html  css  js  c++  java
  • js函数的对象的继承

    1.原型链继承:将父亲的实例赋给子类的原型。

    缺点:如果有一个子类实例改变所继承的内容,则当下一个子类实例继承是会是上一个子类改变之后的内容,而不是原有父亲的内容。

    (解决:对象冒充继承方法)

    function Father(name, age) {
                this.name = 'li';
                this.age = 3;
                this.arr = [1, 2, 3];
            }
            function Son(sex) {
                this.sex = sex;
            }
            Son.prototype = new Father; //将父类的实例赋值给子类的原型
            var son1 = new Son('男'); //new一个子类的实例son1
            var son2 = new Son('女'); //new一个子类的实例son2
            console.log(son1.arr); //打印son1继承的属性arr  [1, 2, 3]
            son1.arr.push(4); //通过son1改变arr的值 此时改变的是子类的原型链
            console.log(son2.arr); //再用son2打印arr值   [1, 2, 3, 4]

    2.对象冒充继承: 通过call或其他方法改变父类中的this指向,让父类的this指向那子类,这样子类实例对象就可以使用父类中的属性和方法。

    优点: 解决了原型链继承引用类型共用的问题 。

    缺点:不能调用父类原型链中的方法函数。(解决:组合模式方法)

    function Father(name, age) {
                this.name = 'li';
                this.age = 3;
                this.arr = [1, 2, 3];
                this.sayHi = function() {
                    return 'Hi' + this.name;
                }
            }
            Father.prototype.showName = function() {
                return this.name;
            }
    
            function Son(sex) {
                Father.call(this); //通过call改变Father的this指向Son,这样就可以使Son中拥有Father的属性
                this.sex = sex;
            }
            var son1 = new Son('男');
            console.log(son1); //Son {nme: "li", age: 3, arr: Array(3), sex: "男", sayHi: ƒ}
            console.log(son1.name); //li
            console.log(son1.sayHi()); //可以调用父类本身具有的方法  Hili
            // console.log(son1.showName()); //报错 son1.showName is not a function
            //缺点:不能调用父类原型链中的方法函数
    
            //----------------------------------------------------------
            //解决了原型链中一个子类对象改变父类属性会影响其他子类的问题
            son1.arr.push(4);
            console.log(son1.arr); //[1, 2, 3, 4]
            var son2 = new Son();
            console.log(son2.arr); //[1, 2, 3]

    3.组合继承:利用对象冒充继承父类本身的属性和方法,利用原型链继承父类原型上的方法

    优点:解决了不能调用父类原型链中的方法函数;

    缺点: 1.相同的属性,在原型链上出现了两次(读取没有问题,因为子实例上面的屏闭了 原型上面的属性)

    2.父类的构造函数调用了两次

    解决:寄生组合继承

    function Father(name, age) {
                this.name = 'li';
                this.age = 3;
                this.arr = [1, 2, 3];
                this.sayHi = function() {
                    return 'Hi' + this.name;
                }
            }
            Father.prototype.showName = function() {
                return this.name;
            }
    
            function Son(sex) {
                Father.call(this); //通过call改变Father的this指向Son,这样就可以使Son中拥有Father的属性 调用一次
                this.sex = sex;
            }
            Son.prototype = new Father(); //通过原型链继承父类原型中的方法 调用两次
            var son1 = new Son('男');
            console.log(son1); //Son {name: "li", age: 3, arr: Array(3), sex: "男", sayHi: ƒ}
            console.log(son1.showName()); //li
            console.log(son1.sayHi()); //Hili

    可以看到age,arr,name,sayHi在原型链中出现了两次。

     

    4.寄生组合继承:(完美)

    function Father(name, age) {
                this.name = 'li';
                this.age = 3;
                this.arr = [1, 2, 3];
                this.sayHi = function() {
                    return 'Hi' + this.name;
                }
            }
            Father.prototype.showName = function() {
                    return this.name;
                }
                //  Son.prototype = new Father;//不能直接继承父类
                // 父的实例,不能直接赋给子的原型,利用一个中间函数中转一下
            function Son(sex) {
                Father.call(this); // 利用对象冒充继承继承属性Father的属性
                this.sex = sex;
            }
    
            // var F = function() {};
            // F.prototype = Father.prototype;
            // Son.prototype = new F();
            // Son.prototype.constructor = Son;
            inherits(Son, Father); // 调这个封装函数,相当于上面四句话
            // 子的原型上的方法,必须在调用inherits以后,再添加
            var son1 = new Son('男');
            console.log(son1.showName()); //li
            function inherits(Child, Parent) {
                var F = function() {};
                F.prototype = Parent.prototype;
                Child.prototype = new F();
                Child.prototype.constructor = Child;
            }
  • 相关阅读:
    android viewpager嵌套使用photoview异常问题
    android mvp设计模式
    android webview处理h5打开本地文件浏览器的功能
    使用python进行新浪微博粉丝爬虫
    android之ViewPager修改滑动速度
    我眼中的“阿里月饼事件”
    奄奄一息雏鸟
    RPC(远程过程调用)的应用
    对于开源菜谱的思考
    我跟360上网导航的过招
  • 原文地址:https://www.cnblogs.com/ximenchuifa/p/13498139.html
Copyright © 2011-2022 走看看