{"id":"l-js-1-4","courseId":"javascript-fundamentals","lang":"en","kind":"lesson","summary":"Create and clean up strings, read characters by index, use the everyday string methods, and build readable output such as “Lunch: $12.20” with template literals.","html":"<p>Pocket’s numbers are exact now, but nobody wants to read <code dir=\"ltr\">1220</code>. People want <code dir=\"ltr\">Lunch: $12.20</code>. Text in JavaScript is a <strong>string</strong>, and most of what a user ever sees from your program is a string you built.</p>\n<h2 id=\"sec-1\" tabindex=\"-1\">Writing strings</h2>\n<p>You can write a string with single quotes, double quotes or backticks:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"js\" data-run=\"js\" data-index=\"0\"><div class=\"code-head\"><span class=\"code-title\">JavaScript</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn code-run\" data-action=\"run\" data-lang=\"js\" data-index=\"0\" aria-label=\"Run this example\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z\"/></svg><span>Run</span></button><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"Copy code\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>Copy</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">const</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> a</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> 'Coffee'</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">;</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">const</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> b</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> \"Sam's lunch\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">;</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">const</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> c</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> `Bus`</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">;</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">console.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(a, b, c);</span></span></code></pre><div class=\"run-output\" data-run-output=\"0\" hidden></div></div>\n<p>Single and double quotes behave the same; pick one style and stick to it (this course uses double quotes). Use the other kind when your text contains a quote, as in <code dir=\"ltr\">&quot;Sam's lunch&quot;</code>, or escape it with a backslash: <code dir=\"ltr\">'Sam\\'s lunch'</code>. <code dir=\"ltr\">\\n</code> inside a string is a line break.</p>\n<p>Backticks are special, and you will use them most. They make <strong>template literals</strong>.</p>\n<h2 id=\"sec-2\" tabindex=\"-1\">Template literals: values inside text</h2>\n<p>Joining strings with <code dir=\"ltr\">+</code> gets messy quickly: <code dir=\"ltr\">&quot;Lunch: $&quot; + dollars + &quot; (&quot; + category + &quot;)&quot;</code>. It is easy to forget a space or a quote. A template literal lets you write the text once and drop values into it with <code dir=\"ltr\">${ }</code>:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"js\" data-run=\"js\" data-index=\"1\"><div class=\"code-head\"><span class=\"code-title\">JavaScript</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn code-run\" data-action=\"run\" data-lang=\"js\" data-index=\"1\" aria-label=\"Run this example\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z\"/></svg><span>Run</span></button><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"Copy code\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>Copy</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">const</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> label</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> \"Lunch\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">;</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">const</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> cents</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 1220</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">;</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">const</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> category</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> \"food\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">;</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">const</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> line</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> `${</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">label</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">}: $${</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">(</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">cents</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> /</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 100</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">).</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">toFixed</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">2</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">)</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">} (${</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">category</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">})`</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">;</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">console.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(line);</span></span></code></pre><div class=\"run-output\" data-run-output=\"1\" hidden></div></div>\n<p>Anything inside <code dir=\"ltr\">${ }</code> is a full JavaScript expression. It is evaluated, turned into a string, and inserted. Here <code dir=\"ltr\">(cents / 100).toFixed(2)</code> divides to get <code dir=\"ltr\">12.2</code>, and <code dir=\"ltr\">toFixed(2)</code> turns that into the string <code dir=\"ltr\">&quot;12.20&quot;</code> with exactly two decimals. The first <code dir=\"ltr\">$</code> is a plain dollar sign; only <code dir=\"ltr\">$</code> followed by <code dir=\"ltr\">{</code> starts an insertion.</p>\n<p>Template literals can also span lines, which is handy for multi-line messages:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"js\" data-run=\"js\" data-index=\"2\"><div class=\"code-head\"><span class=\"code-title\">JavaScript</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn code-run\" data-action=\"run\" data-lang=\"js\" data-index=\"2\" aria-label=\"Run this example\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z\"/></svg><span>Run</span></button><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"Copy code\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>Copy</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">const</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> report</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> `Pocket summary</span></span>\n<span class=\"line\"><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">  Spent: $22.00</span></span>\n<span class=\"line\"><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">  Left:  $3.00`</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">;</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">console.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(report);</span></span></code></pre><div class=\"run-output\" data-run-output=\"2\" hidden></div></div>\n<aside class=\"callout callout-tip\" role=\"note\"><p class=\"callout-title\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5\"/><path d=\"M9 18h6\"/><path d=\"M10 22h4\"/></svg><span><span class=\"callout-kind\">Tip</span><span class=\"callout-sep\" aria-hidden=\"true\"> · </span>A proper currency formatter</span></p>\n<p><code dir=\"ltr\">toFixed</code> is fine for Pocket. For real apps that show many currencies, use the built-in formatter, which knows every currency’s symbol and separators:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"js\" data-run=\"js\" data-index=\"3\"><div class=\"code-head\"><span class=\"code-title\">JavaScript</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn code-run\" data-action=\"run\" data-lang=\"js\" data-index=\"3\" aria-label=\"Run this example\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z\"/></svg><span>Run</span></button><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"Copy code\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>Copy</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">const</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> usd</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> new</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> Intl.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">NumberFormat</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"en-US\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, { style: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"currency\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, currency: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"USD\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> });</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">console.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(usd.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">format</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">1220</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> /</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 100</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">));</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">console.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(usd.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">format</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">1234567</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> /</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 100</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">));</span></span></code></pre><div class=\"run-output\" data-run-output=\"3\" hidden></div></div>\n</aside>\n<h2 id=\"sec-3\" tabindex=\"-1\">Characters, positions and slices</h2>\n<p>A string is a sequence of characters, and each one has a position called an <strong>index</strong>, counting from 0. <code dir=\"ltr\">length</code> tells you how many characters there are.</p>\n<figure class=\"diagram\"><svg class=\"diagram-svg\" focusable=\"false\" viewBox=\"0 0 640 200\" role=\"img\" aria-labelledby=\"l-js-1-4-t1\"><defs><marker id=\"arrow-l-js-1-4-1\" viewBox=\"0 0 10 10\" refX=\"9\" refY=\"5\" markerWidth=\"7\" markerHeight=\"7\" orient=\"auto-start-reverse\"><path d=\"M0 0 L10 5 L0 10 z\" class=\"d-arrowhead\"/></marker></defs>\n  <title id=\"l-js-1-4-t1\">The string Coffee has six characters at indexes 0 to 5. slice(0, 3) copies indexes 0, 1 and 2, giving Cof, and stops before index 3.</title>\n  <rect class=\"d-box-primary\" x=\"110\" y=\"40\" width=\"70\" height=\"56\" rx=\"8\"/>\n  <text class=\"d-code\" x=\"145\" y=\"74\" text-anchor=\"middle\">C</text>\n  <rect class=\"d-box-primary\" x=\"180\" y=\"40\" width=\"70\" height=\"56\" rx=\"8\"/>\n  <text class=\"d-code\" x=\"215\" y=\"74\" text-anchor=\"middle\">o</text>\n  <rect class=\"d-box-primary\" x=\"250\" y=\"40\" width=\"70\" height=\"56\" rx=\"8\"/>\n  <text class=\"d-code\" x=\"285\" y=\"74\" text-anchor=\"middle\">f</text>\n  <rect class=\"d-box\" x=\"320\" y=\"40\" width=\"70\" height=\"56\" rx=\"8\"/>\n  <text class=\"d-code\" x=\"355\" y=\"74\" text-anchor=\"middle\">f</text>\n  <rect class=\"d-box\" x=\"390\" y=\"40\" width=\"70\" height=\"56\" rx=\"8\"/>\n  <text class=\"d-code\" x=\"425\" y=\"74\" text-anchor=\"middle\">e</text>\n  <rect class=\"d-box\" x=\"460\" y=\"40\" width=\"70\" height=\"56\" rx=\"8\"/>\n  <text class=\"d-code\" x=\"495\" y=\"74\" text-anchor=\"middle\">e</text>\n  <text class=\"d-label-muted\" x=\"145\" y=\"122\" text-anchor=\"middle\">0</text>\n  <text class=\"d-label-muted\" x=\"215\" y=\"122\" text-anchor=\"middle\">1</text>\n  <text class=\"d-label-muted\" x=\"285\" y=\"122\" text-anchor=\"middle\">2</text>\n  <text class=\"d-label-muted\" x=\"355\" y=\"122\" text-anchor=\"middle\">3</text>\n  <text class=\"d-label-muted\" x=\"425\" y=\"122\" text-anchor=\"middle\">4</text>\n  <text class=\"d-label-muted\" x=\"495\" y=\"122\" text-anchor=\"middle\">5</text>\n  <text class=\"d-label-muted\" x=\"60\" y=\"122\" text-anchor=\"middle\">index</text>\n  <path class=\"d-line\" d=\"M110 150 L320 150\"/>\n  <text class=\"d-code\" x=\"215\" y=\"178\" text-anchor=\"middle\">slice(0, 3) → \"Cof\"</text>\n  <path class=\"d-dashed\" d=\"M320 30 L320 160\"/>\n  <text class=\"d-label-muted\" x=\"420\" y=\"178\" text-anchor=\"middle\">stops before 3</text>\n</svg><figcaption>Indexes start at 0, and slice stops before its end index</figcaption></figure>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"js\" data-run=\"js\" data-index=\"4\"><div class=\"code-head\"><span class=\"code-title\">JavaScript</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn code-run\" data-action=\"run\" data-lang=\"js\" data-index=\"4\" aria-label=\"Run this example\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z\"/></svg><span>Run</span></button><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"Copy code\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>Copy</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">const</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> word</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> \"Coffee\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">;</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">console.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(word.</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">length</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">);      </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// 6</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">console.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(word[</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">0</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">]);          </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// first character</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">console.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(word.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">at</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">-</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">1</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">));      </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// last character</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">console.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(word.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">slice</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">0</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">3</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">)); </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// from index 0 up to, not including, 3</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">console.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(word.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">slice</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">3</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">));    </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// from index 3 to the end</span></span></code></pre><div class=\"run-output\" data-run-output=\"4\" hidden></div></div>\n<p><code dir=\"ltr\">word.at(-1)</code> counts from the end, which saves you writing <code dir=\"ltr\">word[word.length - 1]</code>.</p>\n<h2 id=\"sec-4\" tabindex=\"-1\">Methods that return new strings</h2>\n<p>Strings come with built-in <strong>methods</strong>, functions you call with a dot. The ones you will use weekly:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"js\" data-run=\"js\" data-index=\"5\"><div class=\"code-head\"><span class=\"code-title\">JavaScript</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn code-run\" data-action=\"run\" data-lang=\"js\" data-index=\"5\" aria-label=\"Run this example\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z\"/></svg><span>Run</span></button><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"Copy code\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>Copy</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">const</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> raw</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> \"  Coffee with Sam  \"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">;</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">const</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> clean</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> raw.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">trim</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">();</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">console.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(clean);                      </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// spaces removed from both ends</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">console.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(clean.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">toUpperCase</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">());</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">console.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(clean.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">includes</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Sam\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">));      </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// true or false</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">console.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(clean.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">startsWith</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Coffee\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">));</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">console.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(clean.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">replaceAll</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\" \"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"-\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">));</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">console.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"7\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">padStart</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">3</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"0\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">));       </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// \"007\"</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">console.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">`[${</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">raw</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">}]`</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">);                 </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// the original is untouched</span></span></code></pre><div class=\"run-output\" data-run-output=\"5\" hidden></div></div>\n<p>That last line is the key idea: strings are <strong>immutable</strong>. No method ever changes a string; each one returns a new string. If you want to keep the result, store it.</p>\n<aside class=\"callout callout-mistake\" role=\"note\"><p class=\"callout-title\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3\"/><path d=\"M12 9v4\"/><path d=\"M12 17h.01\"/></svg><span><span class=\"callout-kind\">Common mistake</span><span class=\"callout-sep\" aria-hidden=\"true\"> · </span>Calling a method and throwing away the result</span></p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"js\" data-index=\"6\"><div class=\"code-head\"><span class=\"code-title\">JavaScript</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"Copy code\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>Copy</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">let</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> label </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> \"  coffee \"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">;</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">label.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">trim</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">();          </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// returns \"coffee\"... and nobody keeps it</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">label.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">toUpperCase</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">();   </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// same again</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">console.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(label);    </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// still \"  coffee \"</span></span></code></pre></div>\n<p>Write <code dir=\"ltr\">label = label.trim();</code> or, better, store the result under a new <code dir=\"ltr\">const</code>: <code dir=\"ltr\">const cleanLabel = label.trim();</code>.</p>\n</aside>\n<p>Combining methods is common. To capitalise the first letter of a label, take the first character, uppercase it, and add the rest:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"js\" data-run=\"js\" data-index=\"7\"><div class=\"code-head\"><span class=\"code-title\">JavaScript</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn code-run\" data-action=\"run\" data-lang=\"js\" data-index=\"7\" aria-label=\"Run this example\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z\"/></svg><span>Run</span></button><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"Copy code\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>Copy</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">const</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> label</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> \"groceries\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">;</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">const</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> nice</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> label[</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">0</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">].</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">toUpperCase</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">() </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">+</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> label.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">slice</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">1</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">);</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">console.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(nice);</span></span></code></pre><div class=\"run-output\" data-run-output=\"7\" hidden></div></div>\n<p>Two more methods answer “where is it?” rather than “is it there?”. <code dir=\"ltr\">indexOf(&quot;Sam&quot;)</code> returns the index where the text first appears, or <code dir=\"ltr\">-1</code> when it is not there at all. And <code dir=\"ltr\">split(&quot; &quot;)</code> cuts a string into pieces wherever it finds the separator and gives you back a list, <code dir=\"ltr\">[&quot;Coffee&quot;, &quot;with&quot;, &quot;Sam&quot;]</code>. Lists are called arrays, and they get a whole lesson in section 3.</p>\n<h2 id=\"sec-5\" tabindex=\"-1\">Strings and numbers, back and forth</h2>\n<p>Pocket constantly crosses the border between text and numbers. Amounts are numbers while you calculate and strings when you display them; typed input is a string until you convert it.</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"js\" data-run=\"js\" data-index=\"8\"><div class=\"code-head\"><span class=\"code-title\">JavaScript</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn code-run\" data-action=\"run\" data-lang=\"js\" data-index=\"8\" aria-label=\"Run this example\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z\"/></svg><span>Run</span></button><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"Copy code\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>Copy</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">const</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> cents</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 450</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">;</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">console.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">String</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(cents), </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">typeof</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\"> String</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(cents));  </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// number to string</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">console.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">`${</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">cents</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">}`</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">.</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">length</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">);                    </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// a template literal converts too</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">console.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">Number</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"4.50\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">) </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">*</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 100</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">);                 </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// string to number</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">console.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">Number</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"  12 \"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">));                      </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// spaces around digits are ignored</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">console.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">Number</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">));                           </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// careful: an empty string becomes 0</span></span></code></pre><div class=\"run-output\" data-run-output=\"8\" hidden></div></div>\n<p>The last line is a trap worth remembering. An empty text box converts to <code dir=\"ltr\">0</code>, not <code dir=\"ltr\">NaN</code>, so “the user typed nothing” looks exactly like “the user typed zero”. When you validate forms in section 4, you will check for empty input before converting.</p>\n<h2 id=\"sec-6\" tabindex=\"-1\">Comparing strings</h2>\n<p><code dir=\"ltr\">===</code> compares strings character by character, and it is case-sensitive: <code dir=\"ltr\">&quot;Food&quot; === &quot;food&quot;</code> is <code dir=\"ltr\">false</code>. Users type categories however they like, so <strong>normalise before you compare</strong>: trim the spaces and pick one case.</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"js\" data-run=\"js\" data-index=\"9\"><div class=\"code-head\"><span class=\"code-title\">JavaScript</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn code-run\" data-action=\"run\" data-lang=\"js\" data-index=\"9\" aria-label=\"Run this example\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z\"/></svg><span>Run</span></button><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"Copy code\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>Copy</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">const</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> typed</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> \"  Food \"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">;</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">console.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(typed </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">===</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> \"food\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">);                       </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// false</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">console.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(typed.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">trim</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">().</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">toLowerCase</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">() </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">===</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> \"food\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">);  </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// true</span></span></code></pre><div class=\"run-output\" data-run-output=\"9\" hidden></div></div>\n<p>You can also use <code dir=\"ltr\">&lt;</code> and <code dir=\"ltr\">&gt;</code> on strings. They compare character codes one position at a time, which works for simple lowercase words (<code dir=\"ltr\">&quot;apple&quot; &lt; &quot;banana&quot;</code> is true) and goes wrong quickly beyond that: <code dir=\"ltr\">&quot;Zebra&quot; &lt; &quot;apple&quot;</code> is also true, because every uppercase letter has a smaller code than every lowercase one. Section 3 shows the right way to sort text, with <code dir=\"ltr\">localeCompare</code>, which follows the rules of a real language.</p>\n<p>Pocket can now hold amounts, calculate with them exactly and print them in a form people can read. What it cannot do yet is react: warn you when you go over budget, or treat food differently from rent. In the next section your program starts making decisions.</p>\n","toc":[{"id":"sec-1","text":"Writing strings","level":2},{"id":"sec-2","text":"Template literals: values inside text","level":2},{"id":"sec-3","text":"Characters, positions and slices","level":2},{"id":"sec-4","text":"Methods that return new strings","level":2},{"id":"sec-5","text":"Strings and numbers, back and forth","level":2},{"id":"sec-6","text":"Comparing strings","level":2}],"takeaways":["Strings can use single quotes, double quotes or backticks; backticks make template literals, which can insert values with <code dir=\"ltr\">${}</code> and span several lines.","Strings are immutable, so methods like <code dir=\"ltr\">trim()</code> and <code dir=\"ltr\">toUpperCase()</code> return a new string and leave the original unchanged.","Characters are numbered from 0, <code dir=\"ltr\">length</code> counts them, and <code dir=\"ltr\">slice(start, end)</code> copies a piece up to, but not including, <code dir=\"ltr\">end</code>.","Format cents for display with <code dir=\"ltr\">(cents / 100).toFixed(2)</code> or <code dir=\"ltr\">Intl.NumberFormat</code>, and keep the stored amount as a number."],"further":[{"title":"Template literals (MDN)","url":"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals"},{"title":"String (MDN)","url":"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String"},{"title":"Intl.NumberFormat (MDN)","url":"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat"}],"quiz":[{"q":"<p>What does this print?</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"js\" data-index=\"0\"><div class=\"code-head\"><span class=\"code-title\">JavaScript</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"Copy code\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>Copy</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">let</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> label </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> \"  lunch \"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">;</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">label.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">trim</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">();</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">console.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">`[${</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">label</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">}]`</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">);</span></span></code></pre></div>\n","options":[{"text":"<code dir=\"ltr\">[lunch]</code>","why":"<code dir=\"ltr\">trim()</code> returns a new, trimmed string, but nothing stores it, so <code dir=\"ltr\">label</code> still has its spaces."},{"text":"<code dir=\"ltr\">[  lunch ]</code>","why":"Correct. Strings are immutable. Write <code dir=\"ltr\">label = label.trim();</code> to keep the result."},{"text":"<code dir=\"ltr\">[${label}]</code>","why":"Backticks make a template literal, so <code dir=\"ltr\">${label}</code> is replaced by the value of <code dir=\"ltr\">label</code>."}],"answer":1},{"q":"<p><code dir=\"ltr\">const word = &quot;Pocket&quot;;</code> Which expression gives <code dir=\"ltr\">&quot;Poc&quot;</code>?</p>","options":[{"text":"<code dir=\"ltr\">word.slice(1, 3)</code>","why":"Indexes start at 0, so this starts at “o” and stops before index 3, giving “oc”."},{"text":"<code dir=\"ltr\">word.slice(0, 2)</code>","why":"The end index is excluded, so this gives only “Po”."},{"text":"<code dir=\"ltr\">word[0, 3]</code>","why":"Square brackets read a single character. The comma expression evaluates to 3, so this returns “k”."},{"text":"<code dir=\"ltr\">word.slice(0, 3)</code>","why":"Correct. It copies indexes 0, 1 and 2 and stops before 3."}],"answer":3},{"q":"<p>You need to show 1220 cents as <code dir=\"ltr\">$12.20</code>. Which is right?</p>","options":[{"text":"<code dir=\"ltr\">&quot;$&quot; + (1220 / 100).toFixed(2)</code>","why":"Correct. Dividing gives 12.2, and <code dir=\"ltr\">toFixed(2)</code> returns the string “12.20” with exactly two decimals."},{"text":"<code dir=\"ltr\">&quot;$&quot; + 1220 / 100</code>","why":"This prints “$12.2”, because numbers drop trailing zeros when they become text."},{"text":"<code dir=\"ltr\">&quot;$&quot; + 1220.toFixed(2)</code>","why":"That formats the cents, not dollars, and the dot right after an integer literal is a syntax error anyway."}],"answer":0}],"exercise":{"kind":"web","mode":"js","starter":{"js":"// An expense as it arrived from a messy form\nconst rawLabel = \"   coffee with Sam \";\nconst cents = 450;\nconst category = \"FOOD\";\n\n// Build line so it reads exactly: Coffee with Sam: $4.50 (food)\nconst line = rawLabel + \": \" + cents + \" (\" + category + \")\";\nconsole.log(line);\n"},"solution":{"js":"const rawLabel = \"   coffee with Sam \";\nconst cents = 450;\nconst category = \"FOOD\";\n\nconst trimmed = rawLabel.trim();\nconst label = trimmed[0].toUpperCase() + trimmed.slice(1);\nconst price = (cents / 100).toFixed(2);\n\nconst line = `${label}: $${price} (${category.toLowerCase()})`;\nconsole.log(line);\n"},"checks":[{"id":"trimmed","test":"return typeof line === 'string' && line === line.trim() && line.startsWith('C');"},{"id":"price","test":"return typeof line === 'string' && line.includes('$4.50');"},{"id":"exact","test":"return line === 'Coffee with Sam: $4.50 (food)';\n"},{"id":"logged","test":"return logs.some((l) => l === 'Coffee with Sam: $4.50 (food)');\n"}],"title":"Format an expense line","prompt":"<p>An expense arrived from a form with messy text. Build the string <code dir=\"ltr\">line</code> so that it reads exactly <code dir=\"ltr\">Coffee with Sam: $4.50 (food)</code>, then log it. Use the variables: trim <code dir=\"ltr\">rawLabel</code> and capitalise its first letter, show <code dir=\"ltr\">cents</code> as dollars with two decimals, and lowercase <code dir=\"ltr\">category</code>. A template literal keeps this readable.</p>\n","hints":["Start with <code dir=\"ltr\">const trimmed = rawLabel.trim();</code> so the first character is the letter c, not a space.","<code dir=\"ltr\">trimmed[0].toUpperCase() + trimmed.slice(1)</code> capitalises the first letter. <code dir=\"ltr\">(cents / 100).toFixed(2)</code> gives <code dir=\"ltr\">&quot;4.50&quot;</code>.","Put it together with backticks: <code dir=\"ltr\">`${label}: $${price} (${category.toLowerCase()})`</code>."],"explanation":"<p>Each string method returns a new string, so the solution stores each step under its own name: <code dir=\"ltr\">trimmed</code>, then <code dir=\"ltr\">label</code>. Doing the trim first matters, because in the raw text index 0 is a space. <code dir=\"ltr\">toFixed(2)</code> turns <code dir=\"ltr\">4.5</code> into the text <code dir=\"ltr\">&quot;4.50&quot;</code>, which is what people expect to see for money. The template literal then reads almost like the output itself; the first <code dir=\"ltr\">$</code> in <code dir=\"ltr\">$${price}</code> is a literal dollar sign and the second starts the insertion.</p>\n","checkLabels":{"trimmed":"Starts with a capital C and has no stray spaces","price":"Shows the amount as $4.50","exact":"<code dir=\"ltr\">line</code> is exactly “Coffee with Sam: $4.50 (food)”","logged":"Logs the line"}},"words":715,"readMinutes":3}