JS小册 第一章 数据类型与标准库 字符串

119 阅读10分钟

这是我的第一篇掘金博客,开启掘金写作之路。

  1.定义\n

字符串就是零个或多个排在一起的字符,放在单引号或双引号之中。

\'abc\'
\"abc\"

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

\'key = \"value\"\'
\"It\'s a long journey\"

上面两个都是合法的字符串。

如果要在单引号字符串的内部,使用单引号,就必须在内部的单引号前面加上反斜杠,用来转义。双引号字符串内部使用双引号,也是如此。

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

\"Did she say \\\"Hello\\\"?\"
// \"Did she say \"Hello\"?\"

由于 HTML 语言的属性值使用双引号,所以很多项目约定 JavaScript 语言的字符串只使用单引号,本教程遵守这个约定。当然,只使用双引号也完全可以。重要的是坚持使用一种风格,不要一会使用单引号表示字符串,一会又使用双引号表示。

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

\'a
b
c\'
// SyntaxError: Unexpected token ILLEGAL

上面代码将一个字符串分成三行,JavaScript 就会报错。

如果长字符串必须分成多行,可以在每一行的尾部使用反斜杠。

var longString = \'Long \\
long \\
long \\
string\';

longString
// \"Long long long string\"


  2.字符串与数组\n

字符串可以被视为字符数组,因此可以使用数组的方括号运算符,用来返回某个位置的字符(位置编号从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\"


  3.length 属性\n

length属性返回字符串的长度,该属性也是无法改变的。

var s = \'hello\';
s.length // 5

s.length = 3;
s.length // 5

s.length = 7;
s.length // 5

上面代码表示字符串的length属性无法改变,但是不会报错。



  4.字符串的操作\n


es5 String字符串的操作:

string转arr: 
str.split();    //str.split(\"x\"); \"x\" 表示转换成字符串时分割的符号

查找第几个元素: 
str.charAt();   //没有兼容性问题

查找字符串里面的内容: 
string.indexOf(str[,targetPosition]);  //查找字符串是否包含str,包含则返回第一个下标,否则返回-1

字符串获取: 
str.slice(start,end); //返回从 start 到 end (不包括)之间的字符,可传负值
str.substr(start[,end]);//返回 str 中从指定位置开始到指定长度的子字符串,start可为负值

字符串的替换: 
str.replace(\"old\",\"new\"); //将找出来的\"old\"替换为\"new\"

字符串的查找:
str.search(regexp)

字符串的去空白:
str.trim()

字符串的转小写:
str.toLowerCase()

字符串的转大写:
str.toUpperCase()

es6 的拓展 String字符串的操作:

检测包含特定字符串:
str.includes(\'hello\');

检测头部是否包含特定字符串:
str.startsWith(\'h\');

检测尾部是否包含特定字符串:
str.endsWith(\'o\');

字符串重复n次:
str.repeat(2); //参数是数值类型

字符串头部补全:
str.padStart(10,\'hello\');
// \'hello\' str , 如果不够位数,则缩减\'hello\'字符串
// 如果 \' \' , 参数为空,则以空格补全

字符串尾部补全:
str.padEnd(\'hello\');
// str \'hello\' , 如果不够位数,则缩减\'hello\'字符串
// 如果 \' \' , 参数为空,则以空格补全

补全应用:
\'09-12\'.padStart(10, \'YYYY-MM-DD\');
// YYYY-09-12
  1.数值范围\n

根据标准,64位浮点数的指数部分的长度是11个二进制位,意味着指数部分的最大值是2047(2的11次方减1)。也就是说,64位浮点数的指数部分的值最大为2047,分出一半表示负数,则 JavaScript 能够表示的数值范围为21024到2-1023(开区间),超出这个范围的数无法表示。

如果一个数大于等于2的1024次方,那么就会发生“正向溢出”,即 JavaScript 无法表示这么大的数,这时就会返回Infinity

Math.pow(2, 1024) // Infinity

如果一个数小于等于2的-1075次方(指数部分最小值-1023,再加上小数部分的52位),那么就会发生为“负向溢出”,即 JavaScript 无法表示这么小的数,这时会直接返回0。

Math.pow(2, -1075) // 0


  2.数值的表示法\n

JavaScript 的数值有多种表示方法,可以用字面形式直接表示,比如35(十进制)和0xFF(十六进制)。

数值也可以采用科学计数法表示,下面是几个科学计数法的例子。

123e3 // 123000
123e-3 // 0.123
-3.1E 12
.1e-23

科学计数法允许字母eE的后面,跟着一个整数,表示这个数值的指数部分。

以下两种情况,JavaScript 会自动将数值转为科学计数法表示,其他情况都采用字面形式直接表示。

(1)小数点前的数字多于21位。

1234567890123456789012
// 1.2345678901234568e 21

123456789012345678901
// 123456789012345680000

(2)小数点后的零多于5个。

// 小数点后紧跟5个以上的零,
// 就自动转为科学计数法
0.0000003 // 3e-7

// 否则,就保持原来的字面形式
0.000003 // 0.000003


3.数值的进制\n

使用字面量(literal)直接表示一个数值时,JavaScript 对整数提供四种进制的表示方法:十进制、十六进制、八进制、二进制。

  • 十进制:没有前导0的数值。
  • 八进制:有前缀0o0O的数值,或者有前导0、且只用到0-7的八个阿拉伯数字的数值。
  • 十六进制:有前缀0x0X的数值。
  • 二进制:有前缀0b0B的数值。

默认情况下,JavaScript 内部会自动将八进制、十六进制、二进制转为十进制。下面是一些例子。

0xff // 255
0o377 // 255
0b11 // 3

如果八进制、十六进制、二进制的数值里面,出现不属于该进制的数字,就会报错。

0xzz // 报错
0o88 // 报错
0b22 // 报错

上面代码中,十六进制出现了字母z、八进制出现数字8、二进制出现数字2,因此报错。

通常来说,有前导0的数值会被视为八进制,但是如果前导0后面有数字89,则该数值被视为十进制。

0888 // 888
0777 // 511

前导0表示八进制,处理时很容易造成混乱。ES5 的严格模式和 ES6,已经废除了这种表示法,但是浏览器为了兼容以前的代码,目前还继续支持这种表示法。


  4.正零和负零\n

前面说过,JavaScript 的64位浮点数之中,有一个二进制位是符号位。这意味着,任何一个数都有一个对应的负值,就连0也不例外。

JavaScript 内部实际上存在2个0:一个是 0,一个是-0,区别就是64位浮点数表示法的符号位不同。它们是等价的。

-0 === 0 // true
0 === -0 // true
0 === 0 // true

几乎所有场合,正零和负零都会被当作正常的0

0 // 0
-0 // 0
(-0).toString() // \'0\'
( 0).toString() // \'0\'

唯一有区别的场合是, 0-0当作分母,返回的值是不相等的。

(1 / 0) === (1 / -0) // false

上面的代码之所以出现这样结果,是因为除以正零得到 Infinity,除以负零得到-Infinity,这两者是不相等的(关于Infinity详见下文)。


  5.NaN\n

(1)含义

NaN是 JavaScript 的特殊值,表示“非数字”(Not a Number),主要出现在将字符串解析成数字出错的场合。

5 - \'x\' // NaN

上面代码运行时,会自动将字符串x转为数值,但是由于x不是数值,所以最后得到结果为NaN,表示它是“非数字”(NaN)。

另外,一些数学函数的运算结果会出现NaN

Math.acos(2) // NaN
Math.log(-1) // NaN
Math.sqrt(-1) // NaN

0除以0也会得到NaN

0 / 0 // NaN

需要注意的是,NaN不是独立的数据类型,而是一个特殊数值,它的数据类型依然属于Number,使用typeof运算符可以看得很清楚。

typeof NaN // \'number\'

(2)运算规则

NaN不等于任何值,包括它本身。

NaN === NaN // false

数组的indexOf方法内部使用的是严格相等运算符,所以该方法对NaN不成立。

[NaN].indexOf(NaN) // -1

NaN在布尔运算时被当作false

Boolean(NaN) // false

NaN与任何数(包括它自己)的运算,得到的都是NaN

NaN 32 // NaN
NaN - 32 // NaN
NaN * 32 // NaN
NaN / 32 // NaN


  6.Infinity\n

(1)含义

Infinity表示“无穷”,用来表示两种场景。一种是一个正的数值太大,或一个负的数值太小,无法表示;另一种是非0数值除以0,得到Infinity

// 场景一
Math.pow(2, 1024)
// Infinity

// 场景二
0 / 0 // NaN
1 / 0 // Infinity

上面代码中,第一个场景是一个表达式的计算结果太大,超出了能够表示的范围,因此返回Infinity。第二个场景是0除以0会得到NaN,而非0数值除以0,会返回Infinity

Infinity有正负之分,Infinity表示正的无穷,-Infinity表示负的无穷。

Infinity === -Infinity // false

1 / -0 // -Infinity
-1 / -0 // Infinity

上面代码中,非零正数除以-0,会得到-Infinity,负数除以-0,会得到Infinity

由于数值正向溢出(overflow)、负向溢出(underflow)和被0除,JavaScript 都不报错,所以单纯的数学运算几乎没有可能抛出错误。

Infinity大于一切数值(除了NaN),-Infinity小于一切数值(除了NaN)。

Infinity > 1000 // true
-Infinity < -1000 // true

InfinityNaN比较,总是返回false

Infinity > NaN // false
-Infinity > NaN // false

Infinity < NaN // false
-Infinity < NaN // false

(2)运算规则

Infinity的四则运算,符合无穷的数学计算规则。

5 * Infinity // Infinity
5 - Infinity // -Infinity
Infinity / 5 // Infinity
5 / Infinity // 0

0乘以Infinity,返回NaN;0除以Infinity,返回0Infinity除以0,返回Infinity

0 * Infinity // NaN
0 / Infinity // 0
Infinity / 0 // Infinity

Infinity加上或乘以Infinity,返回的还是Infinity

Infinity Infinity // Infinity
Infinity * Infinity // Infinity

Infinity减去或除以Infinity,得到NaN

Infinity - Infinity // NaN
Infinity / Infinity // NaN

Infinitynull计算时,null会转成0,等同于与0的计算。

null * Infinity // NaN
null / Infinity // 0
Infinity / null // Infinity

Infinityundefined计算,返回的都是NaN


  7.数值的操作\n

es5 String字符串的操作:

数字转换为字符串:
num.toString();

四舍五入为指定小数位数的数字:
num.toFixed(num); //num是规定小数的位数

es6 的拓展 Number数字的操作:

函数用于检查其参数是否是非数字值:
Number.isNaN();

函数用于检查其参数是否为有限的:
Number.isFinite();

函数可解析一个字符串,并返回一个整数:
Number.parseInt();

函数可解析一个字符串,并返回一个浮点数:
Number.parseFloat();