Kros的博客 Kros的博客
首页
  • CSS
  • 工具
  • Vue
  • js
  • Vue3
  • 算法
  • 折腾笔记
一言
  • 分类
  • 标签
  • 归档
码云

Kros

凡心所向,素履以往,生如逆旅,一苇以航
首页
  • CSS
  • 工具
  • Vue
  • js
  • Vue3
  • 算法
  • 折腾笔记
一言
  • 分类
  • 标签
  • 归档
码云
  • CSS

  • JavaScript

    • 兼容ie7的水平无限滚动
    • 节流防抖
    • 数组乱序
    • 开启全屏
    • 数据类型
    • 变量提升
    • this调用指向
    • 原型及原型扩展
    • js获取元素属性精度问题
    • setTimeout和setInterval
    • 数组判断
    • dom节点添加或插入元素
    • var、let和const的区别
    • 判断ellipsis是否省略生效
    • 使用ResizeObserver监听元素size变化
    • js自定义事件
    • use strict详解
    • 私有属性
    • js实现类的方式
      • call和apply的理解和使用
      • js失焦和点击事件顺序冲突
      • js中不常见但非常实用的运算符
      • for of和for in的区别
      • defer和async的区别
      • promise值穿透
      • js为什么会出现数字精确度丢失
      • js禁用F12开发者模式
      • 使用scrollTop和scrollTo滚动到目标位置
      • js实现打字机效果
      • 多种方式实现数组去重
      • 替换使用setTimeout
      • encodeURI和encodeURIComponent的区别
      • canvas实现弹跳小球
      • js实现跨标签页通信
      • 事件循环与微任务、宏任务
      • 浏览器存储数据方式
      • 常见的meta元数据使用
      • 使用InterSectionObserver判断元素区域(chatGPT)
    • 工具

    • Vue

    • antdv踩坑记录

    • Vue3

    • 前端
    • JavaScript
    kros
    2023-07-18

    js实现类的方式

    最开始的js并没有类的概率,但随着技术的发展、代码量的堆积以及为了更好的协助多成员工程化开发,模块化和面向对象开发是必不可少的。下面就介绍几种js实现类以及使用js实现面向对象的封装、继承和多态的特性

    # 实现类的方式

    # 使用字面量

    模拟字面量生成的类,然后使用Object.create 创建一个新对象,使用这种创建出来的对象全是公有属性,不能实现属性方法的封装有很大的局限性

    // 定义类
    let Person = {
      name: '张三',
      getName: function() {
        return '我是' + this.name
      }
    }
    // 使用Object.create方法创建类实例
    let person1 = Object.create(Person)
    console.log(person1.getName()) // 我是张三
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    # 使用构造函数

    使用构造函数我们可以通过传入的参数来构建不同的对象

    function Person(name) {
      this.name = name;
      this.getName = function() {
        return '我是' + this.name
      }
    }
    
    // 使用new关键字来创建新对象
    let person1 = new Person('张三')
    let person2 = new Person('李四')
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    # 原型和原型链

    这里不多说,请看我的另一篇文章:原型及原型的扩展

    # 使用class

    在ES6以后,js提供了标准类的写法class ,和其它面向对象语法基本一致

    class 
    
    1

    # 面向对象特性

    这里使用class来进行面向对象封装、继承和多态的实现

    # 封装

    在非class定义的类的情况下可以使用闭包来实现对私有属性和方法的封装,使用class时js提供了专有的私有属性写法。具体请查看我的另一篇文章js私有属性

    // 使用class
    class DemoPrivate {
      #value; // 以#开头的变量或方法为私有属性
      
      #privateMethod() {
        
      }
    }
    
    // 使用闭包
    function useScoreOpt() {
      let total = 0; // 内部属性
      function addNum(num) {
        total += num
        return total
      }
      function getNum() {
        return total
      }
      return { add: addNum, getNum: getNum }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    # 继承

    最简单的方式是通过原型链来进行继承,如果使用class也提供了extend来实现类的继承

    class Person {
      name; // 以#开头的变量或方法为私有属性
      
      constructor(name) {
        this.name = name
      }
      
      getName() {
        return this.name
      }
    }
    class Woman extend Person {
      
      constructor(name) {
        // 父类构造
        super(name)
      }
      
      
      getName() {
        // 父类方法
        return '我是女性,我叫:' + super.getName()
      }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    # 多态

    js中不会对参数类型进行检查,所以每一个函数都是天然的多态

    class Person {
      #name;
      
      getName() {
        return this.#name
      }
      
      setName(name) {
        this.#name = name
      }
    }
    
    let user1 = new Person()
    user1.setName('张三')
    user1.setName(666)
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    # 其它

    当然,如果你使用的TypeScript就没有以上的烦恼,我们可以使用标准的面向对象语法。

    class Person {
      // 静态属性
      static IDCard: String;
      // 私有标识private,没有即为public,使用`:类型`可以标识属性的类型进行语法检查
      private name: String;
      
      constructor(name: String) {
        this.name = name
      }
      
      
      /* getter setter*/
      get name(): String {
        return this.name
      }
      
      set name(name: String) {
        this.name = name
      }
      
      // :string 标识getName返回值类型是字符串
      getIntro() : String {
        return 'hello 你好,我是' + this.name 
      }
      
      // 多态
      getIntro(age: Number) : String {
        return 'hello 你好,我是' + this.name + ' 我今年' + age + '啦'
      }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    上次更新: 2025/09/05, 8:09:00
    私有属性
    call和apply的理解和使用

    ← 私有属性 call和apply的理解和使用→

    最近更新
    01
    Find the next perfect square
    09-05
    02
    Regex validate PIN code
    09-05
    03
    Find the odd int
    09-05
    更多文章>
    Theme by Vdoing | Copyright © 2020-2025 kros king
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式
    icon-heart-o icon-heart icon-infinity icon-pause icon-play link next prev