【js笔记】有关原型和原型链

这里记录一下原型和原型链的理解

构造函数 原型对象 对象原型

构造函数里有一个对象prototype就是原型,构造函数实例化new出来一个实例对象,每个实例对象都有一个__proto__,这个__proto__指向构造函数的prototype原型,实例对象和构造函数的prototype原型都有一个constructor指向构造函数。构造函数的prototype原型也有个__proto__指向Object的prototype。

        function Father() {
            this.color = 'red'
            this.name = 'lv'
        }


        const Foo = new Father

        console.log(Foo.__proto__ === Father.prototype) //true
        console.log(Foo.__proto__.__proto__ === Object.prototype) //true

有关constructor

如果是给原型对象往里加属性,不会改变原型对象constructor指到构造函数上。如果是重新写了原型对象,会影响原型对象,导致没有constructor指到构造函数上。

        //这是给原型对象往里加属性,不会改变原型对象constructor指到构造函数上
        Father.prototype.year = function () {
            this.year = 18
        }





        //这是重新写了原型对象,会影响原型对象,导致没有constructor指到构造函数上
        Father.prototype = {
            age:18,
            fn:function(){
                console.log('22222')
            }
        }

        //这里的不管原型对象还是实例对象的constructor都找不到构造函数身上
        console.log(Father.prototype.constructor === Father) //false
        console.log(Foo.constructor === Father) //false

        //所以这里要把构造函数的原型对象的constructor指到构造函数上
        Father.prototype.constructor = Father

        //或者在这里加上constructor:Father 
        /* Father.prototype = {
            age:18,
            fn:function(){
                console.log('22222')
            },
            constructor:Father
        }  */
        console.log(Father.prototype.constructor === Father) //true
        console.log(Foo.constructor === Father) //true

原型继承方法

原型链继承

就是把子类实例对象能访问的的prototype等于父类的实例对象,就能访问Father.prototype

        function Father() {
            this.color = 'red'
            this.name = 'lv'
            this.arr = [1, 2, 3, 4]
        }

        Father.prototype.getName = function () {
            console.log(this.name)
        }


        function Son() { 
            
        }
        //将父类的实例赋给子类的原型 
        //这是原型链继承 就是把子类实例对象能访问的的prototype等于父类的实例对象,就能访问 Father.prototype
        Son.prototype = new Father()

        //son和son1本来不相关 son.arr.push(5)时son1.arr也变了,引用值共享的问题
        var son = new Son()
        var son1 = new Son()

        son.arr.push(5)
        console.log(son.arr) //[1, 2, 3, 4, 5]
        console.log(son1.arr) //[1, 2, 3, 4, 5]

缺点:引用值共享的问题

构造函数继承

可以解决原型链继承的引用值共享的问题,但是父类的Father.prototype.getName里的方法拿不到

        //构造函数继承Father.call(this)
        function Son() { 
            Father.call(this)
        }

        var son = new Son()
        var son1 = new Son()

        son.arr.push(5)
        console.log(son.arr) //[1, 2, 3, 4, 5]
        console.log(son1.arr) //[1, 2, 3, 4]

组合继承(伪经典继承)

调用了两次父类构造函数,生成了两份实例(子类实例将子类原型上的那份屏蔽了)

        //构造函数继承Father.call(this)
        function Son() { 
            Father.call(this)
        }
        //将父类的实例赋给子类的原型 
        //原型链继承 
        Son.prototype = new Father()

        var son = new Son()
        var son1 = new Son()

        son.arr.push(5)
        console.log(son.arr) //[1, 2, 3, 4, 5]
        console.log(son1.arr) //[1, 2, 3, 4]
        console.log(son.getName) //fn{}   

寄生继承(经典继承)

Object.create()方法创建一个新对象Father.prototype,创建一个对象,对象的原型为creat()参数,就是指定当前对象的原型为传入的参数。

        //构造函数继承Father.call(this)
        function Son() { 
            Father.call(this)
        }
        //将父类的实例赋给子类的原型 
        //原型链继承 
        Son.prototype = Object.create(Father.prototype)
        Son.prototype.constructor = Son

        var son = new Son()
        var son1 = new Son()

        son.arr.push(5)
        console.log(son.arr) //[1, 2, 3, 4, 5]
        console.log(son1.arr) //[1, 2, 3, 4]
        console.log(son.getName) //fn{}   


        //Object.create源码

        Object.create =  function (o) {
            var F = function () {};
            F.prototype = o;
            return new F();
          }

class继承(ES6新增)

extends继承,super方法

        class farther {
            constructor(sonname) {

                this.sonname = sonname
            }
            say() {
                console.log('你的姓是' + this.sonname)
            }
        }


        // extends方法
        class son extends farther { }
        let yours = new son('wang')
        yours.say()




        class son extends farther {
            constructor(sonname, grandsonname) {
                super(sonname, grandsonname)
                this.sonname = sonname
                this.grandsonname = grandsonname
            }
            sayson() {
                console.log('儿子的姓是' + this.grandsonname)
            }
        }

        const sons = new son('lv', 'w')
        const grandsons = new son('lv', 'w')
        sons.say()
        grandsons.sayson()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值