JavaScriptでのメソッド連鎖

あなたはJavaScriptを書いていて、突然あなたが巨大な関数を書いたことを恐怖と恐怖で認識しています。 それは私たちの最高に起こった。 今より小さい部分の機能を分けるほとんど止められない衝動は来る。

大きな関数は、一つの場所で多くの責任を意味し、おそらくコードの匂いもするので、それ自体は良い考えです。 しかし、あなたはその意味や文脈を失わないように関数を分割したいと思っています。 これを行うには、関数連鎖とも呼ばれるメソッド連鎖を考える必要があります。 この記事では、私がそれによって何を意味するのかを説明します。

前提条件

始める前に、すでに慣れ親しんでおく必要があるJavaScriptの概念をいくつか紹介します:

  • Arrow関数
  • 配列メソッド
  • 非同期関数

ほとんどの経験豊富な開発者は、map、reduce、filterなどのArrayメソッドの経験があります。 あなたはおそらくすでにこのようなものに遭遇しました:

const food = ;// This type of usage is very commonfood .map(item => item.type) .reduce((result, fruit) => { result.push(fruit); return ; }, );// result: 

メソッドの連鎖は、同じオブジェクトとその参照を使用して複数の関数を呼び出す場合に発生します。 上記の例では、配列メソッドmapは、膨大な数のメソッドを持つArrayを返します。

Arrayを指す参照を返すため、Arrayのすべてのプロパティにアクセスできます。 それはあなたがあなた自身の方法連鎖のために使うのと同じ原則です。

これをよりよく理解する

私はthisのすべてのニュアンスをカバーするわけではありませんが、なぜthisが機能するのかを理解するのは良いことです。 どんなにあなたが経験しても、これは理解するのは難しいことができますキーワード。 それはしばしば物事があなたがそれらを期待するようにうまくいかない理由です。

ここにその要点があります:thisは常に現在のscopeまたはそれが呼び出されたインスタンスを指します。 例を挙げてみましょう:

const dog = { is: null, log: () => console.log(this.is), bark() { this.is = "woofing"; this.log(); return this; }, walk() { this.is = "walking"; this.log(); return this; }, eat() { this.is = "eating"; this.log(); return this; }};dog .bark() .eat() .walk();

このような関数を書くとき(しゃれは意図していません)、オブジェクトに関連するメソッドを連鎖させたい場合があります。 オブジェクトdogには、walkbarkeatの3つのメソッドがあります。 私がその関数のいずれかを呼び出すたびに、コンソールはその正確な瞬間に犬が何をしているかの表現を表示する必要があります。

しかし、それには問題があります。 ブラウザで実行すると、期待どおりに動作しないことがわかります。 これは、矢印関数が字句スコープを使用しているためです。thisはその周囲のスコープを参照します-この場合はwindowであり、オブジェクト自体ではありません。

これを解決するには、logプロパティを表す無名関数呼び出しを使用する必要があります:

// instead of this: log: () => console.log(this.is),// use this: log() { console.log(this.is); }

これで、犬のthisスコープは関数内でアクセスできるようになります。

クラスを使用して

あなたはクラスを使用して同じ結果を達成することができます:

class Dog { is = null; log() { console.log(this.is); } bark() { this.is = "woofing"; this.log(); return this; } walk() { this.is = "walking"; this.log(); return this; } eat() { this.is = "eating"; this.log(); return this; }}const dog = new Dog();dog .bark() .eat() .walk();

Prototype

を使用するprototypeを使用する必要がある場合は、次のようにします:

function Dog() {}Dog.prototype.is = null;Dog.prototype.log = function() { console.log(this.is);};Dog.prototype.bark = function() { this.is = "woofing"; this.log(); return this;};Dog.prototype.walk = function() { this.is = "walking"; this.log(); return this;};Dog.prototype.eat = function() { this.is = "eating"; this.log(); return this;};const dog = new Dog();dog .bark() .eat() .walk();

非同期関数はどうですか?

async あなたがasync関数を宣言するとき、あなたはそれが約束を返すことを知っています。 そのため、promiseのすべてのメソッドにアクセスすることもできます。

const requests = { user: null, action: null, log(something) { console.log(this); }, async getUser() { this.user = await new Promise(resolve => { setTimeout(() => { resolve("Douglas Pires"); }, 1000); }); this.log("user"); return this; }, async registerAction() { this.action = await new Promise(resolve => { setTimeout(() => { resolve("programming stuff"); }, 1000); }); this.log("action"); return this; }};requests.getUser().then(() => requests.registerAction());

しかし、約束の束を一緒に連鎖させることは良い考えではありません。 私は代わりにawaitキーワードの束を使用することをお勧めします。 それはより簡単で、あなたのコードをはるかに読みやすくします。

await requests.getUser(); // Douglas Piresawait requests.registerAction(); // programming

そして、あなたはここで同じプロパティへのアクセス権を持っています:

console.log(requests.user); // Douglas Piresconsole.log(requests.action); // programming

結論として、

連鎖関数は、オブジェクトを操作する必要があるときに便利です。 また、コードの可読性を向上させる実用的な方法でもあります。 しかし、あなたが上で見てきたように、あなたは賢明に連鎖する必要があります。

この記事では、JavaScriptメソッドチェーンのコンテキストでthis、クラス、プロトタイプ、およびasync関数について説明しました。 私はあなたがいくつかの有用なヒントを拾ってきたし、今より良いトピックについて知らされている願っています。 JavaScriptメソッドのすべてのコードをここに連鎖させた私のリポジトリを見つけることができます。 次の投稿でお会いしましょう!

以下のボタンを使用してソーシャルメディア上で共有すること自由に感じます。 また、NuxtとVuetifyを使用してカラーパレットジェネレータを構築する方法についても書いています。 それをチェックアウトしてください!

コメントを残す

メールアドレスが公開されることはありません。