ES6 Class(类) 总结(九)

ES6 中的 class 是一种面向对象编程的语法糖,提供了一种简洁的方式来定义对象的结构和行为。

JavaScript 语言中,生成实例对象的传统方法是通过构造函数。下面是一个例子。

function Point(x, y) {this.x = x;this.y = y;
}
Point.prototype.toString = function () {return '(' + this.x + ', ' + this.y + ')';
};
var p = new Point(1, 2);

基本上,ES6 的 class 可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的 class 写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。上面的代码用 ES6 的 class 改写,就是下面这样:

class Point {constructor(x, y) {this.x = x;this.y = y;}toString() {return '(' + this.x + ', ' + this.y + ')';}
}

ES6 的类,完全可以看作构造函数的另一种写法:

class Point {// ...
}
typeof Point // "function"
Point === Point.prototype.constructor // true----------------------------------------------------------------------------
class Point {constructor() {// ...}toString() {// ...}toValue() {// ...}
}
// 等同于
Point.prototype = {constructor() {},toString() {},toValue() {},
};

主要特性:

1. 声明式语法:使用 class 关键字声明类。
2. 构造函数:使用 constructor 方法初始化类实例。
3. 实例方法:定义在类内部的普通方法,使用 this 访问实例属性。
4. 静态方法:使用 static 关键字定义,不依赖于类的实例。
5. 实例属性:在构造函数中初始化,或使用字段声明语法(目前是 Stage 3 proposal)。
6. 继承:使用 extends 关键字实现。
7. super 关键字:在子类的构造函数中调用父类的构造函数或方法。
8. getter 和 setter:使用 get 和 set定义属性的访问器。
9. 私有属性和方法:使用 # 定义私有属性和方法(目前是 Stage 3 proposal)。

1. 基本类定义和实例化

class Point {constructor(x, y) {this.x = x;this.y = y;}toString() {return `Point(${this.x}, ${this.y})`;}
}let point = new Point(10, 20);
console.log(point.toString()); // 输出: Point(10, 20)

2. 静态方法、属性

class MathUtils {constructor() {console.log(MyClass.myStaticProp); // 42}static add(a, b) {return a + b;}static myStaticProp = 42;
}console.log(MathUtils.add(1, 2)); // 输出: 3

3. 继承和 super

class Rectangle {constructor(width, height) {this.width = width;this.height = height;}area() {return this.width * this.height;}
}class Square extends Rectangle {constructor(sideLength) {super(sideLength, sideLength);}
}let square = new Square(5);
console.log(square.area()); // 输出: 25

4. getter 和 setter

class Rectangle {constructor(width, height) {this.width = width;this.height = height;}get area() {return this.width * this.height;}set width(newWidth) {if (newWidth > 0) {this.width = newWidth;} else {console.log("Width must be positive.");}}
}let rect = new Rectangle(4, 5);
console.log(rect.area); // 输出: 20
rect.width = -10; // 输出: Width must be positive.

class的注意点

(1)严格模式

类和模块的内部,默认就是严格模式,所以不需要使用 use strict 指定运行模式。只要你的代码写在类或模块之中,就只有严格模式可用。考虑到未来所有的代码,其实都是运行在模块之中,所以 ES6 实际上把整个语言升级到了严格模式。

(2)不存在提升

类不存在变量提升(hoist),这一点与 ES5 完全不同。

new Foo(); // ReferenceError
class Foo {}//不会报错
//因为 Bar 继承 Foo 的时候, Foo 已经有定义了。
//但是,如果存在 class 的提升,上面代码就会报错,
//因为 class 会被提升到代码头部,而 let 命令是不提升的,
//所以导致 Bar 继承 Foo 的时候, Foo 还没有定义。
{let Foo = class {};class Bar extends Foo {}
}

(3)name 属性

由于本质上,ES6 的类只是 ES5 的构造函数的一层包装,所以函数的许多特性都被Class继承,包括 name 属性。

class Point {}
Point.name // "Point"
//name 属性总是返回紧跟在 class 关键字后面的类名。

(4)Generator 方法

如果某个方法之前加上星号( * ),就表示该方法是一个 Generator 函数。

class Foo {constructor(...args) {this.args = args;}* [Symbol.iterator]() {for (let arg of this.args) {yield arg;}}
}
for (let x of new Foo('hello', 'world')) {console.log(x);
}
// hello
// world//Foo 类的 Symbol.iterator 方法前有一个星号,表示该方法是一个 Generator 函数。 
//Symbol.iterator 方法返回一个 Foo 类的默认遍历器, for...of 循环会自动调用这个遍历器。

(5)this 的指向

类的方法内部如果含有 this ,它默认指向类的实例。但是,必须非常小心,一旦单独使用该方法,很可能报错。

class Logger {printName(name = 'there') {this.print(`Hello ${name}`);}print(text) {console.log(text);}
}
const logger = new Logger();
const { printName } = logger;
printName(); // TypeError: Cannot read property 'print' of undefined

避免使用this,在构造方法中绑定 this:

class Logger {constructor() {this.printName = this.printName.bind(this);}// ...
}

避免使用this,使用箭头函数:

class Obj {constructor() {this.getThis = () => this;}
}
const myObj = new Obj();
myObj.getThis() === myObj // true

避免使用this,使用 Proxy

function selfish (target) {const cache = new WeakMap();const handler = {get (target, key) {const value = Reflect.get(target, key);if (typeof value !== 'function') {return value;}if (!cache.has(value)) {cache.set(value, value.bind(target));}return cache.get(value);}};const proxy = new Proxy(target, handler);return proxy;
}
const logger = selfish(new Logger());

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/44190.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用定时器消除抖动

问题:定时器中断和按键中断属于什么操作模式,轮询吗? 具体怎么实现 定时器中断 (判断) 时间参数 按键中断(修改) 中断 向量表.s文件 DCD SysTick_Handler …

如何理解跨界营销?详解跨界营销的主要类型和方法!

跨界营销是一种创新的营销策略,它巧妙地捕捉不同行业、产品和消费者偏好之间的共通点和潜在联系。这种策略将看似不相关的元素相互融合,相互影响,创造出一种全新的生活方式和审美观念,以此吸引目标消费者群体的注意和青睐。 通过…

Oracle左连接过滤条件注意事项

1、left join 结果集行数与主表查询结果集行数一致 2、主表与辅表多关联条件要括起来 3、对于辅表的过滤条件写在on后面是先对辅表过滤后再与主表关联,写在where后面是对主表与辅表关联后的结果集再进行过滤 4、对于主表的过滤条件写在on后面不生效,只能…

LiveNVR监控流媒体Onvif/RTSP用户手册-用户管理:编辑、添加用户、关联通道、重置密码、删除、过滤搜索

LiveNVR监控流媒体Onvif/RTSP用户手册-用户管理:编辑、添加用户、关联通道、重置密码、删除、过滤搜索 1、用户管理1.1、添加用户1.2、关联通道1.3、重置密码1.4、编辑1.5、删除1.6、过滤搜索 2、RTSP/HLS/FLV/RTMP拉流Onvif流媒体服务 1、用户管理 1.1、添加用户 点击用户管理…

学习网络的第一步:全面解析OSI与TCP/IP模型

我是小米,一个喜欢分享技术的29岁程序员。如果你喜欢我的文章,欢迎关注我的微信公众号“软件求生”,获取更多技术干货! Hello,大家好!我是你们的好朋友小米。今天我们来聊一聊网络基础知识中的重量级选手——OSI模型和TCP/IP模型!网络的世界就像一个巨大的迷宫,而这两个…

Docker 镜像构建报 exec xxx.sh: no such file or directory

问题记录 场景: 处于对nacos docker 部署最新版本的探究,但是nacos/nacos-server镜像拉取不到最新版本,官网也是给出自己构建镜像的方案。 具体步骤很简单,先clone项目,然后签出你要的nacos版本,通过docke…

算法力扣刷题记录 四十二【101. 对称二叉树、100.相同的树、572.另一个树的子树】

前言 二叉树篇,开始对二叉树操作练习。 记录 四十二【101. 对称二叉树】。 继续。 一、题目阅读 给你一个二叉树的根节点 root , 检查它是否轴对称。 示例 1: 输入:root [1,2,2,3,4,4,3] 输出:true示例 2&#x…

S5730交换机上配置访问控制列表(ACL)、OSPF路由和PIM-SM组播

配置访问控制列表(ACL) 假设我们创建一个简单的ACL,允许或拒绝特定流量通过。 进入系统视图 sys 创建一个标准ACL,允许192.168.1.0/24网段的流量通过 acl number 2001 rule 5 permit source 192.168.1.0 0.0.0.255 其他流量默…

Pytest单元测试系列[v1.0.0][Pytest基础]

Pytest安装与配置 和Unittest一样,Pytest是另一个Python语言的单元测试框架,与Unittest相比它的测试用例更加容易编写、运行方式更加灵活、报错信息更加清晰、断言写法更简洁并且它可以运行有unittest和nose编写的测试用例。 Pytest 安装 启动命令行&…

【Pytorch】Conda环境下载慢换源/删源/恢复默认源

文章目录 背景临时换源永久换源打开conda配置condarc换源执行配置 命令行修改源添加源查看源 删源恢复默认源使用示范 背景 随着实验增多,需要分割创建环境的情况时有出现,在此情况下使用conda create --name xx python3.10 pytorch torchvision pytorc…

uni-app三部曲之二: 封装http请求

1.引言 前面一篇文章写了使用Pinia进行全局状态管理。 这篇文章主要介绍一下封装http请求,发送数据请求到服务端进行数据的获取。 感谢: 1.yudao-mall-uniapp: 芋道商城,基于 Vue Uniapp 实现,支持分销、拼团、砍价、秒杀、优…

电脑自动重启是什么原因呢?99%人都不知道的解决办法,直接打破循环

当你的电脑突然毫无预警地自动重启,不仅打断了工作流程,还可能导致未保存的数据丢失,这无疑是一件令人沮丧的事情。那么,电脑自动重启是什么原因呢?有什么方法可以解决呢?别担心,在大多数情况下…

Android Retrofit post请求,@Body传递的参数转义问题

文章目录 问题解决原因解决方案一:自己拼接json字符串,Body使用RequestBody类型,比如解决方案二:修改Retrofit的Gson 问题 因为传递的参数字符串中有等号 ,结果传递的时候,打印出来 原始字符串&#xff…

【AIGC】GPT-4深度解析:自然语言处理的新纪元

目录 第一部分:GPT-4技术概览 1.1 GPT-4模型架构 多模态输入处理 专家混合(MoE)技术详解 参数规模和模型复杂性 1.2 GPT-4的关键技术创新 上下文窗口的扩展 模型性能预测技术 1.3 GPT-4与其他模型的比较 性能对比 架构差异 第二部…

docker-2

27.构建python应用镜像-dockerfile实践项目 1.基于官方的镜像,构建python代码运行环境 dockerfile 2.运行镜像,开启一个读写的容器空间(定制操作,将代码丢进去,运行调试) 3.提交这个变化的容器层数据&#…

cal命令

1、命令详解: cal(全称:Calendar)该命令用来显示当前日历或者指定日期的公历。 2、官方参数: -1, --one 仅显示当前月份(默认)-3, --three 显示上个月、当前月和下个月-s, --sunday…

谷粒商城P85发布商品时规格参数不显示问题

P85讲,发布商品,点击下一步之后,发现规格参数不显示 打开控制台发现报错forEach...错误 查了问题原因,发现返回的分组中个别组的关联属性(attrs)可能为null 所以这个时候,需要确保后端返回的attrs不能为null 方式1…

数据结构之顺序存储线性表实现详解与示例(C,C#,C++)

文章目录 一、顺序存储线性表的基本概念二、顺序存储线性表的实现1、数据结构定义2、初始化3、添加元素4、访问元素5、修改元素6、删除元素7、销毁 三、示例C语言示例C#语言示例C语言示例 顺序存储线性表是一种基本的数据结构,它将线性表的元素按照一定的顺序存放在…

Mysql中存储过程、存储函数、自定义函数、变量、流程控制语句、光标/游标、定义条件和处理程序的使用示例

场景 存储过程 存储过程是一组为了完成特定功能的SQL语句集合。使用存储过程的目的是将常用或复杂的工作预先用SQL语句写好并用一个指定名称存储起来, 这个过程经编译和优化后存储在数据库服务器中,因此称为存储过程。 当以后需要数据库提供与己定义…

分享WPF的UI开源库

文章目录 前言一、HandyControl二、AduSkin三、Adonis UI四、Panuon.WPF.UI五、LayUI-WPF六、MahApps.Metro七、MaterialDesignInXamlToolkit八、FluentWPF九、DMSkin总结 前言 分享WPF的UI开源库。 一、HandyControl HandyControl是一套WPF控件库,它几乎重写了所…