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 相关文章推荐
escape、encodeURI、encodeURIComponent等方法的区别比较
Dec 27 Javascript
jQuery中jqGrid分页实现代码
Nov 04 Javascript
简单几步实现返回顶部效果
Dec 05 Javascript
JS实现搜索关键词的智能提示功能
Jul 07 Javascript
vue Render中slots的使用的实例代码
Jul 19 Javascript
深入理解Vue transition源码分析
Jul 30 Javascript
js实现微信/QQ直接跳转到支付宝APP打开口令领红包功能
Jan 09 Javascript
Vue.js 实现微信公众号菜单编辑器功能(一)
May 08 Javascript
js指定日期增加指定月份的实现方法
Dec 19 Javascript
详解如何使用nvm管理Node.js多版本
May 06 Javascript
Vue实现 点击显示再点击隐藏效果(点击页面空白区域也隐藏效果)
Jan 16 Javascript
Vue记住滚动条和实现下拉加载的完美方法
Jul 31 Javascript
MutationObserver在页面水印实现起到的作用详解
Jul 07 #Javascript
js作用域及作用域链工作引擎
Promise静态四兄弟实现示例详解
Jul 07 #Javascript
Three.js实现雪糕地球的使用示例详解
二维码条形码生成的JavaScript脚本库
Jul 07 #Javascript
JS实现简单的九宫格抽奖
JS实现九宫格拼图游戏
You might like
超级好用的一个php上传图片类(随机名,缩略图,加水印)
2010/06/30 PHP
PHP在字符断点处截断文字的实现代码
2011/04/21 PHP
配置php.ini实现PHP文件上传功能
2014/11/27 PHP
Extjs学习笔记之一 初识Extjs之MessageBox
2010/01/07 Javascript
jquery 插件实现图片延迟加载效果代码
2010/02/06 Javascript
js 函数调用模式小结
2011/12/26 Javascript
用jQuery获取IE9下拉框默认值问题探讨
2013/07/22 Javascript
js 实现菜单左右滚动显示示例介绍
2013/11/21 Javascript
Javascript学习笔记之 对象篇(三) : hasOwnProperty
2014/06/24 Javascript
超级好用的jQuery圆角插件 Corner速成
2014/08/31 Javascript
使用PHP+JavaScript将HTML页面转换为图片的实例分享
2016/04/18 Javascript
JS代码实现根据时间变换页面背景效果
2016/06/16 Javascript
jQuery实现的分页功能示例
2017/01/22 Javascript
jQuery 判断元素整理汇总
2017/02/28 Javascript
Centos6.8下Node.js安装教程
2017/05/12 Javascript
vue.js实例对象+组件树的详细介绍
2017/10/20 Javascript
node将geojson转shp返回给前端的实现方法
2019/05/29 Javascript
详解vuejs中执行npm run dev出现页面cannot GET/问题
2020/04/26 Javascript
python实现调用其他python脚本的方法
2014/10/05 Python
RC4文件加密的python实现方法
2015/06/30 Python
Python中flatten( )函数及函数用法详解
2018/11/02 Python
Django之模型层多表操作的实现
2019/01/08 Python
关于Numpy中的行向量和列向量详解
2019/11/30 Python
python 字段拆分详解
2019/12/17 Python
美国婚礼装饰和活动用品批发供应商:Event Decor Direct
2018/10/12 全球购物
印度首个本地在线平台:nearbuy
2019/03/28 全球购物
Looking4Parking美国:全球排名第一的机场停车比较品牌
2019/08/26 全球购物
酒店人事专员岗位职责
2013/12/19 职场文书
合作意向书范本
2014/03/31 职场文书
抗洪救灾先进集体事迹材料
2014/05/26 职场文书
食品工程专业求职信
2014/06/15 职场文书
单位租车协议书
2015/01/29 职场文书
幼儿园小班个人总结
2015/02/12 职场文书
导游经典开场白——导游词
2019/04/17 职场文书
详细聊聊vue中组件的props属性
2021/11/02 Vue.js
安装Ruby和 Rails的详细步骤
2022/04/19 Ruby