当前位置: 首页 > news >正文

js 类、原型及class

 js   一直允许定义类。ES6新增了相关语法(包括class关键字)让创建类更容易。新语法创建的类和老式的类原理相同。js 的类和基于原型的继承机制与Java等语言中的类和继承机制有着本质区别。

1 类和原型

类意味着一组对象从同一个原型对象继承属性。因此,原型对象是类的核心特征。

用工厂函数创建和初始化该类的新实例:

function range(from, to) {let r = Object.create(range.methods);r.from = from;r.to = to;return r;
}range.methods = {includes(x) {return this.from <= x && x <= this.to;},*[Symbol.iterator]() {for (let x = Math.ceil(this.from); x <= this.to; x++)yield x;},toString() {return "(" + this.from + "..." + this.to + ")";},}let r = range(1,3);
console.log(r.includes(2));
console.log(r + ""); // 调用的是toString()方法
console.log(r); // 打印对象本身,而非调用toString()方法
console.log([...r])

2 类和构造函数

只有函数(不包括箭头函数、生成器函数和异步函数)对象才有prototype属性。

上面定义类的写法非习惯写法,因为它没有定义构造函数。构造函数要使用new关键字调用,会自动创建新对象,因此构造函数本身只需初始化新对象的状态。构造函数调用的关键在于构造函数的prototype属性将被用作新对象的原型。

function Range(from,to) {this.from = from;this.to = to;
}// 原型属性名必须命名为prototype
Range.prototype = {includes(x) {return this.from <= x && x <= this.to;},*[Symbol.iterator]() {for (let x = Math.ceil(this.from); x <= this.to; x++)yield x;},toString() {return "(" + this.from + "..." + this.to + ")";}
}let r = new Range(1,3);
console.log(r.includes(2));
console.log(r + "");
console.log(r)
console.log([...r])

2.1 instanceof

当且仅当两个对象继承同一个原型对象时,它们才是同一个类的实例。instanceof 操作符用于检查某个对象是否是某个特定类的实例。

严格来讲,instanceof操作符并非检查对象是否通过某个构造函数初始化,而是检查对象是否继承了原型。(不一定是直接继承)

let prototype = {}function Person() {}function Animal() {}let p = new Person();console.log( p instanceof Person); // true
console.log( p instanceof Animal); // falsePerson.prototype = prototype
Animal.prototype = prototypelet p2 = new Person()
console.log( p2 instanceof Person); // true
console.log( p2 instanceof Animal); // true

2.2 constructor 属性

prototype属性的值是一个对象,其有一个不可枚举的constructor属性,该属性的值就是prototype所属的函数对象:

let F = function() {};

let p = F.prototype;

let c = p.constructor;

c === F; //true

3 使用class关键字定义类

class关键字是在ES6才引入的。

使用class来定义类:

class Person {constructor(age) {this.age = age;}showAge() {console.log(this.age);}}let p = new Person(12);
p.showAge();let Animal = class {constructor(name) {this.name = name}showName() {console.log(this.name)}
}let a = new Animal("大象");
a.showName()

与函数声明不同,类声明不会“提升”(函数定义就像是会被提升到包含文件或包含函数顶部一样,而类声明不会)。

类声明除了语句到形式外,还有表达式的形式。不过这种形式并不常用:

let Persopn = class { constructor() {} }

3.1 静态方法

在class体中,把static关键字放在方法声明前面可以定义静态方法。静态方法是作为构造函数而非原型的属性定义的。

class Person {static hello() {console.log("hello word")}
}Person.hello(); // hello word
let p = new Person();
p.hello(); // 报错,p.hello is not a function

静态函数必须通过构造函数而非实例调用。

3.2 获取和设置方法

在class 体内,可像对象字面量中一样定义获取方法和设置方法,唯一的区别是类体内的方法后面不加逗号。

class Person {set age(val) {if (val <= 0) throw new TypeError("年龄不能小于0")this.age = val}
}let person = new Person();
person.age = -1
console.log(person.age)

4 子类

ES6之前定义子类的方式是通过原型,ES6则通过extends定义子类。

4.1 子类与原型

function Person() {console.log("Person的构造器")
}Person.prototype = {constructor: Person,showType() {console.log("Person")}
}function Man() {console.log("Man的构造器")
}Man.prototype = Object.create(Person.prototype)
let man = new Man();
man.showType()
console.log(man.constructor)Man.prototype.constructor = Man
console.log(man.constructor)

只有在知道父类实现细节的前提下才可能这样定义子类,健壮的子类化机制应该允许类调用父类的方法和构造函数,在ES6之前,js中没有简单的方法做到这些。

4.2 通过extends和super创建子类

class Person {constructor() {console.log("Person:" + new.target)}
}class Man extends Person {constructor() {super();console.log(this)console.log("Man")}
}class Woman extends Person {constructor() {super();console.log("Woman")}
}let man = new Man();
let woman = new Woman()

注意事项:

1)使用extends关键字定义了一个类,则该类的构造函数必须使用super()调用父类构造器。
    2)在通过super()调用父类构造器之前,不能在构造器中使用this关键字。
    3)new.target引用的是被调用的构造函数。

在实际开发中,并不建议创建很多子类,建议通过“组合”的方式来替代继承。

相关文章:

js 类、原型及class

js 一直允许定义类。ES6新增了相关语法(包括class关键字)让创建类更容易。新语法创建的类和老式的类原理相同。js 的类和基于原型的继承机制与Java等语言中的类和继承机制有着本质区别。 1 类和原型 类意味着一组对象从同一个原型对象继承属性。因此&#xff0c;原型对象是…...

day-30 代码随想录算法训练营 回溯part06

332.重新安排行程 思路&#xff1a;使用unordered_map记录起点机场对应到达机场&#xff0c;内部使用map记录到达机场的次数&#xff08;因为map会进行排序&#xff0c;可以求出最小路径&#xff09; class Solution { public:vector<string>res;unordered_map<stri…...

txt、pcd、las、ply 格式点云基本的读写和显示 (附 python c++ 代码)

一、文本(txt) 1.1、存储结构 使用文本格式存储的点云数据文件结构比较简单,每个点是一行记录,点的信息存储格式为 x y z或者 x y z r g b。 1.2、读取 读取文本格式的点云数据时,可以按照一般的文本读取方法,这里记录一下如何使用open3d读取txt格式的点云数据 impo…...

k8s节点pod驱逐、污点标记

一、设置污点&#xff0c;禁止pod被调度到节点上 kubectl cordon k8s-node-145 设置完成后&#xff0c;可以看到该节点附带了 SchedulingDisabled 的标记 二、驱逐节点上运行的pod到其他节点 kubectl drain --ignore-daemonsets --delete-emptydir-data k8s-node-145 显示被驱逐…...

【项目 计网6】 4.17 TCP三次握手 4.18滑动窗口 4.19TCP四次挥手

文章目录 4.17 TCP三次握手4.18滑动窗口4.19TCP四次挥手 4.17 TCP三次握手 TCP 是一种面向连接的单播协议&#xff0c;在发送数据前&#xff0c;通信双方必须在彼此间建立一条连接。所谓的“连接”&#xff0c;其实是客户端和服务器的内存里保存的一份关于对方的信息&#xff…...

茶叶小笔记

文章目录 茶叶的作用茶叶的主要成分茶多酚氨基酸(蛋白质)生物碱 茶叶的分类乌龙茶铁观音(安溪) 绿茶龙井(西湖)龙井43 绿茶(日照)毛尖(信阳毛尖)太平猴魁六安瓜片 红茶金骏眉大红袍 白茶云南白茶 黄茶黑茶花草茶 茶叶的形状过期茶的利用茶叶蛋大排档泡澡泡脚除湿除臭 茶渣的利用…...

安全开发-JS应用NodeJS指南原型链污染Express框架功能实现审计WebPack打包器第三方库JQuery安装使用安全检测

文章内容 环境搭建-NodeJS-解析安装&库安装安全问题-NodeJS-注入&RCE&原型链案例分析-NodeJS-CTF题目&源码审计打包器-WebPack-使用&安全第三方库-JQuery-使用&安全 环境搭建-NodeJS-解析安装&库安装 Node.js是运行在服务端的JavaScript 文档参考…...

Android JNI系列详解之CMake编译工具的使用

一、CMake工具的介绍 如图所示&#xff0c;CMake工具的主要作用是&#xff0c;将C/C编写的native源文件编译打包生成库文件&#xff08;包含动态库或者静态库文件&#xff09;&#xff0c;集成到Android中使用。 二、CMake编译工具的使用 使用主要是配置两个文件&#xff1a;CM…...

springboot中关于继承WebMvcConfigurationSupport后自定义的全局Jackson失效解决方法,localdate返回数组问题

一般情况下我们在config里增加jackson的全局配置文件就能满足基本的序列化需求&#xff0c;比如前后端传参的问题。 Configuration public class JacksonConfig {public static final String LOCAL_TIME_PATTERN "HH:mm:ss";public static final String LOCAL_DATE…...

LeetCode 面试题 02.03. 删除中间节点

文章目录 一、题目二、C# 题解 一、题目 若链表中的某个节点&#xff0c;既不是链表头节点&#xff0c;也不是链表尾节点&#xff0c;则称其为该链表的「中间节点」。 假定已知链表的某一个中间节点&#xff0c;请实现一种算法&#xff0c;将该节点从链表中删除。 例如&#x…...

Redis知识点总结

概述 Redis诞生于2009年&#xff0c;全称是Remote Dictionarty Server(远程词典服务器) 只支持单线程 非关联&#xff1a;主要指的是表中没有主外键等概念 Redis是一款内存数据库&#xff0c;主要存储键值对类型的数据 基本用法 注意&#xff1a;该操作是在cli中进行的 键名…...

(四)k8s实战-服务发现

一、Service 1、配置文件 apiVersion: v1 kind: Service metadata:name: nginx-svclabels:app: nginx-svc spec:ports:- name: http # service 端口配置的名称protocol: TCP # 端口绑定的协议&#xff0c;支持 TCP、UDP、SCTP&#xff0c;默认为 TCPport: 80 # service 自己的…...

AxureRP制作静态站点发布互联网,内网穿透实现公网访问

AxureRP制作静态站点发布互联网&#xff0c;内网穿透实现公网访问 文章目录 AxureRP制作静态站点发布互联网&#xff0c;内网穿透实现公网访问前言1.在AxureRP中生成HTML文件2.配置IIS服务3.添加防火墙安全策略4.使用cpolar内网穿透实现公网访问4.1 登录cpolar web ui管理界面4…...

[Go版]算法通关村第十四关白银——堆高效解决的经典问题(在数组找第K大的元素、堆排序、合并K个排序链表)

目录 题目&#xff1a;在数组中找第K大的元素解法1&#xff1a;维护长度为k的最小堆&#xff0c;遍历n-k个元素&#xff0c;逐一和堆顶值对比后&#xff0c;和堆顶交换&#xff0c;最后返回堆顶复杂度&#xff1a;时间复杂度 O ( k ( n − k ) l o g k ) O(k(n-k)logk) O(k(n−…...

『FastGithub』一款.Net开源的稳定可靠Github加速神器,轻松解决GitHub访问难题

&#x1f4e3;读完这篇文章里你能收获到 如何使用FastGithub解决Github无法访问问题了解FastGithub的工作原理 文章目录 一、前言二、项目介绍三、访问加速原理四、FastGithub安装1. 项目下载2. 解压双击运行3. 运行效果4. GitHub访问效果 一、前言 作为开发者&#xff0c;会…...

软件开发的201个原则 阅读笔记 第172-201个原则

目录 原则172 做项目总结 第8章 产品保证原则 原则173 产品保证并不是奢侈品 原则 174 尽早建立软件配置管理过程 原则175 使软件配置管理适应软件过程 原则176 组织SCM 独立于项目管理 原则 177 轮换人员到产品保证组织 给所有中间产品一个名称和版本 原则179 控制基准 原则…...

vue 后台管理系统登录 记住密码 功能(Cookies实现)

安装插件 import Cookies from js-cookie 组件引入 import Cookies from js-cookie; 存值&#xff1a; Cookies.set(username, state.account, { expires: 30 }); // username 存的值的名字&#xff0c;state.account 存的值 expires 存储的时间&#xff0c;30天Cookies…...

elementUI moment 年月日转时间戳 时间限制

changeStartTime(val){debuggerthis.startT val// this.startTime parseInt(val.split(-).join())this.startTime moment(val).unix() * 1000 //开始时间毫秒if(this.endTime){this.endTime moment(this.endT).unix() * 1000 //结束时间毫秒if(this.startTime - this.endTi…...

用AI + Milvus Cloud搭建着装搭配推荐系统教程

以下函数定义了如何将图像转换为向量并插入到 Milvus Cloud 向量数据库中。代码会循环遍历所有图像。(注意:如果需要开启 Milvus Cloud 全新特性动态 Schema,需要修改代码。) 查询向量数据库 以下代码演示了如何使用输入图像查询 Milvus Cloud 向量数据库,以检索和上传…...

大数据领域都有什么发展方向

近年来越来越多的人选择大数据行业&#xff0c;大数据行业前景不错薪资待遇好&#xff0c;各大名企对于大数据人才需求不断上涨。 大数据从业领域很宽广&#xff0c;不管是科技领域还是食品产业&#xff0c;零售业等都是需要大数据人才进行大数据的处理&#xff0c;以提供更好…...

前端倒计时误差!

提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...

8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂

蛋白质结合剂&#xff08;如抗体、抑制肽&#xff09;在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上&#xff0c;高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术&#xff0c;但这类方法普遍面临资源消耗巨大、研发周期冗长…...

智能在线客服平台:数字化时代企业连接用户的 AI 中枢

随着互联网技术的飞速发展&#xff0c;消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁&#xff0c;不仅优化了客户体验&#xff0c;还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用&#xff0c;并…...

【Go】3、Go语言进阶与依赖管理

前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课&#xff0c;做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程&#xff0c;它的核心机制是 Goroutine 协程、Channel 通道&#xff0c;并基于CSP&#xff08;Communicating Sequential Processes&#xff0…...

高危文件识别的常用算法:原理、应用与企业场景

高危文件识别的常用算法&#xff1a;原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件&#xff0c;如包含恶意代码、敏感数据或欺诈内容的文档&#xff0c;在企业协同办公环境中&#xff08;如Teams、Google Workspace&#xff09;尤为重要。结合大模型技术&…...

(转)什么是DockerCompose?它有什么作用?

一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用&#xff0c;而无需手动一个个创建和运行容器。 Compose文件是一个文本文件&#xff0c;通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...

selenium学习实战【Python爬虫】

selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...

C++使用 new 来创建动态数组

问题&#xff1a; 不能使用变量定义数组大小 原因&#xff1a; 这是因为数组在内存中是连续存储的&#xff0c;编译器需要在编译阶段就确定数组的大小&#xff0c;以便正确地分配内存空间。如果允许使用变量来定义数组的大小&#xff0c;那么编译器就无法在编译时确定数组的大…...

SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题

分区配置 (ptab.json) img 属性介绍&#xff1a; img 属性指定分区存放的 image 名称&#xff0c;指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件&#xff0c;则以 proj_name:binary_name 格式指定文件名&#xff0c; proj_name 为工程 名&…...

IP如何挑?2025年海外专线IP如何购买?

你花了时间和预算买了IP&#xff0c;结果IP质量不佳&#xff0c;项目效率低下不说&#xff0c;还可能带来莫名的网络问题&#xff0c;是不是太闹心了&#xff1f;尤其是在面对海外专线IP时&#xff0c;到底怎么才能买到适合自己的呢&#xff1f;所以&#xff0c;挑IP绝对是个技…...