JavaScript中indexOf()方法完整指南:从基础到实战

学习如何使用JavaScript中的indexOf()方法,包含语法详解
这是一篇面向初学者的深度解析,涵盖JavaScript强大的indexOf()方法——从字符串到数组,以及真实世界的应用示例。
🔍 JavaScript中的indexOf()是什么?
indexOf()方法用于查找字符串或数组中特定元素的位置(索引)。如果未找到,则返回-1。
🧪 语法
对于字符串:
  1. string.indexOf(searchValue, startIndex)
javascript
对于数组:
  1. array.indexOf(searchElement, fromIndex)
javascript
📘 在字符串中使用indexOf()
  1. const text = "JavaScript is amazing";
  2. console.log(text.indexOf("Script")); // 4
javascript
大小写敏感性
  1. console.log(text.indexOf("script")); // -1
javascript
🔁 查找第一次出现
  1. const sentence = "I love JavaScript because JavaScript is fun!";
  2. console.log(sentence.indexOf("JavaScript")); // 7
javascript
🕵️‍♂️ 查找所有出现位置
  1. const str = "JS is cool. JS is powerful. JS is everywhere!";
  2. let index = str.indexOf("JS");
  3. while (index !== -1) {
  4. console.log("Found at:", index);
  5. index = str.indexOf("JS", index + 1);
  6. }
javascript
🧾 在数组中使用indexOf()
  1. const fruits = ["apple", "banana", "cherry", "apple"];
  2. console.log(fruits.indexOf("apple")); // 0
  3. console.log(fruits.indexOf("cherry")); // 2
javascript
  1. const numbers = [1, 5, 10, 15];
  2. console.log(numbers.indexOf(10)); // 2
  3. console.log(numbers.indexOf(20)); // -1
javascript
🎯 检查元素是否存在
  1. if (fruits.indexOf("banana") !== -1) {
  2. console.log("Banana is in the list!");
  3. }
javascript
🧠 indexOf() vs includes()
特性
indexOf()
includes()
返回值
索引或-1
true / false
使用场景
查找位置
检查存在性
性能提示
  1. // 更简单的检查
  2. arr.includes("item");

  3. // 更灵活
  4. arr.indexOf("item") !== -1
javascript
📌 真实世界应用案例
  1. const input = "Learn JavaScript the fun way!";
  2. const term = "JavaScript";

  3. if (input.indexOf(term) !== -1) {
  4. console.log(`The term "${term}" exists in the sentence.`);
  5. }
javascript
常见面试题
Q: 如何在不使用正则表达式的情况下检查字符串是否包含某个单词?
A: 使用.indexOf()并将结果与-1进行比较。
🧩 练习挑战
编写一个函数,查找句子中是否存在单词"React"并返回其位置。
  1. function findReact(sentence) {
  2. return sentence.indexOf("React");
  3. }

  4. console.log(findReact("I love React and JavaScript")); // 7
javascript
总结
适用于字符串和数组
找到时返回索引,未找到时返回-1
区分大小写
仅检查存在性时使用includes()
🧠 常见问题
Q: indexOf()能在数组中查找对象吗?
A: 不能,只能查找字符串、数字等原始值。
Q: 如果存在多个匹配项怎么办?
A: 只返回第一个索引。
Q: indexOf()会修改数组或字符串吗?
A: 不会,它是非变异的。
🔥 想要更多内容?
阅读完整博客(包含图片和格式):
深入理解indexOf()方法
1. 基础用法详解
字符串搜索
  1. // 基本搜索
  2. const text = "Hello World";
  3. console.log(text.indexOf("World")); // 6
  4. console.log(text.indexOf("world")); // -1 (区分大小写)

  5. // 从指定位置开始搜索
  6. console.log(text.indexOf("o", 5)); // 7 (从索引5开始搜索'o')
  7. console.log(text.indexOf("o", 8)); // -1 (从索引8开始搜索'o',未找到)

  8. // 搜索空字符串
  9. console.log(text.indexOf("")); // 0 (空字符串总是存在于任何字符串的开始)
  10. console.log(text.indexOf("", 5)); // 5 (从索引5开始,空字符串存在于索引5)
javascript
数组搜索
  1. const numbers = [1, 2, 3, 4, 5, 2, 6];
  2. console.log(numbers.indexOf(2)); // 1 (第一个2的位置)
  3. console.log(numbers.indexOf(2, 2)); // 5 (从索引2开始搜索,找到第二个2)

  4. const mixed = [1, "hello", true, null, undefined];
  5. console.log(mixed.indexOf("hello")); // 1
  6. console.log(mixed.indexOf(true)); // 2
  7. console.log(mixed.indexOf(null)); // 3
  8. console.log(mixed.indexOf(undefined)); // 4
javascript
2. 高级应用场景
查找所有匹配项
  1. function findAllOccurrences(str, searchValue) {
  2. const positions = [];
  3. let index = str.indexOf(searchValue);
  4. while (index !== -1) {
  5. positions.push(index);
  6. index = str.indexOf(searchValue, index + 1);
  7. }
  8. return positions;
  9. }

  10. const text = "JavaScript is amazing and JavaScript is powerful";
  11. console.log(findAllOccurrences(text, "JavaScript")); // [0, 25]
  12. console.log(findAllOccurrences(text, "is")); // [11, 33, 36]
javascript
检查字符串是否以特定内容开始或结束
  1. function startsWith(str, prefix) {
  2. return str.indexOf(prefix) === 0;
  3. }

  4. function endsWith(str, suffix) {
  5. const index = str.indexOf(suffix);
  6. return index !== -1 && index === str.length - suffix.length;
  7. }

  8. console.log(startsWith("Hello World", "Hello")); // true
  9. console.log(startsWith("Hello World", "World")); // false
  10. console.log(endsWith("Hello World", "World")); // true
  11. console.log(endsWith("Hello World", "Hello")); // false
javascript
提取子字符串
  1. function extractBetween(str, startDelimiter, endDelimiter) {
  2. const startIndex = str.indexOf(startDelimiter);
  3. if (startIndex === -1) return null;
  4. const endIndex = str.indexOf(endDelimiter, startIndex + startDelimiter.length);
  5. if (endIndex === -1) return null;
  6. return str.substring(startIndex + startDelimiter.length, endIndex);
  7. }

  8. const text = "Hello [World] and [Universe]";
  9. console.log(extractBetween(text, "[", "]")); // "World"
javascript
3. 实际项目应用
表单验证
  1. function validateEmail(email) {
  2. // 检查是否包含@符号
  3. const atIndex = email.indexOf("@");
  4. if (atIndex === -1) {
  5. return "邮箱必须包含@符号";
  6. }
  7. // 检查@符号不在开头或结尾
  8. if (atIndex === 0 || atIndex === email.length - 1) {
  9. return "@符号不能在开头或结尾";
  10. }
  11. // 检查是否包含域名
  12. const dotIndex = email.indexOf(".", atIndex);
  13. if (dotIndex === -1 || dotIndex === atIndex + 1) {
  14. return "邮箱格式不正确";
  15. }
  16. return "邮箱格式正确";
  17. }

  18. console.log(validateEmail("user@example.com")); // "邮箱格式正确"
  19. console.log(validateEmail("user@.com")); // "邮箱格式不正确"
  20. console.log(validateEmail("@example.com")); // "@符号不能在开头或结尾"
javascript
文件路径处理
  1. function getFileExtension(filename) {
  2. const lastDotIndex = filename.lastIndexOf(".");
  3. if (lastDotIndex === -1 || lastDotIndex === filename.length - 1) {
  4. return null;
  5. }
  6. return filename.substring(lastDotIndex + 1);
  7. }

  8. function getFileNameWithoutExtension(filename) {
  9. const lastDotIndex = filename.lastIndexOf(".");
  10. if (lastDotIndex === -1) {
  11. return filename;
  12. }
  13. return filename.substring(0, lastDotIndex);
  14. }

  15. console.log(getFileExtension("document.pdf")); // "pdf"
  16. console.log(getFileExtension("image.jpg")); // "jpg"
  17. console.log(getFileExtension("README")); // null
  18. console.log(getFileNameWithoutExtension("document.pdf")); // "document"
javascript
URL参数解析
  1. function getQueryParam(url, paramName) {
  2. const queryIndex = url.indexOf("?");
  3. if (queryIndex === -1) return null;
  4. const queryString = url.substring(queryIndex + 1);
  5. const paramStart = queryString.indexOf(paramName + "=");
  6. if (paramStart === -1) return null;
  7. const valueStart = paramStart + paramName.length + 1;
  8. const valueEnd = queryString.indexOf("&", valueStart);
  9. if (valueEnd === -1) {
  10. return queryString.substring(valueStart);
  11. }
  12. return queryString.substring(valueStart, valueEnd);
  13. }

  14. const url = "https://example.com/page?name=John&age=25&city=NYC";
  15. console.log(getQueryParam(url, "name")); // "John"
  16. console.log(getQueryParam(url, "age")); // "25"
  17. console.log(getQueryParam(url, "city")); // "NYC"
  18. console.log(getQueryParam(url, "country")); // null
javascript
4. 性能优化技巧
使用includes()进行简单存在性检查
  1. // 性能更好的方式
  2. const fruits = ["apple", "banana", "cherry"];

  3. // 推荐:使用includes()检查存在性
  4. if (fruits.includes("banana")) {
  5. console.log("Found banana!");
  6. }

  7. // 不推荐:使用indexOf()检查存在性
  8. if (fruits.indexOf("banana") !== -1) {
  9. console.log("Found banana!");
  10. }
javascript
缓存indexOf()结果
  1. function processText(text, searchTerm) {
  2. const index = text.indexOf(searchTerm);
  3. if (index !== -1) {
  4. // 使用缓存的索引值,避免重复计算
  5. const before = text.substring(0, index);
  6. const after = text.substring(index + searchTerm.length);
  7. return {
  8. found: true,
  9. position: index,
  10. before,
  11. after,
  12. replacement: before + "[HIGHLIGHTED]" + after
  13. };
  14. }
  15. return { found: false };
  16. }

  17. console.log(processText("Hello World", "World"));
  18. // { found: true, position: 6, before: "Hello ", after: "", replacement: "Hello [HIGHLIGHTED]" }
javascript
5. 常见陷阱和解决方案
陷阱1:NaN的处理
  1. const arr = [1, 2, NaN, 4];
  2. console.log(arr.indexOf(NaN)); // -1 (NaN !== NaN)

  3. // 解决方案:使用includes()
  4. console.log(arr.includes(NaN)); // true

  5. // 或者自定义函数
  6. function indexOfNaN(arr) {
  7. for (let i = 0; i < arr.length; i++) {
  8. if (Number.isNaN(arr[i])) {
  9. return i;
  10. }
  11. }
  12. return -1;
  13. }

  14. console.log(indexOfNaN(arr)); // 2
javascript
陷阱2:对象比较
  1. const objects = [{ id: 1 }, { id: 2 }, { id: 3 }];
  2. console.log(objects.indexOf({ id: 2 })); // -1 (对象引用不同)

  3. // 解决方案:使用findIndex()
  4. const index = objects.findIndex(obj => obj.id === 2);
  5. console.log(index); // 1

  6. // 或者使用some()检查存在性
  7. const exists = objects.some(obj => obj.id === 2);
  8. console.log(exists); // true
javascript
陷阱3:稀疏数组
  1. const sparseArray = [1, , 3, , 5];
  2. console.log(sparseArray.indexOf(undefined)); // -1 (稀疏数组的空槽不是undefined)

  3. // 解决方案:检查长度
  4. for (let i = 0; i < sparseArray.length; i++) {
  5. if (!(i in sparseArray)) {
  6. console.log(`Empty slot at index ${i}`);
  7. }
  8. }
javascript
6. 现代JavaScript替代方案
使用findIndex()查找复杂条件
  1. const users = [
  2. { id: 1, name: "Alice", age: 25 },
  3. { id: 2, name: "Bob", age: 30 },
  4. { id: 3, name: "Charlie", age: 35 }
  5. ];

  6. // 使用indexOf()无法实现
  7. // const index = users.indexOf({ name: "Bob" }); // -1

  8. // 使用findIndex()
  9. const bobIndex = users.findIndex(user => user.name === "Bob");
  10. console.log(bobIndex); // 1

  11. // 使用find()获取对象
  12. const bob = users.find(user => user.name === "Bob");
  13. console.log(bob); // { id: 2, name: "Bob", age: 30 }
javascript
使用includes()和startsWith()/endsWith()
  1. const text = "Hello World";

  2. // 检查包含
  3. console.log(text.includes("World")); // true

  4. // 检查开始
  5. console.log(text.startsWith("Hello")); // true

  6. // 检查结束
  7. console.log(text.endsWith("World")); // true

  8. // 这些方法比indexOf()更语义化
javascript
7. 面试题和练习
面试题1:实现自定义indexOf
  1. function customIndexOf(str, searchValue, fromIndex = 0) {
  2. if (fromIndex < 0) fromIndex = 0;
  3. if (fromIndex >= str.length) return -1;
  4. const searchLength = searchValue.length;
  5. if (searchLength === 0) return fromIndex;
  6. for (let i = fromIndex; i <= str.length - searchLength; i++) {
  7. let match = true;
  8. for (let j = 0; j < searchLength; j++) {
  9. if (str[i + j] !== searchValue[j]) {
  10. match = false;
  11. break;
  12. }
  13. }
  14. if (match) return i;
  15. }
  16. return -1;
  17. }

  18. console.log(customIndexOf("Hello World", "World")); // 6
  19. console.log(customIndexOf("Hello World", "World", 7)); // -1
javascript
面试题2:查找最长重复子字符串
  1. function findLongestRepeatedSubstring(str) {
  2. let longest = "";
  3. for (let i = 0; i < str.length; i++) {
  4. for (let j = i + 1; j < str.length; j++) {
  5. const substring = str.substring(i, j);
  6. const nextIndex = str.indexOf(substring, j);
  7. if (nextIndex !== -1 && substring.length > longest.length) {
  8. longest = substring;
  9. }
  10. }
  11. }
  12. return longest;
  13. }

  14. console.log(findLongestRepeatedSubstring("banana")); // "ana"
  15. console.log(findLongestRepeatedSubstring("abcd")); // ""
javascript
面试题3:检查字符串是否为回文
  1. function isPalindrome(str) {
  2. const cleanStr = str.toLowerCase().replace(/[^a-z0-9]/g, "");
  3. const length = cleanStr.length;
  4. for (let i = 0; i < length / 2; i++) {
  5. if (cleanStr[i] !== cleanStr[length - 1 - i]) {
  6. return false;
  7. }
  8. }
  9. return true;
  10. }

  11. console.log(isPalindrome("A man, a plan, a canal: Panama")); // true
  12. console.log(isPalindrome("race a car")); // false
javascript
总结
indexOf()方法是JavaScript中处理字符串和数组搜索的基础工具。虽然现代JavaScript提供了更多语义化的方法(如includes()、findIndex()等),但indexOf()仍然在需要获取位置信息的场景中发挥着重要作用。
关键要点:
基本用法:查找元素位置,未找到返回-1
大小写敏感:字符串搜索区分大小写
性能考虑:简单存在性检查优先使用includes()
实际应用:表单验证、文件处理、URL解析等
现代替代:复杂条件使用findIndex()、find()等方法
掌握indexOf()方法将帮助你更好地处理字符串和数组操作,为更复杂的JavaScript开发打下坚实基础。