Es6Class类与原型

原型

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

Es6Class类与原型_第1张图片

   获取原型的方法
   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关键字创建一个类,类里面可以加一些属性和方法,

Es6Class类与原型_第2张图片
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 {}   //使用在前定义在后会报错,所以继承时,子类应定义在父类之后

你可能感兴趣的:(es6,javascript,原型模式)