この記事では、es7 の Decorator について詳しく説明します (例を示します)。必要な方は参考にしていただければ幸いです。
1. Decorator の基礎知識
多くのフレームワークやライブラリ、特に React、Redux、mobx で見られます。
Decorator は、クラスの動作を変更するために使用される関数です。この抽象的な概念はよく理解できないので、コードを見てより実践的に説明することをお勧めします。
//定义一个函数,也就是定义一个Decorator,target参数就是传进来的Class。 //这里是为类添加了一个静态属性 function addAge(target) { target.age = 2; } //在Decorator后面跟着Class,Decorator是函数的话,怎么不是addAge(MyGeekjcProject)这样写呢? //我只能这样理解:因为语法就这样,只要Decorator后面是Class,默认就已经把Class当成参数隐形传进Decorator了(就是所谓的语法糖)。 @addAge class MyGeekjcProject {} console.log(MyGeekjcProject.age) // 2
1.1 パラメータを渡してクラスを変更する
しかし、上記のメソッドが 1 つのクラスのみをパラメータとして渡し、十分な柔軟性がない場合はどうすればよいでしょうか。
最終結果が Decorator である限り、外側の層に関数を設定できます。設定する関数の数や渡すパラメーターの数は関係ありません。
function addAge(age) { return function(target) { target.age = age; } } //注意这里,隐形传入了Class,语法类似于addAge(2)(MyGeekjcProject) @testable(2) class MyGeekjcProject {} MyGeekjcProject.age // 2 @addAge(3) class MyGeekjcProject {} MyGeekjcProject.age // 3
1.2 クラスの属性を変更する
以下は変更されたクラスのプロトタイプ オブジェクトです
function description(target) { target.prototype.url = 'https://www.geekjc.com'; } @description class MyGeekjcProject {} let geekjc = new MyGeekjcProject(); geekjc.url // https://www.geekjc.com
修飾子はクラスを変更できるという概念は大まかに理解できます。
//假如修饰类的属性则传入三个参数,对应Object.defineProperty()里三个参数,具体不细说 //target为目标对象,对应为Class的实例 //name为所要修饰的属性名,这里就是修饰器紧跟其后的name属性 //descriptor为该属性的描述对象 //这里的Decorator作用是使name属性不可写,并返回修改后的descriptor function readonly(target, name, descriptor){ descriptor.writable = false; return descriptor; } class Person { @readonly name() { return `${this.first} ${this.last}` } }
Object.defineProperty() については、記事を読んで Object.defineProperty を学習してください。
もう一度複雑な例を見てみましょう。
//定义一个Class并在其add上使用了修饰器 class Math { @log add(a, b) { return a + b; } } //定义一个修饰器 function log(target, name, descriptor) { //这里是缓存旧的方法,也就是上面那个add()原始方法 var oldValue = descriptor.value; //这里修改了方法,使其作用变成一个打印函数 //最后依旧返回旧的方法,真是巧妙 descriptor.value = function() { console.log(`Calling "${name}" with`, arguments); return oldValue.apply(null, arguments); }; return descriptor; } const math = new Math(); math.add(2, 4);上記のコードを読むと、デコレータが何に使用されるかがわかります。はい、修飾子はクラスの動作を変更するだけでなく、クラスの属性も変更できます。
2. React の高次コンポーネント
より一般的には、高次コンポーネントは、React コンポーネントをラップ (ラップ) することによって渡され、一連の最後に、他のコンポーネントを呼び出すために比較的強化された React コンポーネントが返されます。3. 上位コンポーネントを実装する
React コンポーネントを受け取り、それをラップして を返す、最も単純な上位コンポーネント (関数) を実装しましょう。export default function withDescription(WrappedComponent) { return class HOC extends Component { render() { return <div> <div> 极客教程(https://www.geekjc.com)致力于推广各种编程语言技术,也为了未来数字化世界,让人更容易找到操作数字化的方式,为了未来而生的编程学习平台, 大部分资源是完全免费的,并且会根据当前互联网的变化实时更新本站内容。 </div> <wrappedcomponent></wrappedcomponent> </div> } } }他のコンポーネントでは、この上位コンポーネントを参照して強化します。
@withDescription export default class Geekjc extends Component { render() { return ( <div> 我是一个普通组件 </div> ); } }ここでは、書き方の優雅さを向上させるために ES7 のデコレータを使用しています (最初のセクションのデコレータを参照) が、実際には単なる構文上の糖衣です。次のような書き方も可能です。
const EnhanceDemo = withDescription(Geekjc);次に、React コンポーネント ツリーでどのような変更が行われたかを観察します。図に示すように、Geekjc コンポーネントが HOC コンポーネントによってラップされていることがわかります。これは、高い期待と一致しています。 -order コンポーネント。つまり、コンポーネントはタマネギのようにレイヤーごとにラップされます。
HOC が大量にあるため、この時点で少し最適化を行う必要があります。つまり、上位コンポーネントがラップされた後、元の名前を保持する必要があります。
getDisplayName 関数と静的属性
displayName を追加して、
DOM Tree を観察します。
function getDisplayName(component) { return component.displayName || component.name || 'Component'; } export default function (WrappedComponent) { return class HOC extends Component { static displayName = `HOC(${getDisplayName(WrappedComponent)})` render() { return <div> <div> 极客教程(https://www.geekjc.com)致力于推广各种编程语言技术,也为了未来数字化世界,让人更容易找到操作数字化的方式,为了未来而生的编程学习平台, 大部分资源是完全免费的,并且会根据当前互联网的变化实时更新本站内容。 </div> <wrappedcomponent></wrappedcomponent> </div> } } }
タイトル スタイル を追加するという 1 つのことだけを行います。この上位コンポーネントは、このロジックを追加する必要がある任意のコンポーネントで使用でき、この上位コンポーネントによってのみ変更する必要があります。
上位コンポーネントの主な機能は、コンポーネントの共通ロジックをカプセル化して抽象化し、ロジックのこの部分をコンポーネント間でより適切に再利用できるようにすることであることがわかります。4. 上位コンポーネントの高度な使用法
4.1 コンポーネントのパラメーター上記の例を例に挙げますが、この上位コンポーネントは情報のみを表示します。 Web サイトの説明についてですが、より適切に抽象化するには、この説明をパラメータ化して次のように呼び出す必要があります。
@withDescription('欢迎大家访问收藏(https://www.geekjc.com)') export default class Geekjc extends Component { render() { return ( //... ); } }withDescription は、パラメータを受け取り、上位のコンポーネント (関数) を返す次の形式に書き換える必要があります。
export default function (description) { return function (WrappedComponent) { return class HOC extends Component { render() { return <div> <div> {description ?description : '我是描述'} </div> <wrappedcomponent></wrappedcomponent> </div> } } } }ES6 を使用すると、より簡潔に記述できます。
export default(description) => (WrappedComponent) => class HOC extends Component { render() { return <div> <div> {description ? description : '我是描述'} </div> <wrappedcomponent></wrappedcomponent> </div> } }図からわかるように、渡されたパラメータが DOM ツリーに反映されています。
コンセプト: 関数のパラメータの一部だけを渡して呼び出し、残りのパラメータを処理する関数を返します。
関数シグネチャ: fun(params)(otherParams)
アプリケーション: React では、カリー化を通じて、さまざまなパラメーターを渡すことでさまざまな高次コンポーネントを取得できます。
export default function withHeader(WrappedComponent) { return class HOC extends Component { render() { const newProps = { test:'hoc' } // 透传props,并且传递新的newProps return <p> <wrappedcomponent></wrappedcomponent> </p> } } }4.3 逆継承に基づくこの方法で返された React コンポーネントは、渡されたコンポーネントを継承するため、属性よりも多くの領域と権限にアクセスできます。組織化と変更。詳細については、付録にあるリンクを参照して詳しく学習してください。
export default function (WrappedComponent) { return class Inheritance extends WrappedComponent { componentDidMount() { // 可以方便地得到state,做一些更深入的修改。 console.log(this.state); } render() { return super.render(); } } }
4.4 组合多个高阶组件
上述高阶组件为React组件增强了一个功能,如果需要同时增加多个功能需要怎么做?这种场景非常常见,例如我既需要增加一个组件标题,又需要在此组件未加载完成时显示Loading。
@withDescription @withLoading class Demo extends Component{ }
使用compose可以简化上述过程,也能体现函数式编程的思想。
const enhance = compose(withHeader,withLoading); @enhance class Demo extends Component{ }组合 Compose
compose可以帮助我们组合任意个(包括0个)高阶函数,例如compose(a,b,c)返回一个新的函数d,函数d依然接受一个函数作为入参,只不过在内部会依次调用c,b,a,从表现层对使用者保持透明。
基于这个特性,我们便可以非常便捷地为某个组件增强或减弱其特征,只需要去变更compose函数里的参数个数便可。
compose函数实现方式有很多种,这里推荐其中一个recompact.compose,详情见下方参考类库,也可以看我之前写的一篇文章reduce与redux中compose函数
5. 与父组件区别
高阶组件作为一个函数,它可以更加纯粹地关注业务逻辑层面的代码,比如数据处理,数据校验,发送请求等,可以改善目前代码里业务逻辑和UI逻辑混杂在一起的现状。父组件则是UI层的东西,我们先前经常把一些业务逻辑处理放在父组件里,这样会造成父组件混乱的情况。为了代码进一步解耦,可以考虑使用高阶组件这种模式。
6. 开源的高阶组件使用
6.1 recompact
recompact提供了一系列使用的高阶组件,可以增强组件的行为,可以利用此库学习高阶组件的写法。
import recompact from 'recompact' import { pure, withProps } from 'recompact' const enhance = recompact.compose( withProps({ className: 'beautiful' }), pure, ) @enhance class Demo extends Component{ }
6.2 React Sortable
通过使用此库提供的高阶组件,可以方便地让列表元素可拖动。
以上がes7のデコレータを詳しく解説(例付き)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

CおよびJavaScriptは、WebAssemblyを介して相互運用性を実現します。 1)CコードはWebAssemblyモジュールにコンパイルされ、JavaScript環境に導入され、コンピューティングパワーが強化されます。 2)ゲーム開発では、Cは物理エンジンとグラフィックスレンダリングを処理し、JavaScriptはゲームロジックとユーザーインターフェイスを担当します。

JavaScriptは、Webサイト、モバイルアプリケーション、デスクトップアプリケーション、サーバー側のプログラミングで広く使用されています。 1)Webサイト開発では、JavaScriptはHTMLおよびCSSと一緒にDOMを運用して、JQueryやReactなどのフレームワークをサポートします。 2)ReactNativeおよびIonicを通じて、JavaScriptはクロスプラットフォームモバイルアプリケーションを開発するために使用されます。 3)電子フレームワークにより、JavaScriptはデスクトップアプリケーションを構築できます。 4)node.jsを使用すると、JavaScriptがサーバー側で実行され、高い並行リクエストをサポートします。

Pythonはデータサイエンスと自動化により適していますが、JavaScriptはフロントエンドとフルスタックの開発により適しています。 1. Pythonは、データ処理とモデリングのためにNumpyやPandasなどのライブラリを使用して、データサイエンスと機械学習でうまく機能します。 2。Pythonは、自動化とスクリプトにおいて簡潔で効率的です。 3. JavaScriptはフロントエンド開発に不可欠であり、動的なWebページと単一ページアプリケーションの構築に使用されます。 4. JavaScriptは、node.jsを通じてバックエンド開発において役割を果たし、フルスタック開発をサポートします。

CとCは、主に通訳者とJITコンパイラを実装するために使用されるJavaScriptエンジンで重要な役割を果たします。 1)cは、JavaScriptソースコードを解析し、抽象的な構文ツリーを生成するために使用されます。 2)Cは、Bytecodeの生成と実行を担当します。 3)Cは、JITコンパイラを実装し、実行時にホットスポットコードを最適化およびコンパイルし、JavaScriptの実行効率を大幅に改善します。

現実世界でのJavaScriptのアプリケーションには、フロントエンドとバックエンドの開発が含まれます。 1)DOM操作とイベント処理を含むTODOリストアプリケーションを構築して、フロントエンドアプリケーションを表示します。 2)node.jsを介してRestfulapiを構築し、バックエンドアプリケーションをデモンストレーションします。

Web開発におけるJavaScriptの主な用途には、クライアントの相互作用、フォーム検証、非同期通信が含まれます。 1)DOM操作による動的なコンテンツの更新とユーザーインタラクション。 2)ユーザーエクスペリエンスを改善するためにデータを提出する前に、クライアントの検証が実行されます。 3)サーバーとのリフレッシュレス通信は、AJAXテクノロジーを通じて達成されます。

JavaScriptエンジンが内部的にどのように機能するかを理解することは、開発者にとってより効率的なコードの作成とパフォーマンスのボトルネックと最適化戦略の理解に役立つためです。 1)エンジンのワークフローには、3つの段階が含まれます。解析、コンパイル、実行。 2)実行プロセス中、エンジンはインラインキャッシュや非表示クラスなどの動的最適化を実行します。 3)ベストプラクティスには、グローバル変数の避け、ループの最適化、constとletsの使用、閉鎖の過度の使用の回避が含まれます。

Pythonは、スムーズな学習曲線と簡潔な構文を備えた初心者により適しています。 JavaScriptは、急な学習曲線と柔軟な構文を備えたフロントエンド開発に適しています。 1。Python構文は直感的で、データサイエンスやバックエンド開発に適しています。 2。JavaScriptは柔軟で、フロントエンドおよびサーバー側のプログラミングで広く使用されています。


ホットAIツール

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

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

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

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

人気の記事

ホットツール

ZendStudio 13.5.1 Mac
強力な PHP 統合開発環境

SAP NetWeaver Server Adapter for Eclipse
Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。

DVWA
Damn Vulnerable Web App (DVWA) は、非常に脆弱な PHP/MySQL Web アプリケーションです。その主な目的は、セキュリティ専門家が法的環境でスキルとツールをテストするのに役立ち、Web 開発者が Web アプリケーションを保護するプロセスをより深く理解できるようにし、教師/生徒が教室環境で Web アプリケーションを教え/学習できるようにすることです。安全。 DVWA の目標は、シンプルでわかりやすいインターフェイスを通じて、さまざまな難易度で最も一般的な Web 脆弱性のいくつかを実践することです。このソフトウェアは、

VSCode Windows 64 ビットのダウンロード
Microsoft によって発売された無料で強力な IDE エディター

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