React-class-extends-原型&原型链&原型问题解析

原型及原型链的概念

1、原型的概念

2、原型链的概念

总结

class-extends-原型问题及解析

图像解析

问题

函数原型对象

复盘


原型及原型链的概念

1、原型的概念

JavaScript的所有对象中都包含了一个 [proto] 内部属性,这个属性所对应的就是自身的原型
JavaScript的函数对象,除了原型 [proto] 之外,还有 prototype 属性,当函数对象作为构造函数创建实例时,该 prototype 属性值将被作为实例对象的原型 [proto]

2、原型链的概念

当一个对象调用自身不存在的属性/方法时,就会去自己 [proto] 关联的前辈 prototype 对象上去找,如果没找到,就会去该 prototype 原型 [proto] 关联的前辈 prototype 去找。依次类推,直到找到属性/方法或 undefined 为止。从而形成了所谓的“原型链”。

总结

JavaScript中的对象,都有一个内置属性[Prototype],指向这个对象的原型对象。当查找一个属性或方法时,如果在当前对象中找不到,会继续在当前对象的原型对象中查找;如果原型对象中依然没有找到,会继续在原型对象的原型中查找(原型也是对象,也有它自己的原型);直到找到为止,或者查找到最顶层的原型对象中也没有找到,就结束查找,返回undefined。这个查找过程是一个链式的查找,每个对象都有一个到它自身原型对象的链接,这些链接组建的整个链条就是原型链。拥有相同原型的多个对象,他们的共同特征正是通过这种查找模式体现出来的。
在上面的查找过程,我们提到了最顶层的原型对象,这个对象就是Object.prototype,这个对象中保存了最常用的方法,如toString、valueOf、hasOwnProperty等,因此我们才能在任何对象中使用这些方法。

class-extends-原型问题及解析

function Fn(){
            this.a = 1//实例对象上挂a
            this.b = 2
            // 实例上挂一个属性,属性名是一个对象
            this.getA = function(){
                console.log(this.a);
            }
        }
        // 类的原型对象上添加方法
        Fn.prototype.getA = function(){
            console.log(this.a);
        }
        Fn.prototype.getB = function(){
            console.log(this.b);
        }
        // 实例
        let f1 = new Fn()
        let f2 = new Fn //小括号有没有都行
        // 问题
        console.log(f1.getA === f2.getA);//false
        console.log(f1.getB === f2.getB);//true
        console.log(f1.__proto__.getB===Fn.prototype.getB);//false
        console.log(f1.__proto__.getB === f2.getA);//false
        console.log(f1.__proto__.getA === Fn.prototype.getA);//true
        console.log(f1.constructor);
        // ƒ Fn(){
        //     this.a = 1//实例对象上挂a
        //     this.b = 2
        //     实例上挂一个属性,属性名是一个对象
        //     this.getA = function(){
        //         console.log(this.a);
        //     }
        // }
        console.log(Fn.prototype.__proto__.constructor);
        // ƒ Object() { [native code] }
        f1.getA()//1
        f1.__proto__.getA()//undefined
        f2.getB()//2
        Fn.prototype.getB()//undefined

图像解析:

类:prototype属性指向原型对象

原型:constructor指向类

所有对象都有__proto__属性,属性值是当前实例的所属类的原型

原型链:先查找自己的私有属性=> __proto__ =>共有属性

问题:

01. console.log(f1.getA === f2.getA); 输出://false

解析:f1实例和f2实例开辟出来的空间营地址不一致,判断为false

02. console.log(f1.getB === f2.getB); 输出://true

解析:f1实例和f2实例均没有getB,查找公有属性,在所属性的原型中查找,公有属性相同,判断为true

03. console.log(f1.__proto__.getB===Fn.__prototype__.getB); 输出://true

解析:f1.__proto__.getB => 原型对象的getB <= Fn.__prototype__.getB

04. console.log(f1.__proto__.getA === f2.getA);输出://false

解析:f1.__proto__.getA =>营地址1   f2.getA =>营地址4

05. console.log(f1.__proto__.getA === Fn.prototype.getA);输出://true

解析:f1.__proto__.getA =>营地址1<= Fn.prototype.getA

06. console.log(f1.constructor);   

输出:

  ƒ Fn(){

            this.a = 1//实例对象上挂a

            this.b = 2

            实例上挂一个属性,属性名是一个对象

            this.getA = function(){

                console.log(this.a);

            }

        }

解析:f1实例私有属性中没有constructor,去共有属性原型对象中查找,原型对象constructor指向Fn类

07. console.log(Fn.prototype.__proto__.constructor); 输出:// ƒ Object() { [native code] }

解析:Fn.prototype=>Fn的原型对象  

Fn.prototype.__proto__=>Object的原型对象  

Fn.prototype.__proto__.constructor=>Object

08. f1.getA() 输出://1

解析:函数调用,实例自己的方法,f1.getA()=1

09. f1.__proto__.getA() 输出://undefined

解析:f1.__proto__=>Fn的原型对象 原型对象中getA方法没有a参数,输出underfind

10. f2.getB() 输出://2

解析:getB的this指向f2,this指向实例f2的b,输出2

注意:函数this指向问题,特点:谁调用this就指向谁

11. Fn.prototype.getB() 输出://underfind

解析:Fn.prototype=>Fn的原型对象 原型对象中getB方法没有参数,输出underfind

控制台输出:

函数原型对象:

console.log(Fn.__proto__);

ƒ () { [native code] }

console.log(Fn.__proto__.__proto__);

{constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}

console.log(Fn.__proto__.constructor);

ƒ Function() { [native code] }

console.log(Fn.__proto__.constructor.__proto__);

ƒ () { [native code] }

console.log(Fn.prototype.__proto__.__proto__);

null

输出:

复盘:

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值