aboutsummaryrefslogtreecommitdiff
path: root/files/zh-cn/web/javascript/guide/text_formatting/index.html
blob: b0f8b412fe3293846d6ebdabbaadf61341b9de89 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
---
title: Text formatting
slug: Web/JavaScript/Guide/Text_formatting
tags:
  - Guide
  - JavaScript
translation_of: Web/JavaScript/Guide/Text_formatting
---
<div>{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Numbers_and_dates", "Web/JavaScript/Guide/Regular_Expressions")}}</div>

<p class="summary">本章介绍在Javascript中如何使用字符串与文本内容。</p>

<h2 id="字符串">字符串</h2>

<p>JavaScript中的 {{Glossary("String")}} 类型用于表示文本型的数据. 它是由无符号整数值(16bit)作为元素而组成的集合. 字符串中的每个元素在字符串中占据一个位置. 第一个元素的index值是0, 下一个元素的index值是1, 以此类推. 字符串的长度就是字符串中所含的元素个数.你可以通过String字面值或者String对象两种方式创建一个字符串。</p>

<h3 id="String字面量">String字面量</h3>

<p>可以使用单引号或双引号创建简单的字符串:</p>

<pre class="brush: js">'foo'
"bar"</pre>

<p>可以使用转义序列来创建更复杂的字符串:</p>

<h4 id="16进制转义序列">16进制转义序列</h4>

<p>\x之后的数值将被认为是一个16进制数.</p>

<pre class="brush: js">'\xA9' // "©"
</pre>

<h4 id="Unicode转义序列">Unicode转义序列</h4>

<p>Unicode转义序列在\u之后需要至少4个字符.</p>

<pre class="brush: js">'\u00A9' // "©"</pre>

<h4 id="Unicode字元逸出">Unicode字元逸出</h4>

<p>这是ECMAScript 6中的新特性。有了Unicode字元逸出,任何字符都可以用16进制数转义, 这使得通过Unicode转义表示大于<code>0x10FFFF</code>的字符成为可能。使用简单的Unicode转义时通常需要分别写字符相应的两个部分(译注:大于0x10FFFF的字符需要拆分为相应的两个小于0x10FFFF的部分)来达到同样的效果。</p>

<p>请参阅 {{jsxref("String.fromCodePoint()")}} 或 {{jsxref("String.prototype.codePointAt()")}}。</p>

<pre class="brush: js">'\u{2F804}'

// the same with simple Unicode escapes
'\uD87E\uDC04'</pre>

<h3 id="字符串对象">字符串对象</h3>

<p>{{jsxref("String")}} 对象是对原始string类型的封装 .</p>

<pre class="brush: js">const foo = new String('foo'); // 创建一个 String 对象
console.log(foo); // 输出: [String: 'foo']
typeof foo; // 返回 'object'</pre>

<p>你可以在String字面值上使用String对象的任何方法—JavaScript自动把String字面值转换为一个临时的String对象, 然后调用其相应方法,最后丢弃此临时对象.在String字面值上也可以使用String.length属性.</p>

<p>除非必要, 应该尽量使用 String 字面值,因为String对象的某些行为可能并不与直觉一致。举例:</p>

<pre class="brush: js">const firstString = '2 + 2'; //创建一个字符串字面量
const secondString = new String('2 + 2'); // 创建一个字符串对象
eval(firstString); // 返回数字 4
eval(secondString); // 返回包含 "2 + 2" 的字符串对象</pre>

<p><code>String</code> 对象有一个属性 <code>length</code>,标识了字符串中 UTF-16 的码点个数。举例,下面的代码把 13 赋值给了<code>helloLength</code>,因为 "Hello, World!" 包含 13 个字符,每个字符用一个 UTF-16 码点表示。你可以通过数组的方式访问每一个码点,但你不能修改每个字符,因为字符串是不变的类数组对象: </p>

<pre class="brush: js">const hello = 'Hello, World!';
const helloLength = hello.length;
hello[0] = 'L'; // 无效,因为字符串是不变的
hello[0]; // 返回 "H"</pre>

<p>Characters whose Unicode scalar values are greater than U+FFFF (such as some rare Chinese/Japanese/Korean/Vietnamese characters and some emoji) are stored in UTF-16 with two surrogate code units each. For example, a string containing the single character U+1F600 "Emoji grinning face" will have length 2. Accessing the individual code units in such a string using brackets may have undesirable consequences such as the formation of strings with unmatched surrogate code units, in violation of the Unicode standard. (Examples should be added to this page after MDN bug 857438 is fixed.) See also {{jsxref("String.fromCodePoint()")}} or {{jsxref("String.prototype.codePointAt()")}}.</p>

<p><code>String</code>对象有许多方法: 举例来说有些方法返回字符串本身的变体, 如 <code>substring</code><code>toUpperCase</code>.</p>

<p>下表总结了 {{jsxref("String")}} 对象的方法.</p>

<table class="standard-table">
 <caption>
 <h4 id="String对象方法">String对象方法</h4>
 </caption>
 <thead>
  <tr>
   <th scope="col">方法</th>
   <th scope="col">描述</th>
  </tr>
 </thead>
 <tbody>
  <tr>
   <td>{{jsxref("String.charAt", "charAt")}}, {{jsxref("String.charCodeAt", "charCodeAt")}}, {{jsxref("String.codePointAt", "codePointAt")}}</td>
   <td>返回字符串指定位置的字符或者字符编码。</td>
  </tr>
  <tr>
   <td>{{jsxref("String.indexOf", "indexOf")}}, {{jsxref("String.lastIndexOf", "lastIndexOf")}}</td>
   <td>分别返回字符串中指定子串的位置或最后位置。</td>
  </tr>
  <tr>
   <td>{{jsxref("String.startsWith", "startsWith")}}, {{jsxref("String.endsWith", "endsWith")}}, {{jsxref("String.includes", "includes")}}</td>
   <td>返回字符串是否以指定字符串开始、结束或包含指定字符串。</td>
  </tr>
  <tr>
   <td>{{jsxref("String.concat", "concat")}}</td>
   <td>连接两个字符串并返回新的字符串。</td>
  </tr>
  <tr>
   <td>{{jsxref("String.fromCharCode", "fromCharCode")}}, {{jsxref("String.fromCodePoint", "fromCodePoint")}}</td>
   <td>从指定的Unicode值序列构造一个字符串。这是一个String类方法,不是实例方法。</td>
  </tr>
  <tr>
   <td>{{jsxref("String.split", "split")}}</td>
   <td>通过将字符串分离成一个个子串来把一个String对象分裂到一个字符串数组中。</td>
  </tr>
  <tr>
   <td>{{jsxref("String.slice", "slice")}}</td>
   <td>从一个字符串提取片段并作为新字符串返回。</td>
  </tr>
  <tr>
   <td>{{jsxref("String.substring", "substring")}}, {{jsxref("String.substr", "substr")}}</td>
   <td>分别通过指定起始和结束位置,起始位置和长度来返回字符串的指定子集。</td>
  </tr>
  <tr>
   <td>{{jsxref("String.match", "match")}}, {{jsxref("String.replace", "replace")}}, {{jsxref("String.search", "search")}}</td>
   <td>通过正则表达式来工作.</td>
  </tr>
  <tr>
   <td>{{jsxref("String.toLowerCase", "toLowerCase")}}, {{jsxref("String.toUpperCase", "toUpperCase")}}</td>
   <td>
    <p>分别返回字符串的小写表示和大写表示。</p>
   </td>
  </tr>
  <tr>
   <td>{{jsxref("String.normalize", "normalize")}}</td>
   <td>按照指定的一种 Unicode 正规形式将当前字符串正规化。</td>
  </tr>
  <tr>
   <td>{{jsxref("String.repeat", "repeat")}}</td>
   <td>将字符串内容重复指定次数后返回。</td>
  </tr>
  <tr>
   <td>{{jsxref("String.trim", "trim")}}</td>
   <td>去掉字符串开头和结尾的空白字符。</td>
  </tr>
 </tbody>
</table>

<h3 id="多行模板字符串">多行模板字符串</h3>

<p>模板字符串是一种允许内嵌表达式的String字面值. 可以用它实现多行字符串或者字符串内插等特性.</p>

<p>模板字符串使用反勾号 (` `) (<a class="external external-icon" href="https://en.wikipedia.org/wiki/Grave_accent">grave accent</a>) 包裹内容而不是单引号或双引号. 模板字符串可以包含占位符. 占位符用美元符号和花括号标识 (<code>${expression}</code>).</p>

<h4 id="多行">多行</h4>

<p>源代码中插入的任何新行开始字符都作为模板字符串的内容. 使用一般的字符串时, 为了创建多行的字符串不得不用如下语法:</p>

<pre class="brush: js">console.log("string text line 1\n\
string text line 2");
// "string text line 1
// string text line 2"</pre>

<p>为了实现同样效果的多行字符串, 现在可以写成如下形式:</p>

<pre class="brush: js">console.log(`string text line 1
string text line 2`);
// "string text line 1
// string text line 2"</pre>

<h4 id="嵌入表达式">嵌入表达式</h4>

<p>为了在一般的字符串中嵌入表达式, 需要使用如下语法:</p>

<pre class="brush: js">const five = 5;
const ten = 10;
console.log('Fifteen is ' + (five + ten) + ' and not ' + (2 * five + ten) + '.');
// "Fifteen is 15 and not 20."</pre>

<p>现在, 使用模板字符串, 可以使用语法糖让类似功能的实现代码更具可读性:</p>

<pre class="brush: js">const five = 5;
const ten = 10;
console.log(`Fifteen is ${five + ten} and not ${2 * five + ten}.`);
// "Fifteen is 15 and not 20."</pre>

<p>更多信息, 请阅读 <a href="/en-US/docs/Web/JavaScript/Reference">JavaScript reference</a> 中的 <a href="/en-US/docs/Web/JavaScript/Reference/Template_literals">Template literals</a></p>

<h2 id="国际化">国际化</h2>

<p>{{jsxref("Intl")}} 对象是ECMAScript国际化API的命名空间, 它提供了语言敏感的字符串比较,数字格式化和日期时间格式化功能.  {{jsxref("Collator")}}, {{jsxref("NumberFormat")}}, 和 {{jsxref("DateTimeFormat")}} 对象的构造函数是<code>Intl</code>对象的属性.</p>

<h3 id="日期和时间格式化">日期和时间格式化</h3>

<p>{{jsxref("DateTimeFormat")}} 对象在日期和时间的格式化方面很有用. 下面的代码把一个日期格式化为美式英语格式. (不同时区结果不同.)</p>

<pre class="brush: js">const msPerDay = 24 * 60 * 60 * 1000;

// July 17, 2014 00:00:00 UTC.
const july172014 = new Date(msPerDay * (44 * 365 + 11 + 197));//2014-1970=44年
//这样创建日期真是醉人。。。还要自己计算天数。。。11是闰年中多出的天数。。。
//197是6×30+16(7月的16天)+3(3个大月)-2(2月少2天)

const options = { year: "2-digit", month: "2-digit", day: "2-digit",
                hour: "2-digit", minute: "2-digit", timeZoneName: "short" };
const americanDateTime = new Intl.DateTimeFormat("en-US", options).format;

console.log(americanDateTime(july172014)); // 07/16/14, 5:00 PM PDT
</pre>

<h3 id="数字格式化">数字格式化</h3>

<p>{{jsxref("NumberFormat")}} 对象在数字的格式化方面很有用, 比如货币数量值.</p>

<pre class="brush: js">var gasPrice = new Intl.NumberFormat("en-US",
                        { style: "currency", currency: "USD",
                          minimumFractionDigits: 3 });

console.log(gasPrice.format(5.259)); // $5.259

var hanDecimalRMBInChina = new Intl.NumberFormat("zh-CN-u-nu-hanidec",
                        { style: "currency", currency: "CNY" });

console.log(hanDecimalRMBInChina.format(1314.25)); // ¥ 一,三一四.二五
</pre>

<h3 id="定序">定序</h3>

<p>{{jsxref("Collator")}} 对象在字符串比较和排序方面很有用.</p>

<p>举例, 德语中<em>有两种不同的排序方式 电话本(phonebook)</em> 和 字典(<em>dictionary)</em>. 电话本排序强调发音, 比如在排序前 “ä”, “ö”等被扩展为 “ae”, “oe”等发音.</p>

<pre class="brush: js">var names = ["Hochberg", "Hönigswald", "Holzman"];

var germanPhonebook = new Intl.Collator("de-DE-u-co-phonebk");

// as if sorting ["Hochberg", "Hoenigswald", "Holzman"]:
console.log(names.sort(germanPhonebook.compare).join(", "));
// logs "Hochberg, Hönigswald, Holzman"
</pre>

<p>有些德语词包含变音, 所以在字典中忽略变音进行排序是合理的 (除非待排序的单词只有变音部分不同: <em>schon</em> 先于 <em>schön</em>).</p>

<pre class="brush: js">var germanDictionary = new Intl.Collator("de-DE-u-co-dict");

// as if sorting ["Hochberg", "Honigswald", "Holzman"]:
console.log(names.sort(germanDictionary.compare).join(", "));
// logs "Hochberg, Holzman, Hönigswald"
</pre>

<p>关于{{jsxref("Intl")}} API的更多信息, 请参考 <a href="https://hacks.mozilla.org/2014/12/introducing-the-javascript-internationalization-api/">Introducing the JavaScript Internationalization API</a></p>

<div>{{PreviousNext("Web/JavaScript/Guide/Numbers_and_dates", "Web/JavaScript/Guide/Regular_Expressions")}}</div>