兄弟パラメータを関数のデフォルト値として使用できるとは知りませんでした。

Linda Hamilton
リリース: 2024-10-13 06:24:30
オリジナル
305 人が閲覧しました

I didn

JavaScript は ES2015 以降、デフォルトのパラメーター値をサポートしています。あなたはこれを知っています。私はこれを知っています。私が知らなかったのは、兄弟 パラメータ をデフォルト値自体として使用できるということです。 (あるいは、「隣接する位置パラメーター」かもしれません。これらを何と呼ぶべきかわかりません。)

function myFunc(arg1, arg2 = arg1) {
  console.log(arg1, arg2);
}

myFunc("arg1!");
// "arg1!" "arg1!"
ログイン後にコピー

これはクラス コンストラクターでも機能します。これは、一部の PicPerf.io コードをよりテストしやすくするのに非常に役立つことがわかりました。この目的のために単純な依存性注入が使用されるのが一般的です。少し詳しく見てみましょう。

シナリオ

画像の最適化のテーマに沿って、OptimizedImage クラスがあるとします。画像の URL をコンストラクターに指定すると、画像の新しく最適化されたバッファーまたはキャッシュされたバージョンのいずれかを取得できます。

class OptimizedImage {
  constructor(
    imageUrl: string,
    cacheService = new CacheService(),
    optimizeService = new OptimizeService()
  ) {
    this.imageUrl = imageUrl;
    this.cacheService = cacheService;
    this.optimizeService = optimizeService;
  }

  async get() {
    const cached = this.cacheService.get(this.imageUrl);

    // Return the previously optimized image.
    if (cached) return cached;

    const optimizedImage = await this.optimizeService
      .optimize(this.imageUrl);

    // Cache the optimized image for next time.
    return this.cacheService.put(this.imageUrl, optimizedImage);
  }
}

const instance = new OptimizedImage('https://macarthur.me/me.jpg');
const imgBuffer = await instance.get();
ログイン後にコピー

運用環境で使用される唯一のコンストラクター パラメーターは imageUrl ですが、CacheService と OptimizeService を挿入すると、モックを使用した単体テストが簡単になります。

import { it, expect, vi } from 'vitest';
import { OptimizedImage } from './main';

it('returns freshly optimized image', async function () {
  const fakeImageBuffer = new ArrayBuffer('image!');
  const mockCacheService = {
    get: (url) => null,
    put: vi.fn().mockResolvedValue(fakeImageBuffer),
  };

  const mockOptimizeService = {
    optimize: (url) => fakeImageBuffer,
  };

  const optimizedImage = new OptimizedImage(
    'https://test.jpg',
    mockCacheService,
    mockOptimizeService
  );

  const result = await optimizedImage.get();

  expect(result).toEqual(fakeImageBuffer);
  expect(mockCacheService.put).toHaveBeenCalledWith(
    'https://test.jpg',
    'optimized image'
  );
});
ログイン後にコピー

より複雑にする

この例では、これらのサービス クラスは両方とも、特定のメソッドが呼び出された場合にのみ imageUrl を使用します。しかし、代わりにそれを独自のコンストラクターに渡す必要がある場合を想像してください。インスタンス化を OptimizedImage のコンストラクターに取り込みたくなるかもしれません (私はそうでした):

class OptimizedImage {
  constructor(
    imageUrl: string
  ) {
    this.imageUrl = imageUrl;
    this.cacheService = new CacheService(imageUrl);
    this.optimizeService = new OptimizeService(imageUrl);
  }
ログイン後にコピー

それはうまくいきますが、OptimizedImage がサービスのインスタンス化を完全に担当するようになり、テストもさらに面倒になります。サービス インスタンスのモックを渡すのはそれほど簡単ではありません。

モック クラス定義を渡すことでこれを回避できますが、その場合、独自のコンストラクターを使用してそれらのクラスのモック バージョンを作成する必要があり、テストがさらに面倒になります。幸いなことに、引数リストの残りの部分で imageUrl パラメータを使用するという別のオプションがあります。

兄弟パラメータの共有

少し前まで、これが可能であることさえ知りませんでした。それは次のようになります:

export class OptimizedImage {
  constructor(
    imageUrl: string,
    // Use the same `imageUrl` in both dependencies.
    cacheService = new CacheService(imageUrl),
    optimizeService = new OptimizeService(imageUrl)
  ) {
    this.cacheService = cacheService;
    this.optimizeService = optimizeService;
  }

  async get() {
    const cached = this.cacheService.get();

    // Return the previously optimized image.
    if (cached) return cached;

    const optimizedImage = await this.optimizeService.optimize();

    // Cache the optimized image for next time.
    return this.cacheService.put(optimizedImage);
  }
}
ログイン後にコピー

この設定を使用すると、以前と同じように簡単にこれらのインスタンスをモックすることができ、クラスの残りの部分は imageUrl 自体のインスタンスを保持する必要さえありません。もちろん、インスタンス化は依然として単純です:

const instance = new OptimizedImage('https://macarthur.me/me.jpg');

const img = await instance.get();
ログイン後にコピー

同じテストアプローチもそのまま残ります:

import { it, expect, vi } from 'vitest';
import { OptimizedImage } from './main';

it('returns freshly optimized image', async function () {
  const mockCacheService = {
    get: () => null,
    put: vi.fn().mockResolvedValue('optimized image'),
  };

  const mockOptimizeService = {
    optimize: () => 'optimized image',
  };

  const optimizedImage = new OptimizedImage(
    'https://test.jpg',
    mockCacheService,
    mockOptimizeService
  );

  const result = await optimizedImage.get();

  expect(result).toEqual('optimized image');
  expect(mockCacheService.put).toHaveBeenCalledWith('optimized image');
});
ログイン後にコピー

ここには画期的なことは何もありません。私の生活を人間工学的にもう少し快適にしてくれる小さな機能だけです。今後もこのような逸品に出会えることを期待しています。

以上が兄弟パラメータを関数のデフォルト値として使用できるとは知りませんでした。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!