>  기사  >  웹 프론트엔드  >  함수에서 형제 매개변수를 기본값으로 사용할 수 있다는 것을 몰랐습니다.

함수에서 형제 매개변수를 기본값으로 사용할 수 있다는 것을 몰랐습니다.

Linda Hamilton
Linda Hamilton원래의
2024-10-13 06:24:30305검색

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으로 문의하세요.