JavaScript基础(4)_字符串


字符串是一组由16位值组成的不可变的有序序列,每个字符通常来自于Unicode字符集。
字符串的长度是其所含16位值的个数。
JavaScript字符串的索引从0开始,
空字符串的长度是0.
JavaScript没有表示单个字符的字符型。

一、字符串表示

字符串是由单引号或双引号括起来的零个或多个字符序列。

'abc';
"abc";
'';
"";

单引号字符串内部可使用双引号,双引号字符串内部可使用单引号。

'key="value"';
"It's a small journey.";

如在单引号字符串内部使用单引号,必须使用反斜杠进行转义,双引号字符串内使用双引号也是如此。

'Did she say \'Hello\'?';
"Did she say \"Hello\"?";

※HTML的属性值使用双引号,一般约定JavaScript的字符串使用单引号。

字符串默认只能写在一行内,分成多行会报错。

'one
two';
//SyntaxError: Invalid or unexpected token

ECMAScript 5开始,使用反斜杠(\)可以将字符串拆分成多行。反斜杠和行结束符都不算字符串的内容。
反斜杠后面必须是行结束符,不能是其他字符。

var lines = 'one\
two\
three';
console.log(lines); //onetwothree

连接运算符可连接多个单行字符串,以拆分长字符串。

var longs = "a long "
+ "long "
+ "long "
+ "string.";
console.log(longs); //a long long long string.

如希望字符串另起一行,可使用转义字符:\n。
还有一种利用多行注释的变通方法。

var fun = function() {
   /*
line1
line2
line3
*/};

console.log(fun.toString());
console.log(fun.toString().split('\n').slice(1, -1).join('\n'));

二、转义字符

反斜线后加一个字符,就不再表示它们的字面含义,而是表示一些特殊字符。称为转义字符(escape sequence)。
\o:NUL字符(\u0000)
\b:退格符(\u0008)
\f:换页符(\u000c)
\n:换行符(\u000a)
\r:回车符(\u000d)
\t:水平制表符(\u0009)
\v:垂直制表符(\u000b)
':撇号或单引号(\u0027)
":双引号(\u0022)
\:反斜线(\u005C)
\HHH:反斜杠后面紧跟三个八进制数(000到777)代表一个字符,只能输出256种字符
\xHH:由两位16进制数HH(00~FF)指定的Latin-1字符,只能输出256种字符
\uXXXX 由4位16进制数XXXX(0000到FFFF)指定的Unicode字符
※必须使用小写x和u

console.log('\251');//©
console.log('\xA9');//©
console.log('\XA9');//XA9
console.log('\u00A9');//©
console.log('\U00A9');//U00A9

如在非特殊字符前面使用反斜杠,则反斜杠会省略。

console.log('\a');//a

如在 \u 后面跟上超过了0xFFFF的数值,如:\u20BB7,JavaScript会理解为\u20BB+7,
在ECMAScript 6中,只要将码位放入大括号,就能正确解读该字符。

console.log('\u0061');//a
console.log('\uD842\uDFB7');//?
console.log('\u20BB7');//₻7
console.log('\u{20BB7}');//?
console.log('\u{0061}')//a
console.log('\u{61}')//a

⇒在JavaScript中共有6种方法表示一个字符。

console.log('z');//z
console.log('\z');//z
console.log('\172');//z
console.log('\x7A');//z
console.log('\u007A');//z
console.log('\u{7A}');//z

三、字符集

1.Unicode字符集

JavaScript采用UTF-16编码的Unicode字符集,最常用的Unicode字符都是通过16位(即2个字节,一个编码单元:code unit)的内码表示,并代表字符串中的单个字符。
要为全世界每一个字符提供全球唯一的标识符(又称为码位 code point,从0开始的数值)的话,使用16位是不足以表示如此多的字符的。
表示字符的这些数值或码位,称之为字符编码(character encode)。字符编码必须将码位编码为内部一致的编码单元。
在UTF-16中,前216个码位均以16位的编码单元表示,这个范围称为基本多文种平面(BMP,Basic Multilingual Plane)。
超出这个范围的码位则属于某个辅助平面(supplementary plane),用16位编码单元就无法表示,为此引入了代理对(surrogate pair),其规定用两个16位编码单元表示一个码位。

即字符串里的字符有两种 :

  • 码位在U+0000到U+FFFF之间的,长度为16位(即2个字节)表示的BMP字符;
  • 码点在U+10000到U+10FFFF之间的,长度为32位(即4个字节)表示的辅助平面字符,且前两个字节在0xD800到0xDBFF之间,后两个字节在0xDC00到0xDFFF之间。

对于码位在U+10000到U+10FFFF之间的字符,JavaScript总是认为是两个字符。
也就是说JavaScript返回的字符串长度可能是不正确的。

在ECMAScript 5中,所有字符串操作方法均作用于16位编码单元,而非字符,且不会对代理项对做单独处理,同样JavaScript不会对字符串做标准化的加工,甚至不能保证字符串是合法的UTF-16格式。

2.Base 64转码

一种转码方法,可将任意值转成0-9、a-z、A~Z、+和- 这个64个字符组成的可打印字符。不是为了加密,而是为了不出现特殊字符。
JavaScript提供原生方法:
btoa():任意值转为Base 64编码
atob():Base 64转为原来的值

btoa('Hello'); //"SGVsbG8="
atob("SGVsbG8=");//Hello

※VS Code环境:ng node.js ReferenceError: btoa is not defined,浏览器环境:ok

这两个方法不适合非ASCII码的字符,有错。

要将非ASCII码的字符转为Base 64编码,必须插入一个转码环节,再使用这两个方法。

btoa(encodeURIComponent('你好'));//"JUU0JUJEJUEwJUU1JUE1JUJE"
decodeURIComponent(atob('JUU0JUJEJUEwJUU1JUE1JUJE'));//"你好"

四、模板字面量

ECMAScript 6通过模板字面量填补以下特性

  • 多行字符串:一个正式的多行字符串
  • 基本的字符串格式化:将变量的值嵌入字符串
  • HTML转义:向HTML插入经过安全转换后的字符串

1.基础语法

使用反撇号代替单、双引号,将字符串引起来。如在字符串中使用反撇号,则使用反斜杠进行转义。

let message1 = `Hello world.`;
console.log(message1);//Hello world.
console.log(typeof message1);//string
console.log(message1.length);//12

let message2 = `\`Hello\` "world'.`;
console.log(message2);//`Hello` "world'.
console.log(typeof message2);//string
console.log(message2.length);//16

在模板字面量中,使用单、双引号不需要转义。

2.多行字符串

在ECMAScript 6之前可在一个行的末尾使用反斜杠来创建多行字符串,但打印字符串时并不按跨行方式显示,因为反斜杠只代表行的延续,不代表新的一行。如想输出为新的一行,可加入换行符。(※建议避免使用该方式?)

let lines = 'Multiline \
string';
console.log(lines); //Multiline string

lines = 'Multiline \n\
string';

console.log(lines); 
//Multiline 
//string

通常使用数组或字符串拼接的方式来创建多行字符串。

lines = ['Multiline ', 'string'];
lines.join('\n');

lines = 'Multiline ' + '\n' + 'string';

在模板字面量中直接换行,就可以创建多行字符串。在反撇号之间的所有字符,包括空白字符都属于字符串,要特别小心缩进。
在模板字面量中可显式的使用 \n 插入新行。

lines = `Multiline
string`;

//Multiline
//string
console.log(lines);

//Multiline
//       string
lines = `Multiline
       string`;
console.log(lines);

//Multiline 
//string
lines = `Multiline \nstring`;
console.log(lines);

3.字符串占位符

在模板字面量中,可将任何合法的JavaScript表达式嵌入到占位符中,并将其作为字符串的一部分输出。

占位符由 ${ 和 } 组成,中间可包含任意的JavaScript表达式。

模板字面量可访问作用域中所有可访问的变量,如嵌入一个未定义的变量总是抛出错误,无论严格模式还是非严格模式。

模板字面量本身也可以嵌入另一模板字面量中。

let name = 'Tom',
message = `Hello, ${
     name}.`;

console.log(message);//Hello, Tom.

let count = 10,
price = 0.25;
message = `${
     count} items cost $${
     (count * price).toFixed(2)}`;
//10 items cost $2.50

console.log(message);

name = 'Tom';
message = `Hello ${
     `my name is ${
     name}`}.`;
console.log(message);//Hello my name is Tom.

4.标签模板

标签是在模板字面量第一个反撇号前方标注的字符串。如:

message = tag`Hello world.`;

标签可以是一个函数,调用时传入加工过的模板字面量各个部分数据,但必须结合每个部分来创建结果。
第一个参数是一个数组,包含JavaScript解释过的字面量字符串,之后的参数是每一个占位符的解释值,通常使用不定参数来定义占位符。

function tag(literals, ...substitutions) {
   
       // 返回字符串
}

count = 10,
price = 0.25;
message = passthru`${
     count} items cost $${
     (count * price).toFixed(2)}`;
//10 items cost $2.50

passthru函数接受三个参数,第一个参数是一个数组:第一个占位符前的空字符串("")、第一个占位符和第二个占位符之间的字符串(" items cost $")、第二个占位符之后的字符串(".")

之后的参数是各个占位符的解释值:count:10、(count * price).toFixed(2):2.50。

function passthru(literals, ...substitutions) {
   
       let result = "";

       for (let i = 0; i < substitutions.length; i++) {
   
              result += literals[i];
              result += substitutions[i];
       }

       result += literals[literals.length - 1];

       result += " Good job!";
       return result;
}

console.log(message); //10 items cost $2.50 Good job!

模板标签可访问原生字符串信息,即JavaScript解释之前的字符串,如未转义的转义字符等。
可使用内建的String.raw()标签

message1 = `Multiline\nstring`;
message2 = String.raw`Multiline\nstring`;
console.log(message1);
//Multiline
//string
console.log(message2);//Multiline\nstring

原生字符串信息同样被传入模板标签,标签函数的第一个参数是数组,有一个额外的属性raw,是一个包含每一个字面值的原生等价信息的数组。

function raw(literals, ...substitutions) {
   
       let result = "";

       for (let i = 0; i < substitutions.length; i++) {
   
              // 使用原生值
              result += literals.raw[i];
              result += substitutions[i];
       }

       result += literals.raw[literals.length - 1];

       return result;
}

message = raw`Multiline\nline, \u{20BB7}`;
console.log(message);//Multiline\nline, \u{20BB7}

message = `Multiline\nline, \u{20BB7}`;
console.log(message
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值