原型和原型链

原型

  • 在 JavaScript 中,每个对象都有一个内部属性 [[Prototype]],它指向该对象的原型,可以通过  对象名.__proto__ 或 Object.getPrototypeOf(对象名) 访问对象的原型对象
  • 原型是一个对象,它包含可被共享和继承的属性和方法。
  • 对象可以通过原型访问属性和方法,如果对象本身没有定义某个属性或方法,它会沿着原型链向上查找,直到找到该属性或方法或者到达原型链的末尾。

原型链

  • 原型链是由对象之间的原型引用所组成的链式结构。
  • 当我们访问一个对象的属性或方法时,如果该对象本身没有定义,JavaScript 引擎会沿着原型链向上查找,直到找到该属性或方法或者到达原型链的末尾(即 Object.prototype)。
  • 原型链的顶端是 Object.prototype,它是所有对象的默认原型

原型链的调用机制

        /**
         * 原型链
        */
        function Dq(){
            this.constructor.prototype.dq = () => console.log('地球');
            this.constructor.prototype.some = () => console.log('Dq-Same');
        }

        function Zg(){
            this.init = function(){
                const dq = new Dq();
                Object.setPrototypeOf(this.constructor.prototype, dq.__proto__)
                this.constructor.prototype.constructor = this.constructor
            }
            this.init()
            this.constructor.prototype.zg = () => console.log('中国');
            this.constructor.prototype.some = () => console.log('Zg-Same');
        }

        function Gd() {
            this.init = function(){
                const zg = new Zg();
                Object.setPrototypeOf(this.constructor.prototype, zg.__proto__)
                this.constructor.prototype.constructor = this.constructor
            }
            this.init()
            this.constructor.prototype.gd = () => console.log('广东');
            this.constructor.prototype.some = () => console.log('Gd-Same');
        }

        function Gz() {
            this.init = function(){
                const gd = new Gd();
                Object.setPrototypeOf(this.constructor.prototype, gd.__proto__)
                this.constructor.prototype.constructor = this.constructor
            }
            this.init()
            this.constructor.prototype.gz = () => console.log('广州');
            this.constructor.prototype.some = () => console.log('Gz-Same');
        }

        function Person() {
            this.init = function(){
                const gz = new Gz();
                Object.setPrototypeOf(this.constructor.prototype, gz.__proto__)
                this.constructor.prototype.constructor = this.constructor
            }
            this.init()
            this.constructor.prototype.person = () => console.log('人');
            this.constructor.prototype.some = () => console.log('Person-Same');
        }
        function Man(name){
            this.name = name;
            this.init = function(){
                const pr = new Person()
                Object.setPrototypeOf(this.constructor.prototype, pr.__proto__)
                this.constructor.prototype.constructor = this.constructor
            }
            this.init()
            this.constructor.prototype.man = () => console.log('男');
            this.constructor.prototype.some = () => console.log('Man-Same');
        }
        
        const p1 = new Man('刘德华')
        console.log(p1);
        //刘德华
        console.log(p1.name);
        //男
        p1.man()
        //人
        p1.person()
        //广州
        p1.gz()
        //广东
        p1.gd()
        //中国
        p1.zg()
        //地球
        p1.dq()
        
        //ture  执行的是同个原型对象
        console.log(p1.__proto__ === Object.getPrototypeOf(p1));


        //p1对象没有some()方法找原型对象
        //Man-some
        p1.some()
        //p1原型对象的some()方法
        //Man-Same
        p1.__proto__.some()
        //true
        //证明p1.some()实际上调用的是p1.__proto__.some()
        console.log(p1.some === p1.__proto__.some);

        //Person-Same
        p1.__proto__.__proto__.some()
        //false
        console.log(p1.some === p1.__proto__.__proto__.some)

        //Gz-Same
        p1.__proto__.__proto__.__proto__.some()
        //Gd-Same
        p1.__proto__.__proto__.__proto__.__proto__.some()
        //Zg-Same
        p1.__proto__.__proto__.__proto__.__proto__.__proto__.some()
        //Dq-Same
        p1.__proto__.__proto__.__proto__.__proto__.__proto__.__proto__.some()
        //Error
        p1.__proto__.__proto__.__proto__.__proto__.__proto__.__proto__.__proto__.some()

        console.log('----------------------------------------------------------------');
        //通过递归的方式输出
        const outSome = (obj) => {
            //判断对象是非空
            if(!obj){
                return
            }

            /**
             * 判断对象的原型是不是指向Object.prototype
             * 因为Object.prototype里面没有定义some()方法
            */
            if(obj.__proto__ === Object.prototype ){
                return
            }
            //输出顺序和上面一致
            obj.__proto__.some();
            outSome(obj.__proto__)
        }

        outSome(p1)

  

对象名.__proto__ 和 Object.getPrototypeOf(对象名)

        //ture  执行的是同个原型对象
        console.log(p1.__proto__ === Object.getPrototypeOf(p1));

向上查找机制

        //p1对象没有some()方法找原型对象
        //Man-some
        p1.some()
        //p1原型对象的some()方法
        //Man-Same
        p1.__proto__.some()
        
        //true
        //证明p1.some()实际上调用的是p1.__proto__.some()
        console.log(p1.some === p1.__proto__.some);

        //Person-Same
        p1.__proto__.__proto__.some()
        //false
        console.log(p1.some === p1.__proto__.__proto__.some)

递归调用

        //通过递归的方式输出
        const outSome = (obj) => {
            //判断对象是非空
            if(!obj){
                return
            }

            /**
             * 判断对象的原型是不是指向Object.prototype
             * 因为Object.prototype里面没有定义some()方法
            */
            if(obj.__proto__ === Object.prototype ){
                return
            }
            //输出顺序和上面一致
            obj.__proto__.some();
            outSome(obj.__proto__)
        }

        outSome(p1)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hz没头脑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值