ホームページ ウェブフロントエンド jsチュートリアル JS+TypeScript でクラスを使用する方法

JS+TypeScript でクラスを使用する方法

Jun 06, 2018 pm 02:55 PM
class typescript

今回は、JS+TypeScript でクラスを使用する方法と、JS+TypeScript でクラスを使用する際の注意点について説明します。以下は実際のケースです。

はじめに

フロントエンド開発者にとって、クラスはほとんど使用されません。JavaScript はむしろ関数型プログラミングであり、クラスや新規の痕跡はほとんどありません。したがって、デザイン パターンは、ほとんどのフロントエンド開発者の欠点でもあります。

最近、Angular を学習する過程で、Angular が本当に深く研究する価値のある優れたフレームワークであることに気づきました。

この記事では、JavaScript と TypeScript のクラスについて簡単に紹介します。

基本概念

クラスを紹介する前に、最初にいくつかの基本概念を紹介する必要があります。

1. 静的メンバー

クラス自体のメンバーは継承できますが、インスタンスにはアクセスできません。jQuery 時代の最も一般的な $.ajax などの静的メソッドです。使い方は簡単で、new または関数呼び出しを通じて新しいインスタンスを取得する必要はありません。

2. プライベート メンバー

クラス内のメンバーは通常、継承できず、内部でのみ使用できます。これらはクロージャ内の変数に似ていますが、現時点では JavaScript では直接アクセスできません。プライベート メンバーは他の手段でのみ実装できます。

3. Getter/setter

Accessor プロパティ。インスタンスのプロパティにアクセスまたは変更する場合、Vue はデータの変更を追跡するためにこれらの 2 つの操作を実行します。 。

4. インスタンス メンバー

は、new によって作成されたインスタンスのメンバーを指します。この機能により、コードの再利用も可能になります。

5. 抽象クラス、抽象メソッド

抽象クラスはインスタンス化できないクラスを指し、通常は親クラスとして設計されています。

抽象メソッドはメソッドの名前、パラメータ、戻り値を提供するだけであり、特定の実装はサブクラスによって完了されます。サブクラスが抽象クラスを継承する場合、サブクラスはすべての抽象メソッドを実装する必要があります。そうでない場合は、エラーが報告されます。

これらの概念は両方とも JavaScript で直接実装することはできませんが、TypeScript または他のオブジェクト指向言語では簡単に実装できます。また、この機能はポリモーフィズムを実現するための重要な手段でもあります。

ケース紹介

クラスをよりよく紹介するために、この記事では 3 つのクラス、つまり パーソン、中国人、アメリカ人を例として使用します。単語からすぐにわかります。人は親クラス (基本クラス)、中国人とアメリカ人はサブクラス (派生クラス) です。

person には、名前、年齢、性別、sayHello メソッド、および fullName アクセサー属性の 3 つの属性があります。同時に、Person にはいくつかの静的メンバーとプライベート メンバーもあります。例を考えるのは非常に難しいので、代わりに foo、bar、x、y、z を使用します。

中国人とアメリカ人は、サブクラスとして、Person のインスタンス メンバーと静的メンバーを継承します。同時に、彼らは独自のメソッドと属性もいくつか持っています:

中国人はカンフーの属性を持っており、武道を練習することができます。

アメリカ人はツイッターを持っており、ツイッターを送信することもできます。

次に、JavaScript と TypeScript を使用してこのケースを実装します。

JavaScript のクラス

JavaScript のクラス 2 つのキーワード、class と extends は ES6 で提供されていますが、これらは単なる構文糖ですが、最下位層は継承を実装するために引き続きプロトタイプを使用します。確かに、この書き方によりコードがより明確になり、読みやすくなります。

ES6のクラス

class Person {
 // #x = '私有属性x';
 // static x = '静态属性x';
 // name;
 // age;
 // gender;
 // 上面的写法还在提案中,并没有成为正式标准,不过变化的可能性已经不大了。
 // 顺便吐槽一下,用 # 表示私有成员,真的是很无语.
 /**
  * Person的静态方法,可以被子类继承
  * 可以通过 this 访问静态成员
  */
 static foo() {
  console.log(`类 ${this.name} 有一个 ${this.x}`);
 }
 constructor(name, age, gender) {
  this.name = name;
  this.age = age;
  this.gender = gender;
 }
 /**
  * 数据存储器,可以访问实例成员,子类的实例可以继承
  * 以通过 this 访问实例成员
  */
 get fullName() {
  const suffix = this.gender === '男' ? '先生' : '女士';
  return this.name + suffix;
 }
 set fullName(value) {
  console.log(`你已改名为 ${value} `);
 }
 /**
  * Person的实例方法,可以被子类的实例继承
  * 可以通过 this 访问实例成员
  */
 sayHello() {
  console.log(`你好我是 ${this.fullName} ,我 ${this.age} 岁了`);
 }
}
Person.x = '静态属性x';
ログイン後にコピー
class Chinese extends Person {
 static bar() {
  console.log(`类 ${this.name} 的父类是 ${super.name}`);
  super.foo();
 }
 constructor(name, age, gender, kungfu) {
  super(name, age, gender);
  this.kungfu = kungfu;
 }
 martial() {
  console.log(`${this.name} 正在修炼 ${this.kungfu} `);
 }
}
ログイン後にコピー
rree
class American extends Person {
 // static y = '静态属性y';
 static bar() {
  console.log(`类 ${this.name} 有自己的 ${this.y} ,还继承了父类 ${super.name} 的 ${super.x}`);
 }
 constructor(name, age, gender, twitter) {
  super(name, age, gender);
  this.twitter = twitter;
 }
 sendTwitter(msg) {
  console.log(`${this.name} : `);
  console.log(` ${msg}`);
 }
}
ログイン後にコピー

ES6

ES5以前のクラスの継承は、本質的には、まずサブクラスのインスタンスオブジェクトを作成し

、それからParentの上に親クラスのメソッドを追加するというものです。 (これを)適用してください。

ES6 の継承メカニズムはまったく異なります。本質は、最初に親クラスのインスタンス オブジェクトを作成することです。そのため、最初にスーパー メソッドを呼び出してから、サブクラスのコンストラクターを使用してこれを変更する必要があります。

为了实现继承,我们需要先实现一个 extendsClass 函数,它的作用是让子类继承父类的静态成员和实例成员。

function extendsClass(parent, child) {
 // 防止子类和父类相同名称的成员被父类覆盖
 var flag = false;
 // 继承静态成员
 for (var k in parent) {
  flag = k in child;
  if (!flag) {
   child[k] = parent[k];
  }
 }
 // 继承父类prototype上的成员
 // 用一个新的构造函数切断父类和子类之间的数据共享
 var F = function () { }
 F.prototype = parent.prototype;
 var o = new F();
 for (var k in o) {
  flag = k in child.prototype;
  if (!flag) {
   child.prototype[k] = o[k];
  }
 }
}
ログイン後にコピー
function Person(name, age, gender) {
 this.name = name;
 this.age = age;
 this.gender = this.gender;
 // 如果将 getter/setter 写在 prototype 会获取不到
 Object.defineProperty(this, 'fullName', {
  get: function () {
   var suffix = this.gender === '男' ? '先生' : '女士';
   return this.name + suffix;
  },
  set: function () {
   console.log('你已改名为 ' + value + ' ');
  },
 });
}
Person.x = '静态属性x';
Person.foo = function () {
 console.log('类 ' + this.name + ' 有一个 ' + this.x);
}
Person.prototype = {
 constructor: Person,
 // get fullName() { },
 // set fullName(value) { },
 sayHello: function () {
  console.log('你好我是 ' + this.fullName + ' ,我 ' + this.age + ' 了');
 },
};
ログイン後にコピー
function Chinese(name, age, gender, kungfu) {
 // 用call改变this指向,实现继承父类的实例属性
 Person.call(this, name, age, gender);
 this.kungfu = kungfu;
}
Chinese.bar = function () {
 console.log('类 ' + this.name + ' 的父类是 ' + Person.name);
 Person.foo();
}
Chinese.prototype = {
 constructor: Chinese,
 martial: function () {
  console.log(this.name + ' 正在修炼 ' + this.kungfu + ' ');
 }
};
extendsClass(Person, Chinese);
ログイン後にコピー
function American(name, age, gender, twitter) {
 Person.call(this, name, age, gender);
 this.twitter = twitter;
}
American.y = '静态属性y';
American.bar = function () {
 console.log('类 ' + this.name + ' 有自己的 ' + this.y + ' ,还继承了父类 ' + Person.name + ' 的 ' + Person.x);
}
American.prototype = {
 constructor: American,
 sendTwitter: function (msg) {
  console.log(this.name + ' : ');
  console.log(' ' + msg);
 }
};
extendsClass(Person, American);
ログイン後にコピー

TypeScript 中的 class

讲完了 JavaScript 中的类,还是没有用到 抽象类,抽象方法,私有方法这三个概念,由于 JavaScript 语言的局限性,想要实现这三种概念是很困难的,但是在 TypeScript 可以轻松的实现这一特性。

首先我们稍微修改一下例子中的描述,Person 是抽象类,因为一个正常的人肯定是有国籍的,Person 的 sayHello 方法是抽象方法,因为每个国家打招呼的方式不一样。另外一个人的性别是只能读取,不能修改的,且是确定的是,不是男生就是女生,所以还要借助一下枚举。

enum Gender {
 female = 0,
 male = 1
};
ログイン後にコピー
abstract class Person {
 private x: string = '私有属性x,子类和实例都无法访问';
 protected y: string = '私有属性y,子类可以访问,实例无法访问';
 name: string;
 public age: number;
 public readonly gender: Gender; // 用关键字 readonly 表明这是一个只读属性
 public static x: string = '静态属性x';
 public static foo() {
  console.log(`类 ${this.name} 有一个 ${this.x}`);
 }
 constructor(name: string, age: number, gender: Gender) {
  this.name = name;
  this.age = age;
  this.gender = gender;
 }
 get fullName(): string {
  const suffix = this.gender === 1 ? '先生' : '女士';
  return this.name + suffix;
 }
 set FullName(value: string) {
  console.log(`你已改名为 ${value} `);
 }
 // 抽象方法,具体实现交由子类完成
 abstract sayHello(): void;
}
ログイン後にコピー
class Chinese extends Person {
 public kungfu: string;
 public static bar() {
  console.log(`类 ${this.name} 的父类是 ${super.name}`);
  super.foo();
 }
 public constructor(name: string, age: number, gender: Gender, kungfu: string) {
  super(name, age, gender);
  this.kungfu = kungfu;
 }
 public sayHello(): void {
  console.log(`你好我是 ${this.fullName} ,我 ${this.age} 岁了`);
 }
 public martial() {
  console.log(`${this.name} 正在修炼 ${this.kungfu} `);
 }
}
ログイン後にコピー
class American extends Person {
 static y = '静态属性y';
 public static bar() {
  console.log(`类 ${this.name} 有自己的 ${this.y} ,还继承了父类 ${super.name} 的 ${super.x}`);
 }
 public twitter: string;
 public constructor(name: string, age: number, gender: Gender, twitter: string) {
  super(name, age, gender);
  this.twitter = twitter;
 }
 public sayHello(): void {
  console.log(`Hello, I am ${this.fullName} , I'm ${this.age} years old`);
 }
 public sendTwitter(msg: string): void {
  console.log(`${this.name} : `);
  console.log(` ${msg}`);
 }
}
ログイン後にコピー
Person.x;  // 静态属性x
Person.foo(); // 类 Person 有一个 静态属性x
Chinese.x;  // 静态属性x
Chinese.foo(); // 类 Chinese 有一个 静态属性x
Chinese.bar(); // 类 Chinese 的父类是 Person
American.x;  // 静态属性x
American.y;  // '静态属性y
American.foo(); // 类 American 有一个 静态属性x
American.bar(); // 类 American 有自己的 静态属性y ,还继承了父类 Person 的 静态属性x
const c: Chinese = new Chinese('韩梅梅', 18, Gender.female, '咏春拳');
const a: American = new American('特朗普', 72, Gender.male, 'Donald J. Trump');
c.sayHello(); // 你好我是 韩梅梅女士 ,我 18 岁了
c.martial(); // 韩梅梅 正在修炼 咏春拳 
a.sayHello(); // Hello, I am 特朗普先生 , I'm 72 years old
a.sendTwitter('推特治国'); // 特朗普 : 推特治国
ログイン後にコピー

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

从零开始使用vue-devtools

vue计算属性与侦听器实战项目详解

以上がJS+TypeScript でクラスを使用する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Python でクラスとメソッドを使用する方法 Python でクラスとメソッドを使用する方法 Apr 21, 2023 pm 02:28 PM

クラスとメソッドの概念とインスタンス クラス (Class): 同じプロパティとメソッドを持つオブジェクトのコレクションを記述するために使用されます。コレクション内のすべてのオブジェクトに共通のプロパティとメソッドを定義します。オブジェクトはクラスのインスタンスです。メソッド: クラスで定義された関数。クラス構築メソッド __init__(): クラスには init() という名前の特別なメソッド (構築メソッド) があり、クラスがインスタンス化されるときに自動的に呼び出されます。インスタンス変数: クラスの宣言において、属性を変数で表現したものをインスタンス変数と呼びます。インスタンス変数とは、self で修飾された変数です。インスタンス化: クラスのインスタンス、クラスの特定のオブジェクトを作成します。継承: つまり、派生クラス (派生クラス) は基本クラス (ベースクラス) を継承します。

5 つの一般的な JavaScript メモリ エラー 5 つの一般的な JavaScript メモリ エラー Aug 25, 2022 am 10:27 AM

JavaScript はメモリ管理操作を提供しません。代わりに、メモリは、ガベージ コレクションと呼ばれるメモリ再利用プロセスを通じて JavaScript VM によって管理されます。

Vue3+TypeScript+Vite は画像などの静的リソースを動的に導入するためにどのように使用しますか? Vue3+TypeScript+Vite は画像などの静的リソースを動的に導入するためにどのように使用しますか? May 16, 2023 pm 08:40 PM

質問: Vue3+TypeScript+Vite プロジェクトに画像などの静的リソースを動的に導入するために require を使用する方法!説明: 現在プロジェクトを開発する場合(プロジェクトフレームワークはVue3+TypeScript+Vite)、静的リソースを動的に導入する、つまりimgタグのsrc属性値を動的に取得する必要があります。次のコード: Write コードをアップロードした後、波線エラーが報告され、エラー メッセージ: 名前 "require" が見つかりません。ノードのタイプ定義をインストールする必要がありますか? npmi --save-dev@types/node を試してください。 npmi--save-d 実行後の ts(2580)

MySQLを使用してTypeScriptにデータ型変換機能を実装する方法 MySQLを使用してTypeScriptにデータ型変換機能を実装する方法 Jul 29, 2023 pm 02:17 PM

MySQL を使用して TypeScript にデータ型変換関数を実装する方法 はじめに: データ型変換は、Web アプリケーションを開発するときに非常に一般的な要件です。データベースに格納されているデータを処理するとき、特に MySQL をバックエンド データベースとして使用するとき、多くの場合、クエリ結果のデータを必要な型に変換する必要があります。この記事では、MySQL を使用して TypeScript でデータ型変換を実装する方法を紹介し、コード例を示します。 1.準備:始める

Pythonにおけるクラスとは何を意味するのでしょうか? Pythonにおけるクラスとは何を意味するのでしょうか? May 21, 2019 pm 05:10 PM

クラスとはPythonでクラスを定義するためのキーワードです クラスの定義方法:classの後ろにスペースを入れてからクラス名を追加します; クラス名のルール:最初の文字を大文字にします 複数の単語がある場合はキャメルケースを使用してください[class Dog()] などの名前付け。

Redis と TypeScript を使用してハイパフォーマンス コンピューティング関数を開発する方法 Redis と TypeScript を使用してハイパフォーマンス コンピューティング関数を開発する方法 Sep 20, 2023 am 11:21 AM

Redis と TypeScript を使用してハイ パフォーマンス コンピューティング機能を開発する方法の概要: Redis は、高いパフォーマンスとスケーラビリティを備えたオープン ソースのインメモリ データ構造ストレージ システムです。 TypeScript は、型システムとより優れた開発ツールのサポートを提供する JavaScript のスーパーセットです。 Redis と TypeScript を組み合わせることで、大規模なデータ セットを処理し、Redis のメモリ ストレージとコンピューティング機能を最大限に活用するための効率的なコンピューティング関数を開発できます。この記事ではその方法を説明します

jQueryを使用して要素のクラス名を置換する jQueryを使用して要素のクラス名を置換する Feb 24, 2024 pm 11:03 PM

jQuery は、Web 開発で広く使用されている古典的な JavaScript ライブラリで、イベントの処理、DOM 要素の操作、Web ページ上でのアニメーションの実行などの操作を簡素化します。 jQueryを使っていると要素のクラス名を置き換える場面がよくありますが、この記事ではその実践的な方法と具体的なコード例を紹介します。 1.removeClass() メソッドと addClass() メソッドを使用する jQuery には、削除用の RemoveClass() メソッドが用意されています。

PHP クラスの使用法の詳細な説明: コードをより明確で読みやすくします。 PHP クラスの使用法の詳細な説明: コードをより明確で読みやすくします。 Mar 10, 2024 pm 12:03 PM

PHP コードを記述するとき、クラスを使用するのは非常に一般的な方法です。クラスを使用すると、関連する関数とデータを 1 つのユニットにカプセル化できるため、コードがより明確になり、読みやすく、保守しやすくなります。この記事では、PHPClass の使用法を詳しく紹介し、クラスを適用して実際のプロジェクトでコードを最適化する方法を読者がよりよく理解できるように、具体的なコード例を示します。 1. クラスの作成と使用 PHP では、キーワード class を使用してクラスを定義し、クラス内のプロパティとメソッドを定義できます。

See all articles