JS class语法糖的深入剖析


Posted in Javascript onJuly 07, 2022

引言

在很早以前,写过一篇文章 “类”设计模式和“原型”设计模式——“复制”和“委托”的差异 ,大致意思就是说:代码复用,也就是继承、重写,有两种思路:1. 面向对象的类继承;2. 基于 JavaScript 原型链的原型继承;前者的主要特点是:复制,通俗来说就是把变量、属性再复制一份,后者的主要特点是:委托,通过属性的查找来实现的。

后来呢,深入了解 JavaScript 高级程序设计中的继承,包括构造函数继承、原型继承、组合继承、寄生组合继承,都有各自的缺点,有兴趣的朋友,可以看我这篇文章。

还有,本瓜特别记住:维基对 JavaScript 起源的解释

JavaScript的语言设计主要受到了Self(一种基于原型的编程语言)和Scheme(一门函数式编程语言)的影响。在语法结构上它又与C语言有很多相似。

最后,我的小结呢就是:JavaScript 本身的设计就是“通过原型委托”来实现代码复用的,结果 ES6 搞出了个 class 作为语法糖,其本身还是基于原型链,但又是为了实现面向对象,面向对象是基于 class 类那种“复制”来实现代码复用。

类 和 原型,是两种不同的东西,JS class 将二者混在了一起,别不别扭?

后来也看到一些文章说在 JS 中使用 class 类会造成一些困扰,所以更加坚定要减少使用 class 。

而实际上,本篇题目是:JS class 并不只是简单的语法糖,所以,本篇并不是为了说它不好,而是要说它的好的!

来吧,展翅!

class 第一个好:私有变量

如果不用 class , 还有什么更优雅的方法实现以下子类的私有变量吗?

class Person {
  constructor(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  } // Person.constructor
  get FullName () {
    return this.firstName + " " + this.lastName;
  }
} // Person
class Employee extends Person {
  #salary;
  constructor(firstName, lastName, salary) {
    super(firstName, lastName);
    this.salary = salary;
  }
  get salary() {
    return this.#salary;
  }
  set salary(salary) {
    this.#salary = salary;
    console.log("Salary changed for " + this.fullName + " : $" + this.salary);
  }
} // Employee

设想下,我们用原型链的思路模拟(对象):

const Person = {
  set givenName(givenName) {
    this._givenName = givenName;
  },
  set familyName(familyName) {
    this._familyName = familyName;
  },
  get fullName() {
    return `${this._givenName} ${this._familyName}`;
  }
};
const test = Person; // 这里假设用 对象 模拟 类
test.givenName = "Joe";
test.familyName = "Martinez";
console.log("test.fullName", test.fullName); // Joe Martinez
console.log("test.givenName", test.givenName); // undefined
console.log("test._givenName", test._givenName); // Joe

没有实现私有属性 _givenName

而 class 可以将值存为私有,使得对象外部不能修改:

class 第二个好:super 继承

class 可以通过 super 更优雅的实现继承、和重写,比如:

class Cash {
  constructor() {
    this.total = 0;
  }
  add(amount) {
    this.total += amount;
    if (this.total < 0) this.total = 0;
  }
} // Cash
class Nickles extends Cash {
  add(amount) {
    super.add(amount * 5);
  }
} // Nickles

如果是按照老样子,原型链,它可能是这样的:

const Cash = function() {
  this.total = 0;
}; // Cash
Cash.prototype = {
  add : function(amount) {
    this.total += amount;
    if (this.total < 0) this.total = 0;
  }
}; // Cash.prototype
const Nickles = function() {
  Object.assign(this, new Cash());
  this.add = function(amount) {
    Cash.add.apply(this, amount);
  };
} // Nickles

读起来有点乱,this 指来指去,还有在构造函数中手动做的 assign 操作,这会增加代码执行耗时。

综上两点,JS class 还是非常有使用它的价值的,不用逃避,把它用在合适的场景,肯定会发现其魅力~~

以上就是JS class语法糖的深入剖析的详细内容,更多关于JS class语法糖的资料请关注三水点靠木其它相关文章!

Javascript 相关文章推荐
删除条目时弹出的确认对话框
Jun 05 Javascript
JavaScript编写推箱子游戏
Jul 07 Javascript
JS动态加载脚本并执行回调操作
Aug 24 Javascript
原生JS实现的双色球功能示例
Feb 02 Javascript
解决Angular.js中使用Swiper插件不能滑动的问题
Feb 26 Javascript
jQuery轮播图实例详解
Aug 15 jQuery
JS实现长图上下滚动效果
Mar 19 Javascript
js中调用微信的扫描二维码功能的实现代码
Apr 11 Javascript
浅谈vue生命周期共有几个阶段?分别是什么?
Aug 07 Javascript
Kettle中使用JavaScrip调用jar包对文件内容进行MD5加密的操作方法
Sep 04 Javascript
vue中template的三种写法示例
Oct 21 Javascript
详解Vite的新体验
Feb 22 Javascript
MutationObserver在页面水印实现起到的作用详解
Jul 07 #Javascript
js作用域及作用域链工作引擎
Promise静态四兄弟实现示例详解
Jul 07 #Javascript
Three.js实现雪糕地球的使用示例详解
二维码条形码生成的JavaScript脚本库
Jul 07 #Javascript
JS实现简单的九宫格抽奖
JS实现九宫格拼图游戏
You might like
PHP操作文件的一些基本函数使用示例
2014/11/18 PHP
Linux服务器下PHPMailer发送邮件失败的问题解决
2017/03/04 PHP
php实现微信公众平台发红包功能
2018/06/14 PHP
PHP中如何使用Redis接管文件存储Session详解
2018/11/28 PHP
手机平板等移动端适配跳转URL的js代码
2014/01/25 Javascript
JavaScript的null和undefined区别示例介绍
2014/09/15 Javascript
jQuery动画出现连续触发、滞后反复执行的解决方法
2015/01/28 Javascript
jQuery支持动态参数将函数绑定到事件上的方法
2015/03/17 Javascript
javascript父子页面通讯实例详解
2015/07/17 Javascript
JavaScript实现搜索框的自动完成功能(一)
2016/02/25 Javascript
Bootstrap Modal对话框如何在关闭时触发事件
2016/12/02 Javascript
根据Bootstrap Paginator改写的js分页插件
2016/12/25 Javascript
了解重排与重绘
2019/05/29 Javascript
简单了解Javscript中兄弟ifream的方法调用
2019/06/17 Javascript
[59:30]VG vs LGD 2019国际邀请赛淘汰赛 胜者组 BO3 第二场 8.22
2019/09/05 DOTA
python多重继承新算法C3介绍
2014/09/28 Python
Python中用startswith()函数判断字符串开头的教程
2015/04/07 Python
100行python代码实现跳一跳辅助程序
2018/01/15 Python
Python利用字典破解WIFI密码的方法
2019/02/27 Python
python 标准差计算的实现(std)
2019/07/29 Python
Python生命游戏实现原理及过程解析(附源代码)
2019/08/01 Python
Python中低维数组填充高维数组的实现
2019/12/02 Python
PyTorch的SoftMax交叉熵损失和梯度用法
2020/01/15 Python
python查找特定名称文件并按序号、文件名分行打印输出的方法
2020/04/24 Python
Python通过Schema实现数据验证方式
2020/11/12 Python
弄清Pytorch显存的分配机制
2020/12/10 Python
秘鲁购物网站:Linio秘鲁
2017/04/07 全球购物
介绍一下linux的文件权限
2014/07/20 面试题
面试后感谢信怎么写
2014/02/01 职场文书
服务承诺书范文
2014/05/19 职场文书
2014年工会工作总结
2014/11/12 职场文书
班主任工作经验交流会总结
2015/11/02 职场文书
pytorch训练神经网络爆内存的解决方案
2021/05/22 Python
解决pytorch-gpu 安装失败的记录
2021/05/24 Python
详细聊聊MySQL中慢SQL优化的方向
2021/08/30 MySQL
Dashboard管理Kubernetes集群与API访问配置
2022/04/01 Servers