Es6Class类与原型

原型

  • 原型链:每一个实例对象上有一个proto属性,指向构造函数的原型对象,构造函数的原型对 象也是一个对象,也有proto属性,这样一层一层向上找的过程就形成了原型链
  • 构造函数:用new来调用,就是为了创建一个自定义类
  • 实例:是类在实例化之后一个一个具体的对象

在这里插入图片描述

   获取原型的方法1.通过对象的__proto__获取2.通过构造函数的prototype属性获取到原型3.通过类的prototype属性(Es6)

举个栗子

function Person(){
this.name = "小钟";
}
Person.prototype.showMyName =()=>{   console.log("我是小钟")
}
let smallClock = new Person();
smallClock.showMyName();        // 我是小钟
Person.prototype是一个对象,叫“原型对象”。这里我们在原型对象Person.prototype上面挂载了
showMyName这个方法。
smallClock是构造函数Person实例化出来的一个对象。smallClock上为什么也有showMyName这个方法呢?
因为实例对象smallClock与原型对象Person.prototype之间存在一个隐式链接。这个隐式链接就
__proto__原型链。smallClock自身是没有showMyName方法的,但它有__proto__原型链,当
smallClock在自身的方法中找不到showMyName时,就会通过它原有的__proto__原型链继续
向上查找它的原型对象Person.prototype,通过原型链,实例化对象smallClock也可以拥有原
型对象Person.prototype上的方法。

再举一个栗子对应第一条通过对象的__proto__获取

let fish={name:"我不喜欢吃鱼"}fish.__proto__.eat=()=>{console.log("有鱼刺")}fish.eat();
//fish.__proto__这个就是它的原型,给他的原型上加一个eat方法,

又一个栗子对应第二条通过构造函数的prototype属性获取到原型
这里简单说一下什么是构造函数,构造函数也是一个函数,比较特殊的是构造函数可以new()出一个新的函数,并在new的过程中初始化该函数。

function Fish(name,age){this.name=name;this,age=age
}
let fish=new Fish("鳕鱼",10);
Fish.prototype.eat=()=>{console.log("鱼刺少,可以吃")
}
fish.eat();

原型对象在实际开发中的用处(让时间以xx年xx月xx日的形式展示出来)

  let  studyTime=new Date();Date.prototype.newTime=function(){let studyYear=this.getFullYear();let studyMonth=this.getMonth()+1;let studyDate=this.getDate();return `${studyYear}年${studyMonth}月${studyDate}日`}console.log(studyTime.newTime())   //2022年9月16日

1.类的基本语法

class Person{constructor(name,age){this.name = name;this.age = age;}Speak(){return '我的名字是 ' + this.name+“今年”+this.age;}
}
var person1 = new Person('小钟',22);       //person1 是通过类 Person 实例化出来的对象
console.log(person1.Speak());
// new Person和刚才上面提到的构造函数new一个new Fish很像,其实可以这样理解,Es5创建对象用
构造函数,二Es6用Class关键字创建一个类,类里面可以加一些属性和方法,

在这里插入图片描述
2.类新增方法的几种方式

  • 通过原型prototype修改类方法和新增方法
  Person.prototype.Like=()=>{return "喜欢跑步、滑板、射箭、拳击"}console.log(person1.Like())    //喜欢跑步、滑板、射箭、拳击
  • 通过Object.assign方法来为对象动态增加方法
  Object.assign(Person.prototype,{Run:function(){return "经常晨跑"}})console.log(person1.Run())      //经常晨跑
  • 使用实例对象的__proto__属性新增类的方法
  person1.__proto__.Eat=()=>{return "喜欢喝中杯标准糖去冰厚芋泥啵啵奶茶"}console.log(person1.Eat())     //喜欢喝中杯标准糖去冰厚芋泥啵啵奶茶

3.class类的继承

  class SmallClock extends Person{Listen(){return "很喜欢听毛不易《平凡的一天》"}}let smallClock1=new SmallClock("小钟",23)console.log(smallClock1.Run())      //经常晨跑console.log(smallClock1.Listen())   //很喜欢听毛不易《平凡的一天》

与实际开发结合,例如一个系统,有两种用户,普通用户和管理员,普通用户有用户名和密码,可以登录,管理员除了有用户名和密码外还有更大的权限,比如它可以删除用户

    class User{constructor(name,password){this.name=name;this.password=password}login(){console.log("登录成功")}}class Admin extends User{deleteUser(){console.log("删除某个用户")}}let newPeople=new Admin();newPeople.deleteUser();       //删除某个用户newPeople.login();                //登录成功

用原型如何实现继承呢?(Es5继承)
由于Es5中没有类,只能定义一个构造函数

function User(name,password){this.name=name;this.password=password;this.login=function(){console.log("登录成功")}
}
function Admin(){this.deletePerson=function(){console.log("删除某个用户")}
}
Admin.prototype=new User();
let admin=new Admin();
admin.login();   //登录成功

Admin中没有login方法,然后会去它的原型上面找,Admin的原型等于new User(),User中
有login方法,那假设如果User中也没有login()呢,它是否会继续向上找?
来做一个简单的测试,将下面的代码注释掉

   // this.login=function(){//     console.log("登录成功")// }

报错:admin.login is not a function
没有,再向上一层找,上一层要怎样定义呢?

function User(name,password){this.name=name;this.password=password;
}
function Admin(){this.deletePerson=function(){console.log("删除某个用户")}
}
Object.prototype.login=()=>{console.log("最上层")
}
Admin.prototype=new User();
let admin=new Admin();
admin.login();        //最上层

这就是基于原型链实现的一个在Object,最上层的原型上添加方法

let eat=[1,2,3];
eat.login();       //最上层

此时,所有对象的最上层都是Object.prortotype
注意点
类不存在变量提升(hoist)

new ToDo(); // ReferenceError
class ToDo {}   //使用在前定义在后会报错,所以继承时,子类应定义在父类之后


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部