美文网首页
Js原型链及继承 proto、prototype的关系

Js原型链及继承 proto、prototype的关系

作者: 踩坑怪At芬达 | 来源:发表于2019-10-29 15:37 被阅读0次

    如果觉得还有点用,请您给我一个赞!您的赞是我坚持下去的动力!

    目标:理解原型链及实现类的功能

    先看一段代码输出结果然后再来分析

    function Bar() {
      this.bar = 42;
    }
    Bar.answer = function() {
      return 42;
    };
    Bar.prototype.print = function() {
      console.log(this.bar);
    };
    
    var tBar=new Bar();
    
    Object.keys(Bar) // ['answer']
    Object.keys(Bar.prototype) //['print']
    Object.keys(Bar.__proto__) //[]
    
    
    Object.keys(tBar) //['bar']
    Object.keys(tBar.prototype) // undefined
    Object.keys(tBar.__proto__) // ['print']
    
    

    这里顺便对比一下class的区别,可以发现类的方法成员不能被枚举

    
    class Bar{
        constructor(){
            this.bar=42;
        }
        print(){
            console.log(this.bar);
        }
    }
    var tBar=new Bar();
    
    
    Object.keys(Bar) // []
    Object.keys(Bar.prototype) //[]
    Object.keys(Bar.__proto__) //[]
    
    
    Object.keys(tBar) //['bar']
    Object.keys(tBar.prototype) // undefined
    Object.keys(tBar.__proto__) // []
    
    prototype1.png

    通过代码来看结构

    prototype2.png call_apply_bind.png

    实现一个new操作符

    1.创建一个空对象
    2.链接到原型
    3.绑定this值
    4.返回新对象

    function create(fn,...args){
      let obj = Object.create(fn.prototype);
    
      //调用new对象的构造函数,并把this绑定为obj
      let result = fn.apply(obj,args);
    
      return typeof result==='object'?result:obj;
    }
    

    实现一个类的继承功能,让子类继承父类功能,并且子类的相同功能覆盖父类

    
        function ext(son,father){
            //遍历当期那子类的所有方法,如果出现重复,则不用父类覆盖子类
            for( var param in father.prototype ){
                if( !son.__proto__[param ]){
                    son.__proto__[param] = father.prototype[param];
                }else{
                    son.__proto__[param].super = father.prototype[param];//【可选】将父类方法预留到super内,以备调用
                }
            }
            //先调用父类构造方法进行初始化
            father.apply(son,arguments[2]);
            //创建runSuper方法,用于调用父类的同名方法【可选】
            son.runSuper = function(funName,args){
                if(this.__proto__[funName].super)this.__proto__[funName].super.apply(this,args);
            }.bind(son);
        }
        
        //使用方法如下
        function Father(name){
            this.name= name;
        }
        Father.prototype.age = function(age){
            console.log('father name is ' + this.name +' ,age is ' + age);
        };
    
        function Son(name){
            ext(this,Father,arguments);
        }
        Son.prototype.age = function(age){
            this.runSuper('age',arguments);//【可选】运行父类方法
            console.log('son name is ' + this.name +' ,age is ' + age);
        };
        var son = new Son("cx");
        son.age(23);
        //output:
        //father name is cx ,age is 23
        //son name is cx ,age is 23
    
    

    相关文章

      网友评论

          本文标题:Js原型链及继承 proto、prototype的关系

          本文链接:https://www.haomeiwen.com/subject/vkhgvctx.html