[TOC]
## 概述
### 定义
字符串就是若干个排在一起的字符,放在单引号或双引号之中。
~~~
'abc'
"abc"
~~~
单引号字符串的内部,可以使用双引号;双引号字符串的内部,可以使用单引号。
~~~
'key="value"'
"It's a long journey"
~~~
如果要在单引号字符串的内部,使用单引号(或者在双引号字符串的内部,使用双引号),就必须在内部的单引号(或者双引号)前面加上反斜杠,用来转义。
~~~
'Did she say \'Hello\'?'
"Did she say \"Hello\"?"
~~~
字符串默认只能写在一行内,分成多行将会报错。
~~~
'a
b
c'
// SyntaxError: Unexpected token ILLEGAL
~~~
上面代码将一个字符串分成三行,JavaScript就会报错。
如果长字符串必须分成多行,可以在每一行的尾部使用反斜杠。
~~~
var longString = "Long \
long \
long \
string";
longString
// "Long long long string"
~~~
上面代码表示,加了反斜杠以后,原来写在一行的字符串,可以分成多行,效果与写在同一行完全一样。
但是,这种写法有两个注意点,首先,它是ECMAScript 5新添加的,老式浏览器(如IE 8)不支持,其次,反斜杠的后面必须是换行符,而不能有其他字符(比如空格),否则会报错。
连接运算符(+)可以连接多个单行字符串,用来模拟多行字符串。
~~~
var longString = "Long " +
"long " +
"long " +
"string";
~~~
另外,有一种利用多行注释,生成多行字符串的变通方法。
~~~
(function () { /*
line 1
line 2
line 3
*/}).toString().split('\n').slice(1,-1).join('\n')
// "line 1
// line 2
// line 3"
~~~
### 转义
反斜杠在字符串内有特殊含义,用来表示一些特殊字符,所以又称为转义符。
需要用反斜杠转义的特殊字符,主要有下面这些:
* \0 代表没有内容的字符(\u0000)
* \b 后退键(\u0008)
* \f 换页符(\u000C)
* \n 换行符(\u000A)
* \r 回车键(\u000D)
* \t 制表符(\u0009)
* \v 垂直制表符(\u000B)
* \' 单引号(\u0027)
* \" 双引号(\u0022)
* \\ 反斜杠(\u005C)
* \XXX 用三位八进制数(0到377)代表一些特殊符号,比如\251表示版权符号。
* \xXX 用两位十六进制数(00到FF)代表一些特殊符号,比如\xA9表示版权符号。
* \uXXXX 用四位十六进制的Unicode编号代表某个字符,比如\u00A9表示版权符号。
下面是最后三种字符的特殊写法的例子。
~~~
"\251" // "©"
"\xA9" // "©"
"\u00A9" // "©"
~~~
如果非特殊字符前面使用反斜杠,则反斜杠会被省略。
~~~
"\a"
// "a"
~~~
上面代码表示a是一个正常字符,前面加反斜杠没有特殊含义,则反斜杠会被自动省略。
如果字符串的正常内容之中,需要包含反斜杠,则反斜杠前需要再加一个反斜杠,用来对自身转义。
~~~
"Prev \\ Next"
// "Prev \ Next"
~~~
### 字符串与数组
字符串可以被视为字符数组,因此可以使用数组的方括号运算符,用来返回某个位置的字符(从0开始)。
~~~
var s = 'hello';
s[0] // "h"
s[1] // "e"
s[4] // "o"
// 也可以直接对字符串使用方括号运算符
'hello'[1] // "e"
~~~
如果方括号中的数字超过字符串的范围,或者方括号中根本不是数字,则返回undefined。
~~~
'abc'[3] // undefined
'abc'[-1] // undefined
'abc'["x"] // undefined
~~~
但是,字符串与数组的相似性仅此而已。实际上,字符串是类似数组的对象,且无法改变字符串之中的单个字符。
~~~
var s = 'hello';
delete s[0];
s // "hello"
s[1] = 'a';
s // "hello"
s[5] = '!';
s // "hello"
~~~
上面代码表示,字符串内部的单个字符无法改变和增删,这些操作会默默地失败。
length属性返回字符串的长度,该属性也是无法改变的。
~~~
var s = 'hello';
s.length // 5
s.length = 3;
s.length // 5
s.length = 7;
s.length // 5
~~~
上面代码表示字符串的length属性无法改变,但是不会报错。
字符串也无法添加新属性。
~~~
var s = "Hello World";
s.x = 123;
s.x // undefined
~~~
上面代码为字符串s添加了一个x属性,结果无效,总是返回undefined。
上面这些行为的原因是,在JavaScript内部,变量s其实指向字符串“Hello World”的地址,而“Hello World”本身是一个常量,所以无法改变它,既不能新增,也不能删除。另一方面,当一个字符串被调用属性时,它会自动转为String对象的实例(参见《标准库》一章),调用结束后,该对象自动销毁。这意味着,下一次调用字符串的属性时,实际是调用一个临时生成的新对象,而不是上一次调用时生成的那个对象,所以取不到赋值在上一个对象的属性。如果想要为字符串添加属性,只有在它的原型对象String.prototype上定义(参见《面向对象编程》一章)。
## 字符集
JavaScript使用Unicode字符集,也就是说在JavaScript内部,所有字符都用Unicode表示。ECMAScript 3要求使用Unicode 2.1或以上版本,ECMAScript 5则要求使用Unicode 3及以上版本。
不仅JavaScript内部使用Unicode储存字符,而且还可以直接在程序中使用Unicode,所有字符都可以写成"\uxxxx"的形式,其中xxxx代表该字符的Unicode编码。比如,\u00A9代表版权符号。
~~~
var s = '\u00A9';
s // "©"
~~~
每个字符在JavaScript内部都是以16位(即2个字节)的UTF-16格式储存。也就是说,JavaScript的单位字符长度固定为2个字节。
但是需要注意的是,UTF-16有两种长度:对于U+0000到U+FFFF之间的字符,长度为16位(即2个字节);对于U+10000到U+10FFFF之间的字符,长度为32位(即4个字节),而且前两个字节在0xD800到0xDBFF之间,后两个字节在0xDC00到0xDFFF之间。举例来说,U+1D306对应的字符为
- 第一章 导论
- 1.1 前言
- 1.2 为什么学习JavaScript?
- 1.3 JavaScript的历史
- 第二章 基本语法
- 2.1 语法概述
- 2.2 数值
- 2.3 字符串
- 2.4 对象
- 2.5 数组
- 2.6 函数
- 2.7 运算符
- 2.8 数据类型转换
- 2.9 错误处理机制
- 2.10 JavaScript 编程风格
- 第三章 标准库
- 3.1 Object对象
- 3.2 Array 对象
- 3.3 包装对象和Boolean对象
- 3.4 Number对象
- 3.5 String对象
- 3.6 Math对象
- 3.7 Date对象
- 3.8 RegExp对象
- 3.9 JSON对象
- 3.10 ArrayBuffer:类型化数组
- 第四章 面向对象编程
- 4.1 概述
- 4.2 封装
- 4.3 继承
- 4.4 模块化编程
- 第五章 DOM
- 5.1 Node节点
- 5.2 document节点
- 5.3 Element对象
- 5.4 Text节点和DocumentFragment节点
- 5.5 Event对象
- 5.6 CSS操作
- 5.7 Mutation Observer
- 第六章 浏览器对象
- 6.1 浏览器的JavaScript引擎
- 6.2 定时器
- 6.3 window对象
- 6.4 history对象
- 6.5 Ajax
- 6.6 同域限制和window.postMessage方法
- 6.7 Web Storage:浏览器端数据储存机制
- 6.8 IndexedDB:浏览器端数据库
- 6.9 Web Notifications API
- 6.10 Performance API
- 6.11 移动设备API
- 第七章 HTML网页的API
- 7.1 HTML网页元素
- 7.2 Canvas API
- 7.3 SVG 图像
- 7.4 表单
- 7.5 文件和二进制数据的操作
- 7.6 Web Worker
- 7.7 SSE:服务器发送事件
- 7.8 Page Visibility API
- 7.9 Fullscreen API:全屏操作
- 7.10 Web Speech
- 7.11 requestAnimationFrame
- 7.12 WebSocket
- 7.13 WebRTC
- 7.14 Web Components
- 第八章 开发工具
- 8.1 console对象
- 8.2 PhantomJS
- 8.3 Bower:客户端库管理工具
- 8.4 Grunt:任务自动管理工具
- 8.5 Gulp:任务自动管理工具
- 8.6 Browserify:浏览器加载Node.js模块
- 8.7 RequireJS和AMD规范
- 8.8 Source Map
- 8.9 JavaScript 程序测试
- 第九章 JavaScript高级语法
- 9.1 Promise对象
- 9.2 有限状态机
- 9.3 MVC框架与Backbone.js
- 9.4 严格模式
- 9.5 ECMAScript 6 介绍
- 附录
- 10.1 JavaScript API列表
- 草稿一:函数库
- 11.1 Underscore.js
- 11.2 Modernizr
- 11.3 Datejs
- 11.4 D3.js
- 11.5 设计模式
- 11.6 排序算法
- 草稿二:jQuery
- 12.1 jQuery概述
- 12.2 jQuery工具方法
- 12.3 jQuery插件开发
- 12.4 jQuery.Deferred对象
- 12.5 如何做到 jQuery-free?
- 草稿三:Node.js
- 13.1 Node.js 概述
- 13.2 CommonJS规范
- 13.3 package.json文件
- 13.4 npm模块管理器
- 13.5 fs 模块
- 13.6 Path模块
- 13.7 process对象
- 13.8 Buffer对象
- 13.9 Events模块
- 13.10 stream接口
- 13.11 Child Process模块
- 13.12 Http模块
- 13.13 assert 模块
- 13.14 Cluster模块
- 13.15 os模块
- 13.16 Net模块和DNS模块
- 13.17 Express框架
- 13.18 Koa 框架