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 相关文章推荐
[HTML/CSS/Javascript]WWTJS
Sep 25 Javascript
javascript 避免闭包引发的问题
Mar 17 Javascript
JavaScript 操作键盘的Enter事件(键盘任何事件),兼容多浏览器
Oct 11 Javascript
js各种验证文本框输入格式(正则表达式)
Oct 22 Javascript
获取下拉列表框的值是数组,split,$.inArray示例
Nov 13 Javascript
Jquery取得iframe下内容的方法
Nov 18 Javascript
javascript表格隔行变色加鼠标移入移出及点击效果的方法
Apr 10 Javascript
JS实现从连接中获取youtube的key实例
Jul 02 Javascript
jQuery简单入门示例之用户校验demo示例
Jul 09 Javascript
JS三目运算(三元运算)方法详解
Mar 01 Javascript
Vue实现点击后文字变色切换方法
Feb 11 Javascript
微信公众平台 客服接口发消息的实现代码(Java接口开发)
Apr 17 Javascript
MutationObserver在页面水印实现起到的作用详解
Jul 07 #Javascript
js作用域及作用域链工作引擎
Promise静态四兄弟实现示例详解
Jul 07 #Javascript
Three.js实现雪糕地球的使用示例详解
二维码条形码生成的JavaScript脚本库
Jul 07 #Javascript
JS实现简单的九宫格抽奖
JS实现九宫格拼图游戏
You might like
十天学会php(1)
2006/10/09 PHP
vBulletin Forum 2.3.xx SQL Injection
2006/10/09 PHP
CodeIgniter框架提示Disallowed Key Characters的解决办法
2014/04/21 PHP
PHP解析html类库simple_html_dom的转码bug
2014/05/22 PHP
PHP调用.NET的WebService 简单实例
2015/03/27 PHP
PHP实现带重试功能的curl连接示例
2016/07/28 PHP
基于jquery的时间段实现代码
2012/08/02 Javascript
jquery实现动态画圆
2014/12/04 Javascript
node.js中的events.emitter.once方法使用说明
2014/12/10 Javascript
javascript内置对象操作详解
2015/02/04 Javascript
javascript运算符——逻辑运算符全面解析
2016/06/27 Javascript
jQuery实现倒计时(倒计时年月日可自己输入)
2016/12/02 Javascript
jQuery选择器实例应用
2017/01/05 Javascript
JS实现图片居中悬浮效果
2017/12/25 Javascript
解决bootstrap模态框数据缓存的问题方法
2018/08/10 Javascript
vue-lazyload使用总结(推荐)
2018/11/01 Javascript
对TypeScript库进行单元测试的方法
2019/07/18 Javascript
详解如何在Vue项目中发送jsonp请求
2019/10/25 Javascript
vue.js的简单自动求和计算实例
2019/11/08 Javascript
线程和进程的区别及Python代码实例
2015/02/04 Python
Python Requests模拟登录实现图书馆座位自动预约
2018/04/27 Python
python实现两个dict合并与计算操作示例
2019/07/01 Python
用python实现名片管理系统
2020/06/18 Python
opencv 图像礼帽和图像黑帽的实现
2020/07/07 Python
IGK Hair官网:喷雾、洗发水、护发素等
2020/11/03 全球购物
实习教师自我鉴定
2013/12/09 职场文书
《台湾的蝴蝶谷》教学反思
2014/02/20 职场文书
优秀的导游求职信范文
2014/04/06 职场文书
职位说明书范文
2014/05/07 职场文书
毕业生银行实习自我鉴定
2014/10/14 职场文书
2014幼儿园教育教学工作总结
2014/12/17 职场文书
小学生通知书评语
2014/12/31 职场文书
2015个人简历自我评价语
2015/03/11 职场文书
中学生清明节演讲稿
2015/03/18 职场文书
上诉答辩状范文
2015/05/22 职场文书
详解redis在微服务领域的贡献
2021/10/16 Redis