首頁 >web前端 >js教程 >我不知道您可以使用同級參數作為函數中的預設值。

我不知道您可以使用同級參數作為函數中的預設值。

Linda Hamilton
Linda Hamilton原創
2024-10-13 06:24:30350瀏覽

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中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn