原型和继承知识点

99 阅读2分钟

🍒将User设为ln的原型的方法

<script>
        let User = {
            show(){
                return this.name
            }
        }
        console.dir(User);
   
        let ln = {
            name:'lily',
        }

        //将User设置为ln的原型
        Object.setPrototypeOf(ln,User)
        console.dir(ln);
    </script>

🍑使用serPrototypeof()后ln不仅有了自己的属性name,同时还继承了User的方法和属性

截屏2022-04-22 下午1.58.54.png

🍑获取ln的原型方法使用getPrototypeof()

console.log(Object.getPrototypeOf(ln));

截屏2022-04-22 下午2.03.04.png

🍒关于为什么原型上我们改变原型值的时候,如果属性不是对象则不会被改变?

let ln = {
            name:'lily',
        };
        ln.__proto__ = {
            show(){
                console.log(this.name);
            }
        }
        ln.show();//lily

        ln.__proto__ = 99;

        console.log(ln.__proto__)

为什么?虽然我们改变__proto__但是因为类型不同,改变不成功

原因:原型中原型中有 get __ proto__,set __proto__并不是严格意义上的属性,他是get和set会对设置的值自动进行判断的,

截屏2022-04-22 下午2.23.53.png

如何自主改变__proto__呢?

let ln = Object.create(null);//将原型为空
        ln.__proto__ = 99;
        console.dir(ln);
        console.log(ln.__proto__);

🌈成功改变!

截屏2022-04-22 下午2.30.05.png

🍒改变构造函数的原型并不是继承

//原型的继承,而不是改变构造函数的原型
        function user(){};
        user.prototype.name = function(){
            console.log("user.name");
        }
        let ln = new user();
        ln.name();//user.name

        function Admin(){}
            Admin.prototype = user.prototype;
            Admin.prototype.role = function(){
                console.log("admin.name");
        };

        function Member(){};
        Member.prototype = user.prototype;
        Member.prototype.role = function(){
            console.log("member.name");
        }

        let member = new Member();
        member.name();//user.name
        member.role();//member.name
        let admin = new Admin();
        admin.role();//member.name

可以从上图可得知,Admin,Member都将原型引用了user的原型,可以使用uer的方法和属性,但是,这使得他们自己的方法都放在了user.prototype中,相同名称的方法就会覆盖原来的值

🍒那如何继承呢?--利用对象的__proto__完成继承

//原型的继承
 function user(){};
        user.prototype.name = function(){
            console.log("user.name");
        }
        let ln = new user();
        ln.name();//user.name

        function Admin(){}
            Admin.prototype.__proto__ = user.prototype;
            Admin.prototype.role = function(){
                console.log("admin.name");
        };

        function Member(){};
        Member.prototype.__proto__  = user.prototype;
        Member.prototype.role = function(){
            console.log("member.name");
        }

        
        let member = new Member();
        member.name();//user.name
        member.role();//member.name
        let admin = new Admin();
        admin.role();//admin.name

🌈过程:和改变构造函数的原型方法不同,构造方法自身的方法互不影响,仍然能继承到user的方法和属性

截屏2022-04-22 下午3.49.47.png

🍒使用原型工厂封装继承

// sub 继承 sup
        function extend(sub,sup){
            // sub.prototype.__proto__ = sup.prototype;
            //创建了一个新的对象,这个对象的原型指向sup.prototype,sub.prototype指向这个新的对象
            sub.prototype = Object.create(sup.prototype);
            Object.defineProperty(sub.prototype,"constructor",{
                value:sub,
                enumerable:false//不可以被调用
            }) ;
        }

            
            function User(name,age){
                this.name = name;
                this.age = age;
            }

            User.prototype.show = function(){
                console.log(this.name,this.age);
            }

            function Admin(...args){
                User.apply(this,args);
            }
            extend(Admin,User);
            let admin = new Admin("admin",18);
            admin.show();

            function Member(...args){
                User.apply(this,args);
            }
            extend(Member,User);
            let member = new Member("member",24);
            member.show();

🍒使用对象工厂实现继承

 function User(name,age){
            this.name = name;
            this.age = age;
        }
        User.prototype.show = function(){
            console.log(this.name,this.age)
        }

        function admin(name,age){
            const instance = Object.create(User.prototype);
            User.call(instance,name,age);
            instance.role = function(){
                console.log("is admin");
            }
            return instance;
        }
        let ln = admin('ln',25);
        ln.show();
        ln.role();

        function member(name,age){
            const instance = Object.create(User.prototype);
            User.call(instance,name,age);
            return instance;
        }
        let lily = member('lily',21);
        lily.show();

🍒多继承

//错误示范,用延长原型链的方式完成多继承会使有的方法都被继承了,冗余。
        function Credit(){}
        extend(Request,Credit);
        Credit.prototype.total = function(){
            console.log("积分统计");
        }

        function Request(){}
        extend(User,Request);
        Request.prototype.ajax = function(){
                console.log("请求数据");
        }
        
        function User(name,age){
            this.name = name;
            this.age = age;
        }
        extend(Admin,User);
        User.prototype.show = function(){
            console.log(this.name,this.age);
        }

        function Admin(name,age){
            User.call(this,name,age);
        }
        
        let admin = new Admin('lily',21);
        admin.show();
        admin.ajax();
        admin.total();

如图: image.png

// 方法变为对象
        const Address = {
            getaddress: function(){
                    console.log("地址管理");
                } 
        }

        const Credit = {
            total: function(){
                console.log("积分统计");
            }
        }

        const Request = {
            ajax : function(){
                console.log("请求数据");
            }
        }
        
        function User(name,age){
            this.name = name;
            this.age = age;
        }
        User.prototype.show = function(){
            console.log(this.name,this.age);
        }

        function Admin(name,age){
            User.call(this,name,age);
        }
        extend(Admin,User);
        Admin.prototype = Object.assign(Admin.prototype,Credit,Request);//属性合并
        let admin = new Admin('lily',21);
        admin.show();
        admin.ajax();
        admin.total();

        function Member(name,age){
            User.call(this,name,age);
        }
        extend(Member,User)
        Member.prototype = Object.assign(Member.prototype,Address,Credit);
        let member = new Member("tomy",25);
        member.getaddress();
        member.total();