javascript中的class基础入门(1)

news2024/11/14 13:55:05

javascript中的class

start

  • 最近在学习:cocos ,准备自己制作小游戏。过程中遇到不少疑问,我计划将这些疑问写成一个系列博客,用以记录。
  • 这篇文章来了解 class

1. 前言

1. 前言

  1. 本文对应版本 Cocos Creator 3.8
  2. Cocos Creator3.x编写脚本的语言是 TypeScript,在了解 TypeScript 中的语法之前,我们先掌握 javascript 中的 class
  3. 后面为了方便描述,javascript 我简称为 jsTypeScript 简称为 ts

ts 可以理解为是具有类型语法的js,用大白话说,ts 是基于 js,扩充了类型语法。

  1. 本文仅对 class 主要内容进行说明,更详细说明可参考 阮一峰-ECMAScript 6 入门-class基础语法

2. class 基础介绍

2.1 如何定义class?

// 直接使用 class 关键词定义即可
class Point {}

注意事项:

  1. class 小写;
  2. Point 也就是类名,按规范推荐首字母大写;
  3. 和定义函数不同,定义类,类名后不需要增加小括号;

2.2 如何使用class?

定义一个 class ,结合 new 关键词我们可以创建一个对象(创建出来的对象,我们叫它:实例对象

比如:

class Point {}

var p = new Point()
// p 就是一个实例对象

2.3 class 可以看做 es5 中构造函数写法的语法糖

js 中创建实例对象,是有两种方式:

  1. 在早期的代码中,往往会通过构造函数的方式去实现。
  2. 在 es6 中,引入了 class 关键词,通过 class 实现。

class 的绝大部分功能,ES5 都可以做到。因此为了加深印象,在学习 class 关键词的时候,相同代码,我会列出 ES5 中如何实现的。

es6中的“类”

class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }

  toString() {
    return '(' + this.x + ', ' + this.y + ')';
  }
}

var p = new Point(1, 2)

es5中的“类”

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)

// 构造函数的形式

在这里插入图片描述

注意事项:

  1. 直接对类使用 new 命令,跟构造函数的用法完全一致;
  2. 类的所有方法都定义在类的 prototype 属性上面

3. class 中的 constructor() 方法

3.1 基础说明

  • constructor() 方法是类的默认方法,通过 new 命令生成对象实例时,自动调用该方法。

自动调用constructor

  • 一个类必须有 constructor() 方法,如果没有显式定义,一个空的constructor()方法会被默认添加。

  • constructor()方法默认返回实例对象(即this)。除了默认对象,也可以指定返回另外一个对象。

constructor返回非默认对象

3.2 个人理解

简单来说,constructor 对标 ES5 中的构造函数。我们可以在 constructor ,定义 new 输出的实例对象。classconstructor 必须要有,不写会默认添加。

如下图:

基础的类实现方式 es5-class

4. class 中定义的属性和方法

4.1 实例属性

由上文得知,我们定义实例对象上的属性,需要在 constructor 定义。ES2022为类的实例属性,又规定了一种新写法。

如下:

写法一

// 原来的写法
class Demo {
  constructor() {
    this._count = 0;
  }
 
  add() {
    this._count++;
  }
}

var d = new Demo()
console.log(d) // { _count: 0 }

写法二

// 新的写法
class Demo {
  _count = 0 // _count会绑定在实例对象上

  add() {
    this._count++
  }
}

var d = new Demo()
console.log(d) // { _count: 0 }

这样写,好处非常明显,定义实例对象的属性的时候,可以更加简洁明了。

ps: Cocos Creator3.x 中定义实例属性,就是使用的 写法二 ,更加简洁明了。

注意事项

  • 实例属性顾名思义,定义的属性是实例对象自身的属性,而不是定义在实例对象的原型上面。(参考上方的示例代码。实例属性对应:d上的属性,而不是 Demo.prototype上的属性)

4.2 class中定义的方法

和实例属性不同,class 中直接定义的函数,是定义在实例对象的原型对象上,如下图示例。

在这里插入图片描述

为什么属性和方法有这样的不同?为什么要这么做?

  1. js 中当我们试图访问一个对象的属性时,如果该对象本身没有这个属性,那么 js 会在对象的原型对象上查找这个属性,依次类推,直到找到属性或者达到原型链的顶端。

    这样就保证了我们的函数定义在实例对象的原型上,实例对象是可以访问,调用的。

  2. 所有的实例都可以共享同一个方法,而不是每个实例都存储一份方法的副本。这种做法可以节省内存。

  3. 将方法放在原型上,我们还可以实现方法的继承和重写。子类可以通过在其原型上添加或重写父类的方法来实现继承或重写。

注意事项

  • class 中直接定义的函数,实际上是定义在实例对象的原型对象上

5. 取值函数(getter)和存值函数(setter)

“类”的内部可以使用getset关键字,对某个属性设置存值函数取值函数拦截该属性的存取行为。

5.1 如何定义?

class MyClass {
  constructor() {
    // ...
  }
  get prop() {
    return 'getter';
  }
  set prop(value) {
    console.log('setter: '+value);
  }
}

let inst = new MyClass();

inst.prop = 123;
// setter: 123

inst.prop
// 'getter'

// prop是一个属性,通过 `get`和`set`关键字,拦截 prop 的存取。
// 能拦截属性的存取,就可以根据我们自身的需求去增加逻辑

7. 静态方法和静态属性 static

函数其实本身也是一个对象,而class定义的类,其实也是一个对象。这个对象本身,是可以存储属性的。这些属性我们就叫它静态方法和静态属性

class 中,为了方便定义一个静态属性,我们可以在属性前,增加关键词 static 用以表示。

ES5 中定义静态方法

function Point(x, y) {}

Point.like = 'lazyTomato'

Point.say = function () {
  console.log('我是say方法')
}

ES6 中 class 旧版的定义静态方法

class Point {}
Point.like = 'lazyTomato'
Point.say = function () {
  console.log('我是say方法')
}

ES6 中 class 使用static关键词定义静态方法

class Point {
  static like = 'lazyTomato'
  static say() {
    console.log('我是say方法')
  }
}

注意事项:

  1. static 定义的就是静态属性和静态方法;
  2. 因为静态属性和静态方法,直接定义在 class 上的属性和方法,所以可以不用实例化直接调用。

8. 私有属性和私有方法

有时候,我们定义在类上的属性或者方法,仅供类内部使用,不希望被实例对象调用。

这个时候就出现了希望能私有这些属性和方法的方式。

私有,可以理解为就是仅供内部使用。

8.1 早期的实现方式:

class Point {
  _conut:1
  _say() {
    console.log('不希望被实例对象调用的方法')
  }
}

// 通过给属性或者方法增加 `_` (下划线),表示这个属性或者方法是私有的。
// 但是这个方式并不是百分百保险的,外部还是可以调用。

8.2 利用 Symbol 值的唯一性:

const bar = Symbol('bar');
const snaf = Symbol('snaf');

export default class myClass{

  // 公有方法
  foo(baz) {
    this[bar](baz);
  }

  // 私有方法
  [bar](baz) {
    return this[snaf] = baz;
  }

  // ...
};

但是使用 Reflect.ownKeys() 依然可获取到这些属性。

const inst = new myClass();

Reflect.ownKeys(myClass.prototype)
// [ 'constructor', 'foo', Symbol(bar) ]

8.3 使用 ES6中的

class Foo {
  #a;
  #b;
  constructor(a, b) {
    this.#a = a;
    this.#b = b;
  }
  #sum() {
    return this.#a + this.#b;
  }
  printSum() {
    console.log(this.#sum());
  }
}

9.总结

9.1 总结一下 class 中的一些属性:

名称定义在哪里示例
实例属性实例对象在这里插入图片描述
class中定义的函数定义在实例对象的原型对象上在这里插入图片描述
get和set函数实例对象在这里插入图片描述
静态方法和静态属性类自身在这里插入图片描述
私有属性和私有方法类内部在这里插入图片描述

9.2 不同的属性在谷歌浏览器中的展示效果

1.实例属性,红色高亮

在这里插入图片描述

2.class中定义的函数:红色偏灰

在这里插入图片描述

3.get和set方法:红色更加灰

在这里插入图片描述

4.静态属性和静态方法

在这里插入图片描述

5.私有属性和私有方法

在这里插入图片描述

9.3 为什么 class 中有些属性可以直接通过 this 调用

示例代码一

class Point {
  num = 1
  say() {
    console.log('我是say方法')
  }

  test() {
    console.log(this.num) // 问题1
    console.log(this.say()) // 问题2
  }
}

把上面的代码换一种写法

示例代码二

class Point {
  constructor() {
    this.num = 1
  }
  say() {
    console.log('我是say方法')
  }

  test() {
    console.log(this.num) // 问题1
    console.log(this.say()) // 问题2
  }
}
var p = new Point()
p.test()
问题1: 为什么可以调用 this.num ?

因为谁调用函数,函数this就指向谁,执行 p.test()this 指向 pp 本身有一个 num 属性,所以可以正常调用。

问题2: 为什么可以调用 this.say()?

执行 p.test()this 指向 pp 本身没有 say 方法,但是它原型链上存在,所以可以正常调用。

end

  • 目前就class的基础内容就介绍到这里了。
  • 后续再补充 子类,继承 等内容。

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

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

相关文章

Pytest中测试结果收集:pytest_terminal_summary!

前言 Pytest是Python的一种强大的测试框架,它提供了丰富的功能和插件来满足各种测试需求。 其中,pytest_terminal_summary是一个钩子函数,它允许我们在测试运行结束后,添加自定义的总结信息到测试报告中。这个功能在需要对测试结…

Java 小项目开发日记 04(文章接口的开发、oss图片上传)

Java 小项目开发日记 04&#xff08;文章接口的开发、oss图片上传&#xff09; 项目目录 配置文件&#xff08;pom.xml&#xff09; <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:sc…

HMAC算法

HMAC HMAC可以用来加密、数字签名、报文验证等。 1. 消息认证码 消息认证码&#xff08;Message Authentication Code&#xff0c;MAC&#xff09;是基于消息和秘钥的公开函数&#xff0c;输出为定长数据&#xff1a; MACC(M,K) 假定通信双发共享秘钥K&#xff0c;发送方A向接…

ubuntu22.04 成功编译llvm和clang 3.4.0,及 bitcode 函数名示例,备忘

1, 获取llvm 仓库 从github上获取&#xff1a; $ git clone --recursive https://github.com/llvm/llvm-project.git 2, 检出 llvmorg-3.4.0 tag 针对llvm 3.4.0版本&#xff0c;检出 $ cd llvm-project $ git tag $ git checkout llvmorg-3.4.0 3, 配置并编译llvm 使用 M…

ARK:《BIG IDEAS 2024》

Cathie Wood所带领的方舟投资&#xff08;ARK&#xff09;发布了年度重磅研究报告《BIG IDEAS 2024》&#xff0c;该报告指出人工智能、公共区块链、多组学测序、能源存储和机器人技术这五大板块的融合将带来全球经济活动的改变。 这五个创新平台正在融合并定义这个技术时代&am…

GoFrame:如何简单地搭建一个简单地微服务

一切资料来源于GoFrame官网&#xff0c; 感兴趣的&#xff0c; 可以直接去官网查阅相关资料。 首先下载框架工具&#xff0c; 下载地址&#xff1a;https://github.com/gogf/gf/releases 然后进入你想要放置的项目文件夹&#xff0c; 执行命令行 gf init {project_name} #pr…

插混、油混、增程式、轻混、强混,啥区别

这里写自定义目录标题 随着我国新能源汽车的大力推进&#xff0c;电车可以说是世界未来的主流&#xff0c;只不过现在是处在一个过渡时代 这是个好时代&#xff0c;因为我们见证并体验着历史过渡的细节 这是个不好的时代&#xff0c;因为我们可能只是未来新新人类的试验品 帮他…

微信小程序iOS禁止上下拉显示白边

先上图暴露出问题 iOS端这个页面明明正好显示的&#xff0c;非要能下拉上拉给显示出来点白边。这样不就不好看了嘛。。 想了想是不是支持页面下拉导致的&#xff0c;加入以下代码到json文件中。 {"enablePullDownRefresh": false,"usingComponents": {} }…

【k8s资源调度--DaemonSet】

1、什么是守护进程 有以下这样一个商品场景&#xff1a; 1、用户在商城查询商品信息&#xff0c;查询商品信息的时候需要登录用户&#xff0c;如果用户想要下单&#xff0c;需要提交到订单服务&#xff0c;最后下单完成后&#xff0c;需要更新仓库的商品数量信息。 2、如果每一…

mysql和redis双写一致性策略分析

mysql和redis双写一致性策略分析 一.什么是双写一致性 当我们更新了mysql中的数据后也可以同时保证redis中的数据同步更新&#xff1b; 数据读取的流程&#xff1a; 1.读取redis,如果value!null,直接返回&#xff1b; 2.如果redis中valuenull&#xff0c;读取mysql中数据对应的…

P2040 打开所有的灯

题目传送门&#xff1a;P2040 打开所有的灯 用深度优先搜索实现的一个填色题。 题目步骤&#xff1a; 1..dfs 首先dfs要判断是否符合题意&#xff0c;如果符合题意就更新最短路&#xff1b; 如果不符合题意就枚举 如果是关的就把周围四个包括 给标记上和原来相反的&#xf…

AI大预言模型——ChatGPT与AI绘图及论文高效写作

原文链接&#xff1a;AI大预言模型——ChatGPT与AI绘图及论文高效写作 2023年随着OpenAI开发者大会的召开&#xff0c;最重磅更新当属GPTs&#xff0c;多模态API&#xff0c;未来自定义专属的GPT。微软创始人比尔盖茨称ChatGPT的出现有着重大历史意义&#xff0c;不亚于互联网…

python语言1

一、pytho中的注释 1.1注释的理解 程序员在代码中对代码功能解释说明的标注性文字可以提高代码的可读性注释的内容将被python解释器忽略&#xff0c;不被计算机执行 1.2注释的分类 注释分为&#xff1a;单行注释、多行注释、中文声明注释 &#xff08;1&#xff09;单行注…

计算机网络-网络互连和互联网(五)

1.路由器技术NAT&#xff1a; 网络地址翻译&#xff0c;解决IP短缺&#xff0c;路由器内部和外部地址进行转换。静态地址转换&#xff1a;静态NAT&#xff08;一对一&#xff09; 静态NAT&#xff0c;内外一对一转换&#xff0c;用于web服务器&#xff0c;ftp服务器等固定IP的…

大模型的智慧之源:图技术的崛起

自2023年以来&#xff0c;大语言模型&#xff08;Large Language Models&#xff0c;LLMs&#xff09;的兴起已经改变了科技行业的面貌。 科创公司如果不涉足这一领域&#xff0c;似乎就不好意思称自己是科技企业。 然而&#xff0c;随着大语言模型的普及&#xff0c;它固有的…

Linux高级编程:进程(三),线程(一)

进程的一生&#xff1a; execute&#xff1a; exec族 用fork创建子进程后执行的是和父进程相同的程序&#xff08;但有可能执行不同的代码分支&#xff09;&#xff0c; 子进程往往要调用一种exec函数以执行另一个程序。当进程调用一种exec函数时&#xff0c;该进程的 用户空间…

Python复合型数据避坑指南

目录 前言 列表&#xff08;Lists&#xff09; 1. 修改可变对象 2. 浅拷贝和深拷贝 元组&#xff08;Tuples&#xff09; 集合&#xff08;Sets&#xff09; 字典&#xff08;Dictionaries&#xff09; 1. 键值唯一性 2. 键的类型 实际应用场景 1. 数据分析与清洗 2. 网络…

微信小程序云开发教程——墨刀原型工具入门(安装以及基础使用教程)

引言 作为一个小白&#xff0c;小北要怎么在短时间内快速学会微信小程序原型设计&#xff1f; “时间紧&#xff0c;任务重”&#xff0c;这意味着学习时必须把握微信小程序原型设计中的重点、难点&#xff0c;而非面面俱到。 要在短时间内理解、掌握一个工具的使用&#xf…

Hgame题解(第二星期)

Hgame题解&#xff08;第二星期&#xff09; Web Select More Courses 打开靶机发现是一个登陆页面&#xff0c;根据题目提示下载弱密码字典&#xff0c;通过BP爆破获得用户密码为qwert123 登陆后进入下一个页面&#xff0c;由于学分已满无法选课&#xff0c;所以需要先进行…

仿牛客网项目---显示评论和添加评论功能的实现

这篇文章&#xff0c;我来介绍一下我的项目中的另外一个功能&#xff1a;显示评论和添加评论。 其实这两个功能都不怎么重要&#xff0c;我感觉最重要的应该是用户注册登录功能&#xff0c;这个也了解一下&#xff0c;知道这么一回事儿就好。 首先设计DAO层。 Mapper public …