js原型与原型链

150 阅读2分钟

基本概念

每个对象都有自己的原型对象,它可以使用其原型链上的所有属性和方法。

获取原型的几种方式

  • 通过对象的 __proto__ 获取
     let cat = {
          name: "喵喵"
      }
      // 在 cat 的原型对象上添加一个 eat 方法
      cat.__proto__.eat = function() {
          console.log("吃鱼")
      }
      cat.eat()       // 打印出吃鱼 说明 cat 使用了其原型上的方法
    
  • 通过构造函数的 prototype 获取
    function Dog(name,age) {
       this.name = name
       this.age = age
     }
     // 在 Dog 的原型对象上添加一个 eat 方法
     Dog.prototype.eat = ()=> {
       console.log("吃骨头");
     }
     let dog = new Dog("大黄",2)
     dog.eat()  //打印出吃骨头
    

原型对象的应用

如果我们执行以下代码

    let date = new Date()
    console.log(date)

此时会打印下图中第一行的结果 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tCPuUZpc-1646450542504)(file://D:/soft/Gridea/yuanwenjian/post-images/1645236185058.png)]

如果我们想要打印第二行 这样格式的时间呢; 此时我们就可以给 Date的原型对象添加一个方法 来将输出格式化,具体代码如下

  let data = new Date()
    Date.prototype.formate = function() {
      let year = this.getFullYear()
      let month = this.getMonth()
      let date =  this.getDate()
      return `${year}${month}${date}日`
    }
    console.log(data.formate());

此时就能输出 第二行格式的时间了

原型对象类与继承

类获取原型的方式与构造函数一样,都是通过 prototype 属性去获取

  class Cat {
      constructor(name,age) {
         this.name = name
         this.age = age
      }
    }
    Cat.prototype.eat = function() {
      console.log("吃鱼");
    }
    let cat = new Cat("喵喵",2)
    console.log(cat.name);
    cat.eat()    // 输出吃鱼

类的继承实例

实现 管理员与普通用户 管理员拥有普通用户有的所有属性和功能

    class User {
      constructor(name,password) {
        this.name = name
        this.password = password
      }
      login() {
        console.log("登录");
      }
    }
    // 继承 User 类 获取 其中的属性与方法
    class Admin extends User{
        removeUser() {
          console.log("删除");
        }
    }
    let admin = new Admin()
    // 此时 admin 就可以使用 User 中的 login 方法
    admin.login()

原型继承与原型链

用ES6的 class 我们实现了上述功能,如果不用ES6我们要如何实现上述功能呢? 我们可以通过改变构造方法原型对象的指向 在这个例子中,我们就将 Admin 的原型对象 指向 User 这样的话,Admin就拥有User所有的属性和方法了; 具体代码如下

   function User(name,password) {
      this.name = name
      this.password = password
      this.login = function () {
        console.log("登录")
      }
    }
    function Admin() {
      this.removeUser = function () {
        console.log("删除用户");
      }
    }
  //  基于原型的继承 通过将对象的原型指向要继承的对象
    Admin.prototype = new User()
    let admin = new Admin()
    admin.login()

那么什么是原型链呢? 每个对象都有自己的原型对象,它的原型对象也有自己的原型对象,如下图所示 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qHIK0r61-1646450542506)(file://D:/soft/Gridea/yuanwenjian/post-images/1645238628971.png)]

Tips:Object.prototype 是所有对象的原型对象