선택적으로 String.replace() 연결

삼항과 약간의 정규식 마술을 사용하여 String.replace() 문에 인라인 논리를 추가할 수 있습니다. 다음은 named function parameters pattern을 사용하는 약간 인위적인 예입니다.

const presentableUrl = (fullUrl, { removeProtocol = true, removeWww = false } = {}) =>
  fullUrl
    .replace(/(https?:\/\/)/i, removeProtocol ? '' : '$1')
    .replace(/(www\.)/i, removeWww ? '' : '$1')

어떻게



무슨 일이야?
String.replace()에는 두 가지 중요한 속성이 있습니다. 새 문자열을 반환하므로 호출을 연결할 수 있습니다. 검색 패턴에서 하위 문자열을 임의의 matched group으로 바꿀 수 있습니다. 이것은 '$1' 와 같은 특수 문자열로 수행됩니다. 여기서 $ 뒤의 숫자는 1부터 세는 그룹의 인덱스를 나타냅니다. 이는 전체 패턴을 그룹화하여(즉, 둥근 괄호로 묶음) 다음을 수행할 수 있음을 의미합니다. 그런 다음 전체 일치를 '$1' 로 참조하십시오.

그런 다음 원래 일치를 a ternary statement 의 거짓 표현으로 사용합니다. 즉, 조건이 false 로 평가되면 동일한 문자열을 반환하여 특정 replace 을 효과적으로 단락시킵니다.

그래서 라인

fullUrl.replace(/(https?:\/\/)/i, removeProtocol ? '' : '$1')

의사 코드로 다음과 같이 번역될 수 있습니다.

replace _match_ with
    if removeProtocal is true
        ''
    else
        _match_ /* replace it with itself */




일련의 문자열 변환을 수행하는 함수를 작성하는 것은 매우 일반적입니다. 대부분의 경우 우리는 함수가 pure이 되기를 원합니다. a string가 들어가고, a string가 나옵니다. 그게 전부입니다. 단순한. 원 라이너. 화살표 기능.

그러나 상대적으로 일반적인 기능을 원한다면 때때로 선택적 변환을 허용해야 합니다. 그렇다면 함수의 논리에서 해당 조건을 어디에 삽입해야 할까요? if 문에 넣을 수 있습니다. 이전 예는 다음과 같습니다.

function presentableUrl (fullUrl, { removeProtocol = true, removeWww = false } = {}) {
  let url = fullUrl

  if (removeProtocol) {
    url = url.replace(/https?:\/\//i, '')
  }

  if (removeWww) {
      url = url.replace(/www\./i, '')
  }

  return url
}

약간 징그럽지 않나요? 이제 추적할 내부 변수가 있으며 앞으로 추가할 조건은 또 다른 if 명령문과 3줄의 코드를 가져옵니다. 오래 걸릴거야. 또한 이 함수를 보면 string in, string out만 수행한다는 사실이 명확하지 않습니다. 누군가(예: 미래의 우리) 실수로 순수하지 않은 기능을 추가할 수 있으며 즉시 명확하지 않습니다. .

이것이 바로 arrow functions 및 삼항이 우리가 해결하는 데 도움이 되는 종류의 문제입니다.

언제



나는 이 패턴에 Elegant Footgun™이라는 태그를 달았고 도전적으로 자신의 발에 총을 쏘는 것을 쉽게 만듭니다.

"아름답다", "우아하다"및 "가독성이 좋다"와 같은 최상급 코드는 매우 개인적일 수 있으며 많은 요인에 따라 달라집니다. 개인적으로 나는 이 패턴이 단순 논리의 우아하고 읽기 쉬운 표현이라고 생각합니다("아름다운"은 그것을 밀어붙일 것입니다).

나는 또한 내 코드를 쳐다보며 내 자신의 영리함을 다시 이해하려고 애쓰는 나를 발견할 날을 위해 감정적으로 준비되어 있습니다. 그 날이 오면 내가 이 글을 쓸 수 있기를 바랍니다.

좋은 웹페이지 즐겨찾기