有用的字符串方法

现在我们已经了解了字符串的基础知识,让我们开始思考可以使用内置方法对字符串执行哪些有用的操作,例如查找文本字符串的长度、连接和拆分字符串 、将字符串中的一个字符替换为另一个字符等等。

¥Now that we've looked at the very basics of strings, let's move up a gear and start thinking about what useful operations we can do on strings with built-in methods, such as finding the length of a text string, joining and splitting strings, substituting one character in a string for another, and more.

先决条件: 对 HTML 和 CSS 有基本的了解,对 JavaScript 有了解。
目标: 了解字符串是对象,并学习如何使用这些对象上可用的一些基本方法来操作字符串。

字符串作为对象

¥Strings as objects

JavaScript 中大多数事物都是对象。当你创建字符串时,例如使用

¥Most things are objects in JavaScript. When you create a string, for example by using

js
const string = "This is my string";

你的变量成为字符串对象实例,因此具有大量可用的属性和方法。如果你转到 String 对象页面并向下查看页面一侧的列表,你就可以看到这一点!

¥your variable becomes a string object instance, and as a result has a large number of properties and methods available to it. You can see this if you go to the String object page and look down the list on the side of the page!

现在,在你的大脑开始融化之前,别担心!在学习过程的早期,你确实不需要了解其中的大部分内容。但有一些你可能会经常使用的内容,我们将在此处介绍。

¥Now, before your brain starts melting, don't worry! You really don't need to know about most of these early on in your learning journey. But there are a few that you'll potentially use quite often that we'll look at here.

让我们在 浏览器开发者控制台.txt 中输入一些示例。

¥Let's enter some examples into the browser developer console.

查找字符串的长度

¥Finding the length of a string

这很简单 - 你使用 length 属性。尝试输入以下行:

¥This is easy — you use the length property. Try entering the following lines:

js
const browserType = "mozilla";
browserType.length;

这应该返回数字 7,因为 "mozilla" 是 7 个字符长。出于多种原因,这很有用;例如,你可能想要查找一系列名称的长度,以便可以按长度顺序显示它们,或者让用户知道他们在表单字段中输入的用户名如果超过特定长度则太长 。

¥This should return the number 7, because "mozilla" is 7 characters long. This is useful for many reasons; for example, you might want to find the lengths of a series of names so you can display them in order of length, or let a user know that a username they have entered into a form field is too long if it is over a certain length.

检索特定字符串字符

¥Retrieving a specific string character

与此相关的是,你可以使用方括号表示法返回字符串内的任何字符 - 这意味着你在变量名称的末尾包含方括号 ([])。在方括号内,你可以包含要返回的字符数,因此例如要检索第一个字母,你可以这样做:

¥On a related note, you can return any character inside a string by using square bracket notation — this means you include square brackets ([]) on the end of your variable name. Inside the square brackets, you include the number of the character you want to return, so for example to retrieve the first letter you'd do this:

js
browserType[0];

记住:计算机从 0 开始计数,而不是 1!

¥Remember: computers count from 0, not 1!

要检索任何字符串的最后一个字符,我们可以使用以下行,将此技术与我们上面看到的 length 属性相结合:

¥To retrieve the last character of any string, we could use the following line, combining this technique with the length property we looked at above:

js
browserType[browserType.length - 1];

字符串 "mozilla" 的长度是 7,但是因为计数是从 0 开始的,所以最后一个字符的位置是 6;使用 length-1 得到最后一个字符。

¥The length of the string "mozilla" is 7, but because the count starts at 0, the last character's position is 6; using length-1 gets us the last character.

测试字符串是否包含子字符串

¥Testing if a string contains a substring

有时你会想要查找较大字符串中是否存在较小的字符串(我们通常说字符串中是否存在子字符串)。这可以使用 includes() 方法来完成,该方法采用单个 parameter — 你要搜索的子字符串。

¥Sometimes you'll want to find if a smaller string is present inside a larger one (we generally say if a substring is present inside a string). This can be done using the includes() method, which takes a single parameter — the substring you want to search for.

如果字符串包含子字符串,则返回 true,否则返回 false

¥It returns true if the string contains the substring, and false otherwise.

js
const browserType = "mozilla";

if (browserType.includes("zilla")) {
  console.log("Found zilla!");
} else {
  console.log("No zilla here!");
}

通常你会想知道字符串是否以特定子字符串开头或结尾。这是一个很常见的需求,有两种特殊的方法可以实现:startsWith()endsWith()

¥Often you'll want to know if a string starts or ends with a particular substring. This is a common enough need that there are two special methods for this: startsWith() and endsWith():

js
const browserType = "mozilla";

if (browserType.startsWith("zilla")) {
  console.log("Found zilla!");
} else {
  console.log("No zilla here!");
}
js
const browserType = "mozilla";

if (browserType.endsWith("zilla")) {
  console.log("Found zilla!");
} else {
  console.log("No zilla here!");
}

查找子串在字符串中的位置

¥Finding the position of a substring in a string

你可以使用 indexOf() 方法找到较大字符串中子字符串的位置。此方法需要两个 parameters - 你要搜索的子字符串,以及指定搜索起点的可选参数。

¥You can find the position of a substring inside a larger string using the indexOf() method. This method takes two parameters – the substring that you want to search for, and an optional parameter that specifies the starting point of the search.

如果字符串包含子字符串,则 indexOf() 返回子字符串第一次出现的索引。如果字符串不包含子字符串,则 indexOf() 返回 -1

¥If the string contains the substring, indexOf() returns the index of the first occurrence of the substring. If the string does not contain the substring, indexOf() returns -1.

js
const tagline = "MDN - Resources for developers, by developers";
console.log(tagline.indexOf("developers")); // 20

0 开始,如果从字符串开头开始计算字符数(包括空格),则子字符串 "developers" 的第一次出现位于索引 20 处。

¥Starting at 0, if you count the number of characters (including the whitespace) from the beginning of the string, the first occurrence of the substring "developers" is at index 20.

js
console.log(tagline.indexOf("x")); // -1

另一方面,这会返回 -1,因为字符串中不存在字符 x

¥This, on the other hand, returns -1 because the character x is not present in the string.

既然你知道如何查找子字符串的第一次出现,那么如何查找后续出现的情况呢?你可以通过将大于前一个出现的索引的值作为该方法的第二个参数传递来实现此目的。

¥So now that you know how to find the first occurrence of a substring, how do you go about finding subsequent occurrences? You can do that by passing in a value that's greater than the index of the previous occurrence as the second parameter to the method.

js
const firstOccurrence = tagline.indexOf("developers");
const secondOccurrence = tagline.indexOf("developers", firstOccurrence + 1);

console.log(firstOccurrence); // 20
console.log(secondOccurrence); // 35

在这里,我们告诉该方法从索引 21 (firstOccurrence + 1) 开始搜索子字符串 "developers",并返回索引 35

¥Here we're telling the method to search for the substring "developers" starting at index 21 (firstOccurrence + 1), and it returns the index 35.

从字符串中提取子字符串

¥Extracting a substring from a string

你可以使用 slice() 方法从字符串中提取子字符串。你通过它:

¥You can extract a substring from a string using the slice() method. You pass it:

  • 开始提取的索引
  • 停止提取的索引。这是独占的,意味着该索引处的字符不包含在提取的子字符串中。

例如:

¥For example:

js
const browserType = "mozilla";
console.log(browserType.slice(1, 4)); // "ozi"

索引 1 处的字符是 "o",索引 4 处的字符是 "l"。因此,我们提取从 "o" 开始到 "l" 之前结束的所有字符,得到 "ozi"

¥The character at index 1 is "o", and the character at index 4 is "l". So we extract all characters starting at "o" and ending just before "l", giving us "ozi".

如果你知道要提取字符串中某个字符之后的所有剩余字符,则不必包含第二个参数。相反,你只需要包含要从中提取字符串中剩余字符的字符位置。请尝试以下操作:

¥If you know that you want to extract all of the remaining characters in a string after a certain character, you don't have to include the second parameter. Instead, you only need to include the character position from where you want to extract the remaining characters in a string. Try the following:

js
browserType.slice(2); // "zilla"

这将返回 "zilla" — 这是因为 2 的字符位置是字母 "z",并且由于你没有包含第二个参数,因此返回的子字符串是字符串中的所有剩余字符。

¥This returns "zilla" — this is because the character position of 2 is the letter "z", and because you didn't include a second parameter, the substring that was returned was all of the remaining characters in the string.

注意:slice() 还有其他选择;研究 slice() 页,看看你还可以找到什么。

¥Note: slice() has other options too; study the slice() page to see what else you can find out.

改变大小写

¥Changing case

字符串方法 toLowerCase()toUpperCase() 接受一个字符串并将所有字符分别转换为小写或大写。例如,如果你想在将所有用户输入的数据存储到数据库之前对其进行规范化,这可能很有用。

¥The string methods toLowerCase() and toUpperCase() take a string and convert all the characters to lower- or uppercase, respectively. This can be useful for example if you want to normalize all user-entered data before storing it in a database.

让我们尝试输入以下几行看看会发生什么:

¥Let's try entering the following lines to see what happens:

js
const radData = "My NaMe Is MuD";
console.log(radData.toLowerCase());
console.log(radData.toUpperCase());

更新字符串的部分内容

¥Updating parts of a string

你可以使用 replace() 方法将字符串中的一个子字符串替换为另一个子字符串。

¥You can replace one substring inside a string with another substring using the replace() method.

在此示例中,我们提供两个参数 - 我们要替换的字符串以及我们要替换的字符串:

¥In this example, we're providing two parameters — the string we want to replace, and the string we want to replace it with:

js
const browserType = "mozilla";
const updated = browserType.replace("moz", "van");

console.log(updated); // "vanilla"
console.log(browserType); // "mozilla"

请注意,与许多字符串方法一样,replace() 不会更改调用它的字符串,而是返回一个新字符串。如果你想更新原始的 browserType 变量,你必须这样做:

¥Note that replace(), like many string methods, doesn't change the string it was called on, but returns a new string. If you want to update the original browserType variable, you would have to do something like this:

js
let browserType = "mozilla";
browserType = browserType.replace("moz", "van");

console.log(browserType); // "vanilla"

另请注意,我们现在必须使用 let 而不是 const 来声明 browserType,因为我们正在重新分配它。

¥Also note that we now have to declare browserType using let, not const, because we are reassigning it.

请注意,这种形式的 replace() 仅更改第一次出现的子字符串。如果要更改所有出现的情况,可以使用 replaceAll()

¥Be aware that replace() in this form only changes the first occurrence of the substring. If you want to change all occurrences, you can use replaceAll():

js
let quote = "To be or not to be";
quote = quote.replaceAll("be", "code");

console.log(quote); // "To code or not to code"

主动学习实例

¥Active learning examples

在本节中,我们将让你尝试编写一些字符串操作代码。在下面的每个练习中,我们都有一个字符串数组,以及一个处理数组中每个值并将其显示在项目符号列表中的循环。你现在不需要了解数组或循环 - 这些将在以后的文章中解释。在每种情况下,你所需要做的就是编写代码,以我们想要的格式输出字符串。

¥In this section, we'll get you to try your hand at writing some string manipulation code. In each exercise below, we have an array of strings, and a loop that processes each value in the array and displays it in a bulleted list. You don't need to understand arrays or loops right now — these will be explained in future articles. All you need to do in each case is write the code that will output the strings in the format that we want them in.

每个示例都带有一个 "重置" 按钮,如果你犯了错误并且无法使其再次工作,你可以使用该按钮重置代码;如果你真的遇到困难,可以按 "显示解决方案" 按钮查看潜在的答案。

¥Each example comes with a "Reset" button, which you can use to reset the code if you make a mistake and can't get it working again, and a "Show solution" button you can press to see a potential answer if you get really stuck.

过滤问候语消息

¥Filtering greeting messages

在第一个练习中,我们将从简单开始 - 我们有一系列贺卡消息,但我们希望对它们进行排序以仅列出圣诞节消息。我们希望你在 if () 结构中填写一个条件测试来测试每个字符串,并且仅在它是圣诞节消息时才将其打印在列表中。

¥In the first exercise, we'll start you off simple — we have an array of greeting card messages, but we want to sort them to list just the Christmas messages. We want you to fill in a conditional test inside the if () structure to test each string and only print it in the list if it is a Christmas message.

考虑一下如何测试每种情况下的消息是否是圣诞节消息。所有这些消息中都存在什么字符串,你可以使用什么方法来测试它是否存在?

¥Think about how you could test whether the message in each case is a Christmas message. What string is present in all of those messages, and what method could you use to test whether it is present?

html
<h2>Live output</h2>

<div class="output" style="min-height: 125px;">
  <ul></ul>
</div>

<h2>Editable code</h2>
<p class="a11y-label">
  Press Esc to move focus away from the code area (Tab inserts a tab character).
</p>

<textarea id="code" class="playable-code" style="height: 290px; width: 95%">
const list = document.querySelector('.output ul');
list.innerHTML = '';
const greetings = ['Happy Birthday!',
                 'Merry Christmas my love',
                 'A happy Christmas to all the family',
                 'You\'re all I want for Christmas',
                 'Get well soon'];

for (const greeting of greetings) {
  // Your conditional test needs to go inside the parentheses
  // in the line below, replacing what's currently there
  if (greeting) {
    const listItem = document.createElement('li');
    listItem.textContent = greeting;
    list.appendChild(listItem);
  }
}
</textarea>

<div class="playable-buttons">
  <input id="reset" type="button" value="Reset" />
  <input id="solution" type="button" value="Show solution" />
</div>
css
html {
  font-family: sans-serif;
}

h2 {
  font-size: 16px;
}

.a11y-label {
  margin: 0;
  text-align: right;
  font-size: 0.7rem;
  width: 98%;
}

body {
  margin: 10px;
  background: #f5f9fa;
}
js
const textarea = document.getElementById("code");
const reset = document.getElementById("reset");
const solution = document.getElementById("solution");
let code = textarea.value;
let userEntry = textarea.value;

function updateCode() {
  eval(textarea.value);
}

reset.addEventListener("click", () => {
  textarea.value = code;
  userEntry = textarea.value;
  solutionEntry = jsSolution;
  solution.value = "Show solution";
  updateCode();
});

solution.addEventListener("click", () => {
  if (solution.value === "Show solution") {
    textarea.value = solutionEntry;
    solution.value = "Hide solution";
  } else {
    textarea.value = userEntry;
    solution.value = "Show solution";
  }
  updateCode();
});

const jsSolution = `const list = document.querySelector('.output ul');
list.innerHTML = '';
const greetings = [
  'Happy Birthday!',
  'Merry Christmas my love',
  'A happy Christmas to all the family',
  'You\\'re all I want for Christmas',
  'Get well soon',
];

for (const greeting of greetings) {
  // Your conditional test needs to go inside the parentheses
  // in the line below, replacing what's currently there
  if (greeting.includes('Christmas')) {
    const listItem = document.createElement('li');
    listItem.textContent = greeting;
    list.appendChild(listItem);
  }
}`;

let solutionEntry = jsSolution;

textarea.addEventListener("input", updateCode);
window.addEventListener("load", updateCode);

// stop tab key tabbing out of textarea and
// make it write a tab at the caret position instead

textarea.onkeydown = (e) => {
  if (e.keyCode === 9) {
    e.preventDefault();
    insertAtCaret("\t");
  }

  if (e.keyCode === 27) {
    textarea.blur();
  }
};

function insertAtCaret(text) {
  const scrollPos = textarea.scrollTop;
  let caretPos = textarea.selectionStart;
  const front = textarea.value.substring(0, caretPos);
  const back = textarea.value.substring(
    textarea.selectionEnd,
    textarea.value.length,
  );

  textarea.value = front + text + back;
  caretPos += text.length;
  textarea.selectionStart = caretPos;
  textarea.selectionEnd = caretPos;
  textarea.focus();
  textarea.scrollTop = scrollPos;
}

// Update the saved userCode every time the user updates the text area code

textarea.onkeyup = () => {
  // We only want to save the state when the user code is being shown,
  // not the solution, so that solution is not saved over the user code
  if (solution.value === "Show solution") {
    userEntry = textarea.value;
  } else {
    solutionEntry = textarea.value;
  }

  updateCode();
};

固定大小写

¥Fixing capitalization

在这个练习中,我们有英国城市的名称,但大小写全乱了。我们希望你将它们更改为小写,首字母大写除外。做到这一点的一个好方法是:

¥In this exercise, we have the names of cities in the United Kingdom, but the capitalization is all messed up. We want you to change them so that they are all lowercase, except for a capital first letter. A good way to do this is to:

  1. city 变量中包含的整个字符串转换为小写并将其存储在新变量中。
  2. 获取这个新变量中字符串的第一个字母并将其存储在另一个变量中。
  3. 使用这个最新的变量作为子字符串,将小写字符串的第一个字母替换为小写字符串的第一个字母更改为大写。将此替换过程的结果存储在另一个新变量中。
  4. result 变量的值更改为等于最终结果,而不是 city

注意:提示 - 字符串方法的参数不必是字符串文字;它们也可以是变量,甚至可以是带有对其调用的方法的变量。

¥Note: A hint — the parameters of the string methods don't have to be string literals; they can also be variables, or even variables with a method being invoked on them.

html
<h2>Live output</h2>

<div class="output" style="min-height: 125px;">
  <ul></ul>
</div>

<h2>Editable code</h2>
<p class="a11y-label">
  Press Esc to move focus away from the code area (Tab inserts a tab character).
</p>

<textarea id="code" class="playable-code" style="height: 250px; width: 95%">
const list = document.querySelector('.output ul');
list.innerHTML = '';
const cities = ['lonDon', 'ManCHESTer', 'BiRmiNGHAM', 'liVERpoOL'];

for (const city of cities) {
  // write your code just below here

  const result = city;
  const listItem = document.createElement('li');
  listItem.textContent = result;
  list.appendChild(listItem);
}
</textarea>

<div class="playable-buttons">
  <input id="reset" type="button" value="Reset" />
  <input id="solution" type="button" value="Show solution" />
</div>
css
html {
  font-family: sans-serif;
}

h2 {
  font-size: 16px;
}

.a11y-label {
  margin: 0;
  text-align: right;
  font-size: 0.7rem;
  width: 98%;
}

body {
  margin: 10px;
  background: #f5f9fa;
}
js
const textarea = document.getElementById("code");
const reset = document.getElementById("reset");
const solution = document.getElementById("solution");
let code = textarea.value;
let userEntry = textarea.value;

function updateCode() {
  eval(textarea.value);
}

reset.addEventListener("click", function () {
  textarea.value = code;
  userEntry = textarea.value;
  solutionEntry = jsSolution;
  solution.value = "Show solution";
  updateCode();
});

solution.addEventListener("click", function () {
  if (solution.value === "Show solution") {
    textarea.value = solutionEntry;
    solution.value = "Hide solution";
  } else {
    textarea.value = userEntry;
    solution.value = "Show solution";
  }
  updateCode();
});

const jsSolution = `const list = document.querySelector('.output ul');
list.innerHTML = '';
const cities = ['lonDon', 'ManCHESTer', 'BiRmiNGHAM', 'liVERpoOL'];

for (const city of cities) {
  // write your code just below here
  const lower = city.toLowerCase();
  const firstLetter = lower.slice(0,1);
  const capitalized = lower.replace(firstLetter,firstLetter.toUpperCase());
  const result = capitalized;
  const listItem = document.createElement('li');
  listItem.textContent = result;
  list.appendChild(listItem);
}`;

let solutionEntry = jsSolution;

textarea.addEventListener("input", updateCode);
window.addEventListener("load", updateCode);

// stop tab key tabbing out of textarea and
// make it write a tab at the caret position instead

textarea.onkeydown = function (e) {
  if (e.keyCode === 9) {
    e.preventDefault();
    insertAtCaret("\t");
  }

  if (e.keyCode === 27) {
    textarea.blur();
  }
};

function insertAtCaret(text) {
  const scrollPos = textarea.scrollTop;
  let caretPos = textarea.selectionStart;
  const front = textarea.value.substring(0, caretPos);
  const back = textarea.value.substring(
    textarea.selectionEnd,
    textarea.value.length,
  );

  textarea.value = front + text + back;
  caretPos += text.length;
  textarea.selectionStart = caretPos;
  textarea.selectionEnd = caretPos;
  textarea.focus();
  textarea.scrollTop = scrollPos;
}

// Update the saved userCode every time the user updates the text area code

textarea.onkeyup = function () {
  // We only want to save the state when the user code is being shown,
  // not the solution, so that solution is not saved over the user code
  if (solution.value === "Show solution") {
    userEntry = textarea.value;
  } else {
    solutionEntry = textarea.value;
  }

  updateCode();
};

用旧零件制作新琴弦

¥Making new strings from old parts

在最后一个练习中,数组包含一堆字符串,其中包含有关英格兰北部火车站的信息。这些字符串是包含三个字母的电台代码的数据项,后跟一些机器可读的数据,然后是分号,最后是人类可读的电台名称。例如:

¥In this last exercise, the array contains a bunch of strings containing information about train stations in the North of England. The strings are data items that contain the three-letter station code, followed by some machine-readable data, followed by a semicolon, followed by the human-readable station name. For example:

MAN675847583748sjt567654;Manchester Piccadilly

我们要提取车站代码和名称,并将它们放在一个具有以下结构的字符串中:

¥We want to extract the station code and name, and put them together in a string with the following structure:

MAN: Manchester Piccadilly

我们建议这样做:

¥We'd recommend doing it like this:

  1. 提取三字母车站代码并将其存储在新变量中。
  2. 查找分号的字符索引号。
  3. 使用分号字符索引号作为参考点提取人类可读的站名称,并将其存储在新变量中。
  4. 连接两个新变量和一个字符串文字以形成最终字符串。
  5. result 变量的值更改为最终字符串,而不是 station
html
<h2>Live output</h2>

<div class="output" style="min-height: 125px;">
  <ul></ul>
</div>

<h2>Editable code</h2>
<p class="a11y-label">
  Press Esc to move focus away from the code area (Tab inserts a tab character).
</p>

<textarea id="code" class="playable-code" style="height: 285px; width: 95%">
const list = document.querySelector('.output ul');
list.innerHTML = '';
const stations = ['MAN675847583748sjt567654;Manchester Piccadilly',
                  'GNF576746573fhdg4737dh4;Greenfield',
                  'LIV5hg65hd737456236dch46dg4;Liverpool Lime Street',
                  'SYB4f65hf75f736463;Stalybridge',
                  'HUD5767ghtyfyr4536dh45dg45dg3;Huddersfield'];

for (const station of stations) {
  // write your code just below here

  const result = station;
  const listItem = document.createElement('li');
  listItem.textContent = result;
  list.appendChild(listItem);
}
</textarea>

<div class="playable-buttons">
  <input id="reset" type="button" value="Reset" />
  <input id="solution" type="button" value="Show solution" />
</div>
css
html {
  font-family: sans-serif;
}

h2 {
  font-size: 16px;
}

.a11y-label {
  margin: 0;
  text-align: right;
  font-size: 0.7rem;
  width: 98%;
}

body {
  margin: 10px;
  background: #f5f9fa;
}
js
const textarea = document.getElementById("code");
const reset = document.getElementById("reset");
const solution = document.getElementById("solution");
let code = textarea.value;
let userEntry = textarea.value;

function updateCode() {
  eval(textarea.value);
}

reset.addEventListener("click", function () {
  textarea.value = code;
  userEntry = textarea.value;
  solutionEntry = jsSolution;
  solution.value = "Show solution";
  updateCode();
});

solution.addEventListener("click", function () {
  if (solution.value === "Show solution") {
    textarea.value = solutionEntry;
    solution.value = "Hide solution";
  } else {
    textarea.value = userEntry;
    solution.value = "Show solution";
  }
  updateCode();
});

const jsSolution = `const list = document.querySelector('.output ul');
list.innerHTML = '';
const stations = ['MAN675847583748sjt567654;Manchester Piccadilly',
                  'GNF576746573fhdg4737dh4;Greenfield',
                  'LIV5hg65hd737456236dch46dg4;Liverpool Lime Street',
                  'SYB4f65hf75f736463;Stalybridge',
                  'HUD5767ghtyfyr4536dh45dg45dg3;Huddersfield'];

for (const station of stations) {
  // write your code just below here
  const code = station.slice(0,3);
  const semiColon = station.indexOf(';');
  const name = station.slice(semiColon + 1);
  const result = \`\${code}: \${name}\`;
  const listItem = document.createElement('li');
  listItem.textContent = result;
  list.appendChild(listItem);
}`;

let solutionEntry = jsSolution;

textarea.addEventListener("input", updateCode);
window.addEventListener("load", updateCode);

// stop tab key tabbing out of textarea and
// make it write a tab at the caret position instead

textarea.onkeydown = function (e) {
  if (e.keyCode === 9) {
    e.preventDefault();
    insertAtCaret("\t");
  }

  if (e.keyCode === 27) {
    textarea.blur();
  }
};

function insertAtCaret(text) {
  const scrollPos = textarea.scrollTop;
  let caretPos = textarea.selectionStart;
  const front = textarea.value.substring(0, caretPos);
  const back = textarea.value.substring(
    textarea.selectionEnd,
    textarea.value.length,
  );

  textarea.value = front + text + back;
  caretPos += text.length;
  textarea.selectionStart = caretPos;
  textarea.selectionEnd = caretPos;
  textarea.focus();
  textarea.scrollTop = scrollPos;
}

// Update the saved userCode every time the user updates the text area code

textarea.onkeyup = function () {
  // We only want to save the state when the user code is being shown,
  // not the solution, so that solution is not saved over the user code
  if (solution.value === "Show solution") {
    userEntry = textarea.value;
  } else {
    solutionEntry = textarea.value;
  }

  updateCode();
};

测试你的技能!

¥Test your skills!

你已读完本文,但你还记得最重要的信息吗?在继续之前,你可以找到一些进一步的测试来验证你是否已保留此信息 - 请参阅 测试你的技能:字符串

¥You've reached the end of this article, but can you remember the most important information? You can find some further tests to verify that you've retained this information before you move on — see Test your skills: Strings.

结论

¥Conclusion

你无法逃避这样一个事实:能够在编程中处理单词和句子非常重要 - 尤其是在 JavaScript 中,因为网站就是与人交流。本文为你提供了目前需要了解的有关操作字符串的基础知识。当你将来讨论更复杂的主题时,这应该对你很有帮助。接下来,我们将讨论短期内需要关注的最后一种主要数据类型 - 数组。

¥You can't escape the fact that being able to handle words and sentences in programming is very important — particularly in JavaScript, as websites are all about communicating with people. This article has given you the basics that you need to know about manipulating strings for now. This should serve you well as you go into more complex topics in the future. Next, we're going to look at the last major type of data we need to focus on in the short term — arrays.