javascript中的class基礎入門(1)

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 = xthis.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: 123inst.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 = 1say() {console.log('我是say方法')}test() {console.log(this.num) // 問題1console.log(this.say()) // 問題2}
}

把上面的代碼換一種寫法

示例代碼二

class Point {constructor() {this.num = 1}say() {console.log('我是say方法')}test() {console.log(this.num) // 問題1console.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.pswp.cn/news/712199.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/712199.shtml
英文地址,請注明出處:http://en.pswp.cn/news/712199.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【Sql server】假設有三個字段a,b,c 以a和b分組,如何查詢a和b唯一,但是c不同的記錄

歡迎來到《小5講堂》,大家好,我是全棧小5。 這是《Sql Server》系列文章,每篇文章將以博主理解的角度展開講解, 特別是針對知識點的概念進行敘說,大部分文章將會對這些概念進行實際例子驗證,以此達到加深對…

2_SQL

文章目錄 SQL數據完整性實體完整性域完整性參照完整性default(默認值)comment(注釋) 多表設計一對一一對多多對多數據庫三大范式第一范式:原子性第二范式:唯一性第三范式:數據的冗余 多表查詢連…

JQMobile Loader Widget 遮罩層改造

最近在用jqmobile 做一個混合APP項目時候用到 jqmobile1.4.3提供的Loader Widget控件,但是這個控件本身是一個loading彈出層,這個彈出層彈出之后,用戶還是可以去點擊按鈕,重復發送請求,為了防止重復提交,我想了兩種辦法, 1,在loading彈出層彈出之后,讓按鈕不可用.但是form表單…

記錄SSM項目集成Spring Security 4.X版本 之 加密驗證和記住我功能

目錄 前言 一、用戶登錄密碼加密認證 二、記住我功能 前言 本次筆記的記錄是接SSM項目集成Spring Security 4.X版本 之 加入DWZ,J-UI框架實現登錄和主頁菜單顯示-CSDN博客https://blog.csdn.net/u011529483/article/details/136255768?spm1001.2014.3001.5502 文章之后補…

Python列表的合并、重復、判斷與切片操作你學會了嗎

1.合并列表 通過 實現 list1 ["佛跳墻", "腸粉", "刀削面", "烤鴨"]list2 [32, 4, 5, 7.43, True]list3 list1 list2print(list3) # [佛跳墻, 腸粉, 刀削面, 烤鴨, 32, 4, 5, 7.43, True] 2.重復輸出列表中的元素 通過 * 實…

fastadmin 前端日期字段的添加和編輯

引言 fastadmin 項目中如果需要用到datetime字段的維護&#xff0c;可做如下處理&#xff1a; 1. add.html <div class"form-group"><label class"control-label col-xs-12 col-sm-2">{:__(開始)}:</label><div class"col-x…

vue3 中 主題定制

vue3 中 主題定制 背景 做多主題定制&#xff0c;黑/白 &#xff0c;里面還要再分各種顏色&#xff0c;每次進來都要記住上次的主題設置 效果圖 一、目錄結構 ├── generated │ ├── theme │ │ └── dark-yellow.ts │ │ └── dark-orange.ts │ │…

C++考試成績統計(類實現)

題目&#xff1a;有三名同學&#xff0c;在一次考試中三科成績分別如下表&#xff0c;請輸出三名同學的平均成績&#xff1a; 語文數學英語張三100100100李四9050100王五607080 #include <iostream> #include <string> /*考試成績統計*/ using namespace std;cla…

力扣:120. 三角形最小路徑和

動態規劃 1.先定義dp數組在下標i和下標j時的最小路徑和 &#xff0c;之后初始化dp數組值dp【0】【0】triangle.get(0).get(0)。再用for循環來遍歷數組dp【】的i&#xff0c;并賦值每行的下標為0的dp數組。之后再用for循環遍歷dp【i】【】的j&#xff0c;遞推公式來計算dp【i】…

「算法」常見位運算總結

位運算符 異或 按位異或可以實現無進位相加&#xff0c;所謂無進位相加&#xff0c;就是在不考慮進位的情況下將兩個數相加&#xff08;后面有道題需要用到這種操作&#xff09; 異或的運算律 ①a ^ 0 a ②a ^ a 0 ③a ^ b ^ c a ^ ( b ^ c ) 有符號右移>> 將一個…

IDEA切換 Springboot初始化 URL

&#x1f339;作者主頁&#xff1a;青花鎖 &#x1f339;簡介&#xff1a;Java領域優質創作者&#x1f3c6;、Java微服務架構公號作者&#x1f604; &#x1f339;簡歷模板、學習資料、面試題庫、技術互助 &#x1f339;文末獲取聯系方式 &#x1f4dd; 往期熱門專欄回顧 專欄…

Android基礎控件介紹

在Android應用程序開發中&#xff0c;使用基礎控件是非常常見的。這些控件允許您在用戶界面中顯示文本、圖像、按鈕等元素&#xff0c;以及接收用戶輸入。本文將介紹幾種常見的基礎控件&#xff0c;并給出每個控件在示例XML中使用的屬性的詳細說明。 1. TextView TextView 是…

云計算 2月20號 (認識操作系統)

1、認識操作系統 計算機系統的組成 知識點1&#xff1a;沒有軟件系統的計算機稱之為"裸機" 知識點2&#xff1a;裸機提供基本的可計算性資源 知識點3&#xff1a;操作系統是最靠近硬件的軟件層&#xff0c;負責管理和控制計算機硬件。 計算機硬件組成五大部件 運算器…

Chat GPT:智能對話的下一步

Chat GPT&#xff1a;智能對話的下一步 介紹 Chat GPT&#xff08;Generative Pre-trained Transformer&#xff09;是一種基于Transformer架構的強大對話模型&#xff0c;可以產生自然流暢的回答&#xff0c;并實現人機對話的感覺。本文將探討Chat GPT在智能對話領域的影響和…

代碼隨想錄算法刷題訓練營day29:LeetCode(491)遞增子序列、LeetCode(46)全排列、LeetCode(47)全排列 II

代碼隨想錄算法刷題訓練營day29&#xff1a;LeetCode(491)遞增子序列、LeetCode(46)全排列、LeetCode(47)全排列 II LeetCode(491)遞增子序列 題目 代碼 import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; im…

2024年AI全景預測

歡迎來到 2024 年人工智能和技術的可能性之旅。 在這里&#xff0c;每一個預測都是一個潛在的窗口&#xff0c;通向充滿創新、變革、更重要的是類似于 1950 年代工業革命的未來。 20 世紀 50 年代見證了數字計算的興起&#xff0c;重塑了行業和社會規范。 如今&#xff0c;人工…

老衛帶你學---leetcode刷題(242. 有效的字母異位詞)

242. 有效的字母異位詞 問題 給定兩個字符串 s 和 t &#xff0c;編寫一個函數來判斷 t 是否是 s 的字母異位詞。 注意&#xff1a;若 s 和 t 中每個字符出現的次數都相同&#xff0c;則稱 s 和 t 互為字母異位詞。 示例 1: 輸入: s “anagram”, t “nagaram” 輸出: t…

力扣1143. 最長公共子序列(動態規劃)

Problem: 1143. 最長公共子序列 文章目錄 題目描述思路復雜度Code 題目描述 思路 我們統一標記&#xff1a;str1[i]代表text1表示的字符數組&#xff0c;str2[j]代表text2表示的字符數組&#xff1b;LCS代表最長的公共子序列&#xff1b;&#xff08;我們易得只有str1[i]和str…

Flutter中Widget的生命周期

Widget生命周期&#xff1a; createState-initState-didChangeDependency-build-deactive-dispose 可通過WidgetsBinding類對widget生命周期的回調進行監控。 createState&#xff1a;StatefulWidget 中用于創建 State&#xff1b; initState&#xff1a;State 的初始化操作&am…

CLion遠程調試C++

文件映射到 可以右鍵文件夾選擇重新Cmake 編譯