用原型实现Class的各项语法

本人之前对Class一直不够重视。平时对原型的使用,也仅限于在构造函数的prototype上挂属性。原型尚且用不着,更何况你Class只是原型的一颗语法糖?

直到公司开始了一个webgis项目,使用openlayers。看了下openlayers的代码,整个api都是用Class构建的。我才意识到,对Class的使用已经很普遍了,很多库都在基于Class构建的,所以必须把它研究明白了。

我是这么想的,先把原型搞明白,再把Class搞明白,最后实践一下,把Class的各项语法,用原型还原出来。这样,一定能很好的掌握JS的面向对象思想。

一、回顾一下对象的原型

对于一门编程语言来说,把同一类事物抽象出一个数据结构,并以此为模板创建实例,是一个基本的需求,这也就是面向对象的思想。

JS从一开始就被设计成一门面向对象的语言,它是通过构造函数来作为“模板”,来生成对象的。比如这样:

function Student(name, age) {
    this.name = name;
    this.age = age;
    this.say = function(intro) {
        console.log(intro);
    }
}
let xiaohong = new Student('小红', 14);
let xiaoming = new Student('小明', 15);
xiaohong.say('我是小红,我喜欢看电影'); //我是小红,我喜欢看电影
xiaoming.say('我是小明,我喜欢小红'); //我是小明,我喜欢小红

JS中的构造函数和普通函数有什么不同呢?

其实,任何一个普通函数通过new运算符调用,都可以称作构造函数。构造函数的特别之处,就是里面多了一个this。这个this就是构造函数所返回的对象。普通函数里面没有this,通过new调用得到的是一个空对象,没有任何意义。

现在,可以通过构造函数轻松生成同一类事物——学生了。他们都有姓名和年龄,却又各不相同。

然而,还有一些东西,是他们都一样的,是他们共同分享的。比如他们的班级都是三年二班,班主任都是周杰伦。怎么表示这种关系呢?

这就是prototype,也就是原型。

在JS中,所有函数都有一个prototype属性。这是一个对象,默认只有一个属性:constructor,指向构造函数自身。也就是说,构造函数和原型,通过prototype和construcotr,相互引用。

通过构造函数生成的所有对象,共同分享这个prototype对象。

function Student(name, age) {
    this.name = name;
    this.age = age;
}
Student.prototype.className = '三年二班';
Student.prototype.teacher = '周杰伦';
let xiaohong = new Student('小红', 14);
let xiaoming = new Student('小明', 15);
console.log(xiaohong.className, xiaohong.teacher); //三年二班 周杰伦
console.log(xiaoming.className, xiaoming.teacher); //三年二班 周杰伦

现在,我们有了构造函数、原型、对象。它们是什么关系呢?

构造函数就是原型和对象之间的纽带,负责为原型这个“妈妈”生“孩子”,也就是对象。原型上的东西,是所有孩子都一样的,比如国家、肤色。构造函数上的东西,是孩子们可以个性化的,比如相貌、身高。

也许你还听说过constructor和__proto__,它们又是做什么的?很简单,它们的存在,只是为了:让构造函数、原型、对象三者之间可以相互引用。

function Student(name, age) {
    this.name = name;
    this.age = age;
}
let xiaohong = new Student('小红', 14);
console.log(Student.prototype); //{constructor: Student}
console.log(Student.prototype.constructor === Student); //true
console.log(xiaohong.__proto__ === Student.prototype); //true
console.log(xiaohong.constructor === Student); //true

通过===我们可以得知,它们之间确实是相互引用关系,而不是只是值想等的关系。

二、用原型实现Class的各项语法

接下来,我们用原型的写法,把Class的各项语法还原出来。

(1)构造函数(实例属性和方法)

//Class语法
class Student {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
}
//原型语法
function Student(name, age) {
    this.name = name;
    this.age = age;
}

(2)原型的属性和方法

//Class语法
class Student {
    teacher = '周杰伦';
    say() {
        console.log('认真听讲!');
    }
}
//原型语法
function Student() {}
Student.prototype.teacher = '周杰伦';
Student.prototype.say = function() {
    console.log('认真听讲!');
};
 
let xiaohong = new Student();
console.log(xiaohong.teacher); //周杰伦
xiaohong.say(); //认真听讲!

(3)静态属性和方法

//Class语法
class Student {
    static teacher = '周杰伦';
    static say() {
        console.log('认真听讲!');
    }
}
//原型语法
function Student() {}
Student.teacher = '周杰伦';
Student.say = function() {
    console.log('认真听讲!');
};
 
console.log(Student.teacher); //周杰伦
Student.say(); //认真听讲!

(4)继承

// Class语法
class Person {
    constructor(name) {
        this.name = name;
    }
    say() {
        console.log('我会说话');
    }
    static think() {
        console.log('人类会思考');
    }
}
class Student extends Person {
    constructor(name, school) {
        super(name);
        this.school = school;
    }
    study() {
        console.log('我要上学');
    }
}
let xiaohong = new Student('小红', '十一学校');
 
// 原型语法
function Person(name) {
    this.name = name;
}
Person.prototype.say = function() {
    console.log('我会说话');
}
Person.think = function() {
    console.log('人类会思考');
}
 
function Student(school) {
    this.school = school;
}
Student.prototype = new Person('小红');
Student.prototype.constructor = Student;
Student.prototype.study = function() {
    console.log('我要上学');
};
Object.setPrototypeOf(Student, Person);
let xiaohong = new Student('十一学校');
 
console.log(xiaohong.name); //小红
console.log(xiaohong.school); //十一学校
xiaohong.say(); //我会说话
xiaohong.study(); //我要上学
Student.think(); //人类会思考

由此可见,特别在继承的语法上,Class要比原型简单的多。

总的来说,作为原型的语法糖,Class不仅语义更明确,更好理解,写法上也更简单。所以,以后就愉快的使用Class吧!

本人水平非常有限,写作主要是为了把自己学过的东西捋清楚。如有错误,还请指正,感激不尽。

文章转载自:路泽宇

原文链接:https://www.cnblogs.com/luzeyu/p/17818549.html

体验地址:引迈 - JNPF快速开发平台_低代码开发平台_零代码开发平台_流程设计器_表单引擎_工作流引擎_软件架构

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Sectigo有几种入门https证书买一年送一月

https证书是由CA认证机构颁发的数字证书,对网站传输数据进行加密,维护互联网环境安全,消除浏览器“不安全”提示。Digicert、Thawte、Sectigo等都是知名的CA认证机构,颁发的https证书中有很多都是入门级的https证书,其…

蓝桥杯基础数据结构(java版)

引言 数据结构数据结构。所以数据结构是一个抽象的概念。其目的是为了更好的组织数据方便数据存储。下面我们来看一些简单的数据储存方式 输入和输出 这里先介绍java的输入和输出。简单引入,不过多详细介绍,等我单一写一篇的时候这里会挂上链接 简单的…

【乱七八糟的经验】【个人】打羽毛球如何球球都接稳

从发球开始,球拍就不要离开视线之外。 为了达到这个目的,在待机时右手小臂就需要抬起一个角度,让球拍能在视野右下角: 然后球来时,球如果高,视线往上看,视野角度上移,球拍也要随之上…

代码随想录算法训练营Day22 | 491.非递减子序列、46.全排列、47.全排列||

LeetCode 491 非递减子序列 本题思路&#xff1a;什么情况下要搜集结果&#xff0c;可以写一个判断函数&#xff0c;当大小大于2的时候&#xff0c;并且&#xff0c;是非递减的&#xff0c;才能加入结果集中。需要注意的就是树层的一个去重操作。 class Solution {List<Int…

【PHP】PHP利用ffmreg获取音频、视频的详细信息

目录 一、目的 二、下载并安装ffmreg 三、PHP代码 四、运行结果 一、目的 使用PHP利用ffmreg获取音频、视频的详细信息&#xff0c;音视频总时长、码率、视频分辨率、音频编码、音频采样频率、实际播放时间、文件大小。 二、下载并安装ffmreg 1、下载地址&#xff1a;htt…

现在00后开发人员不晓得加班为何事嘛?

我招了两个做HTML5开端开发的人员&#xff0c;是从培训机构招来的&#xff0c;按理说他们应该很努学很用样才对的。他们上班第一天我就跟他们讲&#xff0c;我们不需要上、下班打卡&#xff1b;你们也不必太过担心迟到或早退。因为我们搞开发的人员首先是按自己的工作任务完成情…

【23种设计模式应用场景汇总】

23种设计模式应用场景汇总 设计模式是一种在软件开发中解决特定问题的通用解决方案。下面我将尝试将23种设计模式融入到一个场景中&#xff1a; 假设我们正在开发一个在线购物系统&#xff0c;我们可以使用以下设计模式&#xff1a; 1. 工厂方法模式&#xff1a;当用户在网站上…

云贝教育 |【OceanBase】OBCA认证考试预约流程

一、OBCA账号登录/注册&#xff0c;链接 https://www.oceanbase.com/ob/login/mobile?gotohttps%3A%2F%2Fwww.oceanbase.com%2Ftraining%2Fdetail%3Flevel%3DOBCA 注册完之后&#xff0c;请点击右上“登录”进行实名认证 OBCA考试报名链接&#xff1a;https://www.oceanbase.…

IDEA2023的激活与安装(全网最靠谱,最快捷的方式)

前言&#xff1a; 相信很多小伙伴已经开始了java的学习之旅&#xff0c;想要更快乐的学习当然少不了IDEA这个得力的开发工具软件。但是IDEA是付费的&#xff0c;免费版功能有太少&#xff0c;怎么才能既免费&#xff0c;又能使用上正式版呢&#xff01;当然还是激活啦&#xf…

数据结构与算法之美学习笔记:48 | B+树:MySQL数据库索引是如何实现的?

目录 前言算法解析总结引申 前言 本节课程思维导图&#xff1a; 作为一个软件开发工程师&#xff0c;你对数据库肯定再熟悉不过了。作为主流的数据存储系统&#xff0c;它在我们的业务开发中&#xff0c;有着举足轻重的地位。在工作中&#xff0c;为了加速数据库中数据的查找速…

maven导入无法拉取所需依赖

maven导入无法拉取所需依赖 1.原因2.解决搞定收工&#xff01; 1.原因 公司使用的是gradle&#xff0c;配置的私有云&#xff0c;maven里面配置私有云完全使用不了&#xff0c;无论配置国内还是国外的&#xff0c;导入的项目报错拉不到jar包。 <mirror><id>mirro…

【小智好书分享• 第一期】深度学习计算机视觉

目录 一、内容简介二、内页插图三、书籍目录四、粉丝福利 &#x1f389;博客主页&#xff1a;小智_x0___0x_ &#x1f389;欢迎关注&#xff1a;&#x1f44d;点赞&#x1f64c;收藏✍️留言 &#x1f389;系列专栏&#xff1a;好书分享 &#x1f389;代码仓库&#xff1a;小智…

汇编代码生成和编译器的后端

1.前置程序&#xff1a;语义分析和中间代码生成 基于SLR(1)分析的语义分析及中间代码生成程序-CSDN博客https://blog.csdn.net/lijj0304/article/details/135097554?spm1001.2014.3001.5501 2.程序目标 在前面编译器前端实现的基础上&#xff0c;将所生成的中间代码翻译成某…

Windows11搭建Python环境(2)- Anaconda虚拟环境中安装Git

在搭建MetaGPT运行环境过程中&#xff0c;使用了Anaconda虚拟环境&#xff0c;在运行MetaGPT时出现错误&#xff1a; 可以看到是没有找到git指令。 在Windows上安装Git&#xff0c;可以直接去官网下载.exe文件&#xff0c;然后安装即可。 但是上面安装完成后&#xff0c;是无…

三使用Docker Hub管理镜像

使用Docker Hub管理镜像 Docker Hub是Docker官方维护的Docker Registry&#xff0c;上面存放着很多优秀的镜像。不仅如此&#xff0c;Docker Hub还提供认证、工作组结构、工作流工具、构建触发器等工具来简化我们的工作。 前文已经讲过&#xff0c;我们可使用docker search 命…

【VUE】element-ui+vue-router:实现导航栏跳转路由

实现目的 页面中点击导航栏菜单中的某一选项卡&#xff0c;使用导航栏进行路由跳转。如下图所示。 我们设计三个页面&#xff0c;首页是App.vue, 两个导航页面分别为 About.vue, Home.vue。在App.vue 页面中有导航菜单&#xff0c;点击菜单分别跳转。 1. 安装 npm install v…

2024中国国际光伏展

2024中国国际光伏展将是中国举办的一个重要的展览会&#xff0c;专门展示光伏技术和产业的最新发展。该展览会将吸引国内外光伏企业、研究机构、政府机构和专业人士参展和参观。 在2024年的中国国际光伏展上&#xff0c;参展商将展示他们最新的光伏技术、设备和产品&#xff0c…

Jetson AGX Orin安装archiconda、Pytorch

想在Jetson AGX Orin创建一个虚拟环境&#xff0c;然后安装pytorch&#xff0c;过程中遇到了很多的坑&#xff0c;这篇文章主要用于记录过程~因为Orin本身是Arm架构&#xff0c;X86架构可以装Anaconda&#xff0c;对于ARM要装archiconda。 1.安装archiconda 1.1确定操作系统架…

[自动驾驶算法][从0开始轨迹预测]:二、自动驾驶系统中常用的坐标系及相应的转换关系

自动驾驶中常见的坐标系与坐标转换 1. 传感器坐标系1.1 相机坐标系统1) 相机相关基础知识2) 相机各坐标系图像/像素坐标系相机坐标系像平面坐标系 3) 相机各坐标系之间的转换像平面坐标系到像素坐标系的转换&#xff08;平移缩放变换&#xff09;相机坐标系转像平面坐标系&…

uniCloud ---- uni-captch实现图形验证码

目录 用途说明 组成部分 目录结构 原理时序 云端一体组件介绍 验证码配置&#xff08;可选&#xff09;&#xff1a; 普通验证码组件 公共模块 云函数公用模块 项目实战 创建云函数 创建注册页 创建云函数 关联公用模块 uni-captcha 刷新验证码 自定义实现 验…