js类与原型链

类的创建

js中创建一个类很容易,如下所示:

<script>
        class Person {

        }
        let p1 = new Person();
        let p2 = new Person();
        console.log(p1);
        console.log(p2);
    </script>

以上创建一个类,并且创建它的实例p1 和p2,输出可以看到输出两个Person实例
在这里插入图片描述
但是,我们实例两个对象却无法区分(输出 都一样啊),所以我们需要对类进行传参,让每一个实例对象都有自己的属性

  <script>
        class Person {
            constructor(name,age){
                this.name = name;
                this.age = age;
            }
        }
        let p1 = new Person('小明',18);
        let p2 = new Person('小红',17);
        console.log(p1);
        console.log(p2);
    </script>
    

在这里插入图片描述

同样我们可以在类中定义一些方法,让实例区调用

   class Person {
            constructor(name,age){
                this.name = name;
                this.age = age;
            }
            say() {
                console.log(`大家好,我是${this.name},我今年${this.age}了`);
            }
        }
        let p1 = new Person('小明',18);
        let p2 = new Person('小红',17);
        console.log(p1);
        console.log(p2);
        p1.say();
        p2.say();

在这里插入图片描述

我们刚才创建了一个类Persion,并且实例了它的对象p1,类和实例之间还有一层关系,那就是原型,原型也是一个对象,它里面有一些属性和方法可以被类和实例继承。
类里面有一个属性,叫做prototype,它可以指向这个原型,同样,类的实例也有一个属性,叫做 proto,它也可以指向这个原型,而原型有一个属性,叫做constructor,它可以指向类,这样,他们三个的关系可以用图来表示。
在这里插入图片描述
同样,从浏览器中我们也能看出来这种关系,比如我们 刚才实例了p1,并把p1输出,那么从刚才那张图中我们就可以从p1中去找到原型,从原型中找到类
在这里插入图片描述
可以看到,输出的实例p1中有一个属性_proto_,它指向一个对象,这个对象就是 原型,我们展开原型
在这里插入图片描述
可以看到,展开原型,发现原型里面有一个constructor属性,它指向Person类,我们展开类
在这里插入图片描述
可以看到类里面有个prototype属性,它指向一个对象,打开对象发现还是 之前那个原型,因此,类,实例对象,原型之间的关系就可以解释的通了。还有一个细节,p1通过_proto_找到原型链的时候,原型链上有一个方法say(),而接着找到类的时候,类中却没有say()方法,这就验证类我们之前的话,类的一些方法放在了原型中,实例可以从原型中继承方法来使用。
下面来看 类的继承

   class Person {
            constructor(name,age){
                this.name = name;
                this.age = age;
            }
            say() {
                console.log(`大家好,我是${this.name},我今年${this.age}了`);
            }
        }
       class Student extends Person{
            
       }
       let s1 = new Student('张三',13)
       console.log(s1)
       s1.say()

这里创建了一个Studengt类,它继承了Prson,并且实例了一个对象s1 ,调用了say()方法,我们知道,Student里面没有say()方法,说吗Student原型里面 也没有say()方法,那么他是怎么找到say()方法并调用呢?我们输出s1,发现了这样一层关系
在这里插入图片描述
即Student原型上如果没有找到所需函数,原型会通过_proto_找到继承的父类的原型,在父类原型上找,这就构成了原型链。
如果我们在Student上重写方法

 class Person {
            constructor(name,age){
                this.name = name;
                this.age = age;
            }
            say() {
                console.log(`大家好,我是${this.name},我今年${this.age}了`);
            }
        }
       class Student extends Person{
            constructor(name,age,hobby){
                super(name,age)
                this.hobby = hobby
            }
            say() {
                console.log(`我的爱好是${this.hobby}`)
            }
       }
       let s1 = new Student('张三',13,'画画')
       console.log(s1)
       s1.say()

那么这里输出的say() 方法则是在Student上定义的方法,原因也可以在原型链上解释
在这里插入图片描述
当student的实例s1首先会在其自己的原型上查找say(),如果没有找到,则通过_proto_去上层原型上查找,如果找到,则不会再去上层原型查找
还有一个细节,我们知道,js中有个Object类,它是所有对象的父类,那么Person的原型肯定可以通过_proto_,找到Object的原型
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

问也去

创作不易,感谢支持

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

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

打赏作者

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

抵扣说明:

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

余额充值