9月阅读周·JavaScript权威指南:类型、值和变量,文本篇
背景
去年下半年,我在微信书架里加入了许多技术书籍,各种类别的都有,断断续续的读了一部分。
没有计划的阅读,收效甚微。
新年伊始,我准备尝试一下其他方式,比如阅读周。每月抽出1~2个非连续周,完整阅读一本书籍。
这个“玩法”虽然常见且板正,但是有效,已经坚持阅读八个月。
已读完书籍:《架构简洁之道》、《深入浅出的Node.js》、《你不知道的JavaScript(上卷)》、《你不知道的JavaScript(中卷)》、《你不知道的JavaScript(下卷)》、《数据结构与算法JavaScript描述》、《WebKit技术内幕》、《前端架构:从入门到微前端》、《秒懂算法:用常识解读数据结构与算法》。
当前阅读周书籍:《JavaScript权威指南》。
文本
JavaScript采用UTF-16编码的Unicode字符集,JavaScript字符串是由一组无符号的16位值组成的序列。最常用的Unicode字符(这些字符属于“基本多语种平面”)都是通过16位的内码表示,并代表字符串中的单个字符,那些不能表示为16位的Unicode字符则遵循UTF-16编码规则——用两个16位值组成的一个序列(亦称做“代理项对”)表示。这意味着一个长度为2的JavaScript字符串(两个16位值)有可能表示一个Unicode字符:
var p="π";//π由16位内码表示0x03c0
var e="e";//e由17位内码表示0x1d452
p.length//=>1:p包含一个16位值
e.length//=>2:e通过UTF-16编码后包含两个16位值:"\ud835\udc52"
JavaScript定义的各式字符串操作方法均作用于16位值,而非字符,且不会对代理项对做单独处理,同样JavaScript不会对字符串做标准化的加工,甚至不能保证字符串是合法的UTF-16格式。
字符串直接量
在JavaScript程序中的字符串直接量,是由单引号或双引号括起来的字符序列。由单引号定界的字符串中可以包含双引号,由双引号定界的字符串中也可以包含单引号。这里有几个字符串直接量的例子:
""//空字符串:它包含0个字符
'testing'
"3.14"
'name="myform"'
"Wouldn't you prefer O'Reilly's book?"
"This string\nhas two lines"
"πis the ratio of a circle's circumference to its diameter"
在ECMAScript 3中,字符串直接量必须写在一行中,而在ECMAScript 5中,字符串直接量可以拆分成数行,每行必须以反斜线(\)结束,反斜线和行结束符都不算是字符串直接量的内容。如果希望在字符串直接量中另起一行,可以使用转义字符\n(后续会有介绍):
"two\nlines"//这里定义了一个显示为两行的字符串
"one\//用三行代码定义了显示为单行的字符串,只在ECMAScript 5中可用
long\
line"
需要注意的是,当使用单引号来定界字符串时,需要格外小心英文中的缩写和所有格写法,比如can't和O'Reilly's。因为撇号和单引号是同一个字符,所以必须使用反斜线(\)来转义(转义符将在下一章讲解)所有的撇号。
在客户端JavaScript程序设计中,JavaScript代码会夹杂HTML代码的字符串,HTML代码也会夹杂JavaScript代码。和JavaScript一样,HTML也使用单引号或者双引号来定界字符串,因此,当JavaScript代码和HTML代码混杂在一起的时候,最好在JavaScript和HTML代码中各自使用独立的引号风格。例如,在JavaScript表达式中使用单引号表示字符串"Thank you",而在HTML事件处理程序属性中则使用双引号表示字符串:
<button onclick="alert('Thank you')">Click Me</button>
转义字符
在JavaScript字符串中,反斜线(\)有着特殊的用途,反斜线符号后加一个字符,就不再表示它们的字面含义了,比如,\n就是一个转义字符(escape sequence),它表示的是一个换行符。
另一个例子是上节中提到的转义字符\',表示单引号(或撇号)。当需要在一个单引号定界的字符串内使用撇号的时候,它就显得非常有用。现在你就会明白我们为什么把它们叫做转义字符了,因为反斜线可以使我们避免使用常规方式解释单引号,当单引号不是用来标记字符串结尾时,它只是一个撇号:
'You\'re right,it can\'t be a quote'
字符串的使用
JavaScript的内置功能之一就是字符串连接。如果将加号(+)运算符用于数字,表示两数相加。但将它作用于字符串,则表示字符串连接,将第二个字符串拼接在第一个之后,例如:
msg="Hello,"+"world";//生成字符串"Hello,world"
greeting="Welcome to my blog,"+""+name;
要确定一个字符串的长度——其所包含的16位值的个数——可以使用字符串的length属性。比如,要得到字符串s的长度:
s.length
除了length属性,字符串还提供许多可以调用的方法(可以在第三部分查到详细信息):
var s="hello,world"//定义一个字符串
s.charAt(0)//=>"h":第一个字符
s.charAt(s.length-1)//=>"d":最后一个字符
s.substring(1,4)//=>"ell":第2~4个字符
s.slice(1,4)//=>"ell":同上
s.slice(-3)//=>"rld":最后三个字符
s.indexOf("l")//=>2:字符l首次出现的位置
s.lastIndexOf("l")//=>10:字符l最后一次出现的位置
s.indexOf("l",3)//=>3:在位置3及之后首次出现字符l的位置
s.split(",")//=>["hello","world"]分割成子串
s.replace("h","H")//=>"Hello,world":全文字符替换
s.toUpperCase()//=>"HELLO,WORLD"
记住,在JavaScript中字符串是固定不变的,类似replace()和toUpperCase()的方法都返回新字符串,原字符串本身并没有发生改变。
在ECMAScript 5中,字符串可以当做只读数组,除了使用charAt()方法,也可以使用方括号来访问字符串中的单个字符(16位值):
s="hello,world";
s[0]//=>"h"
s[s.length-1]//=>"d"
基于Mozilla的Web浏览器(比如Firefox)很久之前就支持这种方式的字符串索引,多数现代浏览器(IE除外)也紧跟Mozilla的脚步,在ECMAScript 5成型之前就支持了这一特性。
模式匹配
JavaScript定义了RegExp()构造函数,用来创建表示文本匹配模式的对象。这些模式称为“正则表达式”(regular expression),JavaScript采用Perl中的正则表达式语法。String和RegExp对象均定义了利用正则表达式进行模式匹配和查找与替换的函数。
RegExp并不是JavaScript的基本类型。和Date一样,它只是一种具有实用API的特殊对象。正则表达式的语法很复杂,API也很丰富。RgeExp是一种强大和常用的文本处理工具。
尽管RegExp并不是语言中的基本数据类型,但是它们依然具有直接量写法,可以直接在JavaScript程序中使用。在两条斜线之间的文本构成了一个正则表达式直接量。第二条斜线之后也可以跟随一个或多个字母,用来修饰匹配模式的含义,例如:
/^HTML///匹配以HTML开始的字符串
/[1-9][0-9]*///匹配一个非零数字,后面是任意个数字
/\bjavascript\b/i//匹配单词"javascript",忽略大小写
RegExp对象定义了很多有用的方法,字符串同样具有可以接收RegExp参数的方法,例如:
var text="testing:1,2,3";//文本示例
var pattern=/\d+/g//匹配所有包含一个或多个数字的实例
pattern.test(text)//=>true:匹配成功
text.search(pattern)//=>9:首次匹配成功的位置
text.match(pattern)//=>["1","2","3"]:所有匹配组成的数组
text.replace(pattern,"#");//=>"testing:#,#,#"
text.split(/\D+/);//=>["","1","2","3"]:用非数字字符截取字符串
总结
字符串(string)是一组由16位值组成的不可变的有序序列,每个字符通常来自于Unicode字符集。JavaScript通过字符串类型来表示文本。字符串的长度(length)是其所含16位值的个数。JavaScript字符串(和其数组)的索引从零开始:第一个字符的位置是0,第二个字符的位置是1,以此类推。空字符串(empty string)长度为0,JavaScript中并没有表示单个字符的“字符型”。要表示一个16位值,只需将其赋值给字符串变量即可,这个字符串长度为1。
作者介绍
非职业「传道授业解惑」的开发者叶一一。
《趣学前端》、《CSS畅想》等系列作者。华夏美食、国漫、古风重度爱好者,刑侦、无限流小说初级玩家。
如果看完文章有所收获,欢迎点赞👍 | 收藏⭐️ | 留言📝。
- 点赞
- 收藏
- 关注作者
评论(0)