JavaScript / endsWith()로 문자열의 끝부분 검사하기
String.endsWith(searchString)는 문자열이 지정한 글자로 끝나는지 검사해 true 또는 false를 반환합니다. 대소문자를 구분하며, 두 번째 인수 endPosition을 주면 문자열 앞쪽의 해당 위치까지를 검사 대상으로 삼습니다.
기본 끝 문자열 검사
찾는 문자열은 끝 부분과 정확히 같아야 합니다. 인덱스를 직접 계산할 필요가 없고, 검사해도 원본 문자열이 바뀌지 않습니다. 공백과 대소문자도 비교에 포함되므로 입력을 정리하고 비교할지는 요구사항에 따라 결정하세요.
console.log('report.pdf'.endsWith('.pdf')); // true
console.log('report.PDF'.endsWith('.pdf')); // false
console.log('report.pdf '.endsWith('.pdf')); // false
console.log('abc'.endsWith('')); // true
빈 문자열은 어느 문자열의 끝에도 맞는 것으로 처리되어 true가 됩니다. 사용자가 반드시 끝 글자를 입력해야 한다면 호출 전에 빈 입력을 검사하세요. 정규식을 검색 인수로 넣으면 TypeError가 발생합니다. MDN의 String.endsWith() 문서에 이 반환 규칙이 나와 있습니다.
endPosition은 끝 글자의 인덱스가 아닌 경계
text.endsWith(searchString, endPosition)은 원본 문자열을 앞에서 endPosition만큼 잘라서 끝을 검사하는 것처럼 생각할 수 있습니다. 위치는 마지막 글자의 인덱스가 아니라 그 다음 경계입니다. "abzcdz"에서 위치 3까지는 "abz"이므로 끝 글자 z가 맞습니다.
const text = 'abzcdz';
console.log(text.endsWith('z')); // true: 전체 끝
console.log(text.endsWith('z', 2)); // false: 'ab'의 끝
console.log(text.endsWith('z', 3)); // true: 'abz'의 끝
console.log(text.slice(0, 3)); // 'abz'
인수를 생략하면 전체 문자열 길이를 경계로 씁니다. 이 값은 인덱스가 아니라 문자열의 UTF-16 위치를 기준으로 하므로, 이모지 등을 포함한 문자열에서 사람이 보는 글자 수와 다를 수 있습니다. 선택 인수가 필요 없는 일반적인 끝 검사에는 생략하는 편이 읽기 쉽습니다.
파일명과 URL에 적용할 때
파일명 문자열에 endsWith(".pdf")를 사용하면 확장자처럼 보이는 끝 부분을 검사할 수 있습니다. 하지만 파일의 실제 형식을 검증하거나 안전한 파일인지 판정하는 기능은 아닙니다. 사용자 입력을 검증하는 서버에서는 파일 내용과 정책을 별도로 확인해야 합니다.
console.log('report.pdf'.endsWith('.pdf')); // true
console.log('report.pdf?download=1'.endsWith('.pdf')); // false
const url = new URL('https://example.com/report.pdf?download=1');
console.log(url.pathname.endsWith('.pdf')); // true
URL 전체에는 검색 매개변수나 해시가 붙을 수 있습니다. 주소의 경로 끝을 확인하려는 목적이라면 new URL(address).pathname처럼 대상 부분을 분리해 검사하세요. 대소문자를 무시해야 할 때는 양쪽 문자열의 대소문자를 동일하게 바꾸되, 파일 시스템이나 서비스가 실제로 대소문자를 구분하는지도 함께 고려해야 합니다.
전체 예제: 검사 경계 바꾸기
아래 코드를 UTF-8로 string-ends-with.html에 저장해 브라우저에서 엽니다. 끝 문자열과 끝 위치 사용 여부를 바꾸면 실제 검사 대상이 된 앞부분과 결과가 표시됩니다. 입력값이 없을 때의 동작도 확인할 수 있습니다.
<!doctype html>
<html lang="ko">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>문자열 끝 검사</title>
</head>
<body>
<label for="text">원본 문자열</label>
<input id="text" type="text" value="abzcdz">
<label for="suffix">끝 문자열</label>
<input id="suffix" type="text" value="z">
<label><input id="use-end" type="checkbox"> 끝 위치 사용</label>
<label for="end">끝 위치</label>
<input id="end" type="number" min="0" step="1" value="3" disabled>
<pre id="output" aria-live="polite"></pre>
<script>
const text = document.querySelector('#text');
const suffix = document.querySelector('#suffix');
const useEnd = document.querySelector('#use-end');
const end = document.querySelector('#end');
const output = document.querySelector('#output');
function show() {
const value = text.value;
const target = suffix.value;
const position = Number(end.value);
if (useEnd.checked && (end.value.trim() === '' ||
!Number.isInteger(position) || position < 0)) {
output.textContent = '끝 위치에는 0 이상의 정수를 입력하세요.';
return;
}
end.disabled = !useEnd.checked;
const checked = useEnd.checked ? value.slice(0, position) : value;
const result = useEnd.checked
? value.endsWith(target, position) : value.endsWith(target);
output.textContent = `검사 대상: ${JSON.stringify(checked)}\n` +
`찾는 끝 문자열: ${JSON.stringify(target)}\n` +
`endsWith() 결과: ${result}`;
}
text.addEventListener('input', show);
suffix.addEventListener('input', show);
useEnd.addEventListener('change', show);
end.addEventListener('input', show);
show();
</script>
</body>
</html>
기본 문자열 abzcdz와 끝 문자열 z의 결과는 true입니다. 끝 위치 사용을 켜고 3을 입력해도 검사 대상 abz가 z로 끝나므로 true입니다. 2로 바꾸면 검사 대상은 ab이고 false입니다. 끝 문자열을 비우면 결과는 true가 됩니다.




