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 相关文章推荐
JavaScript 变量命名规则
Sep 23 Javascript
Javascript 浮点运算精度问题分析与解决
Mar 26 Javascript
AngularJS 模块详解及简单实例
Jul 28 Javascript
JavaScript中 ES6 generator数据类型详解
Aug 11 Javascript
jQuery实现对象转为url参数的方法
Jan 11 Javascript
BootStrap selectpicker后台动态绑定数据
Jun 01 Javascript
浅谈Vue.js中ref ($refs)用法举例总结
Dec 19 Javascript
PM2自动部署代码步骤流程总结
Dec 10 Javascript
基于iview的router常用控制方式
May 30 Javascript
jQuery中DOM常见操作实例小结
Aug 01 jQuery
对layui中table组件工具栏的使用详解
Sep 19 Javascript
实现AJAX异步调用和局部刷新的基本步骤
Mar 17 Javascript
MutationObserver在页面水印实现起到的作用详解
Jul 07 #Javascript
js作用域及作用域链工作引擎
Promise静态四兄弟实现示例详解
Jul 07 #Javascript
Three.js实现雪糕地球的使用示例详解
二维码条形码生成的JavaScript脚本库
Jul 07 #Javascript
JS实现简单的九宫格抽奖
JS实现九宫格拼图游戏
You might like
PHP的一个基础知识 表单提交
2011/07/04 PHP
PHP按行读取文件时删除换行符的3种方法
2014/05/04 PHP
php实现的IMEI限制的短信验证码发送类
2015/05/05 PHP
PHP Streams(流)详细介绍及使用
2015/05/12 PHP
帝国cms目录结构分享
2015/07/06 PHP
PHP常见错误提示含义解释(实用!值得收藏)
2016/04/25 PHP
php 命名空间(namespace)原理与用法实例小结
2019/11/13 PHP
为JavaScript提供睡眠功能(sleep) 自编译JS引擎
2010/08/16 Javascript
$.get获取一个文件的内容示例代码
2013/09/11 Javascript
js鼠标及对象坐标控制属性详细解析
2013/12/14 Javascript
javascript实现的HashMap类代码
2014/06/27 Javascript
JavaScript通过select动态更换图片的方法
2015/03/23 Javascript
Position属性之relative用法
2015/12/14 Javascript
jQuery实用小技巧_输入框文字获取和失去焦点的简单实例
2016/08/25 Javascript
AngularJS模仿Form表单提交的实现代码
2016/12/08 Javascript
bootstrap daterangepicker双日历时间段选择控件详解
2017/06/15 Javascript
JavaScript变量作用域_动力节点Java学院整理
2017/06/27 Javascript
Vue实现美团app的影院推荐选座功能【推荐】
2018/08/29 Javascript
详解@Vue/Cli 3 Invalid Host header 错误解决办法
2019/01/02 Javascript
vue添加class样式实例讲解
2019/02/12 Javascript
对vuex中getters计算过滤操作详解
2019/11/06 Javascript
详解vue路由
2020/08/05 Javascript
[01:48]帕吉至宝加入游戏,遗迹战场现“千劫神屠”
2018/04/07 DOTA
socket + select 完成伪并发操作的实例
2017/08/15 Python
python爬虫获取京东手机图片的图文教程
2017/12/29 Python
python实现给微信指定好友定时发送消息
2019/04/29 Python
python中判断文件结束符的具体方法
2020/08/04 Python
业务员岗位职责
2013/11/16 职场文书
加油口号大全
2014/06/13 职场文书
在宿舍喝酒的检讨书
2014/09/28 职场文书
民主评议党员个人总结
2015/02/13 职场文书
2015年万圣节活动总结
2015/03/24 职场文书
工厂门卫岗位职责
2015/04/13 职场文书
欠款证明
2015/06/24 职场文书
技术转让协议书
2016/03/19 职场文书
Python如何使用logging为Flask增加logid
2021/03/30 Python