字符串、数字对象

primitive 数据

前面我们学习了 对象和数组。

一个对象(Object)实例数据,比如 {name:'白月黑羽'} ,就是一个对象类型的实例,简称一个对象

一个数组(Array)实例数据,比如 [1,2,3] ,就是一个数组类型的实例,简称一个数组


实际上, Array.prototype 的原型就是 Object.prototype

所以,一个数组数据,它的原型的原型就是 Object.prototype,也可以说是一个对象类型,也可以说是一个对象。


实际上,几乎所有的js数据类型,原型链最终都是 Object.prototype ,所以几乎所有的js数据类型的实例,都可以说是一个 对象

它们都可以使用 Object.prototype 的属性方法,和自身原型的属性方法。


那么我们前面学过的 数字(number)和字符串(string),它们有没有原型呢? 它们是不是对象呢?它们有没有属性和方法呢?

比如下面的 n1,s1

let n1 = 356
let s1 = '您好'

注意:它们是 primitive原语 )数据, 不是对象数据

primitive 数据 没有 属性,底层实现 往往就是 直接对应 存储在内存的 数据

所以非常高效。


primitive数据是不能改变的。

注意:

let n1 = 356
let s1 = '您好'

n1 = 33
s1 = '白月黑羽'

并没有改变原来的 356您好 这两个数据,

而是新建了 33白月黑羽 这两个数据, 让 n1 和 s1 对应这两个新数据。

原来的数据对象没有变量引用,会被js引擎清除掉。



可能有的朋友会说:

不对啊, 前面的教程里就说过,字符串可以有 length 属性,表示长度,还有切片slice方法

var s1 = '你好'
var len = s1.length

既然有属性方法,就不是 primitive,不就是对象吗?


这是因为,js引擎看到这样的代码,

会自动创建一个字符串 封装对象: String

然后调用这个对象的 length属性,就像这样

var len = (new String(s1)).length

所以 s1 变量对应的是一个 字符串 primitive, 而不是对象

如果要定义s1变量 对应一个 字符串对象 ,需要这样写

var s1 = new String("你好");

但是我们不推荐这样做,因为定义为primitive 效率更高。而且 js会自动在需要的时候帮我们产生对象

字符串对象

字符串对象 String 有如下常用的属性方法

length

前面说过, length 属性可以返回字符串对象的长度,也就是包含了多少个字符

'我们今天不去上学,我们去踢足球'.length // 表达式结果是15

indexOf

字符串的 indexOf 方法 和 数组的 indexOf 方法类似,

它用来在字符串中查找 参数字符串,并返回该 参数字符串 在其中 第一个 出现的位置索引

var str1 = '我们今天不去上学,我们去踢足球'

// 返回 0 , str1字符串中有两个 '我们'
// indexOf返回的是第一个 '我们' 的索引 0
var pos1 = str1.indexOf('我们')  

如果字符串对象里面 没有 要查找的参数字符串,就会返回 -1


indexOf 方法 的第二个参数,用来指定 查找起始位置 ,比如

var str1 = '我们今天不去上学,我们去踢足球'

// 第2个参数 5, 表示从 索引 5 的位置开始往后查找
var pos1 = str1.indexOf('我们',5)  

// 返回的是后面 我们 的索引  9
console.log(pos1)

切片 slice

在前面讲数组的切片时讲过

split

js 中的 split 方法 和 Python 中的 字符串 split 方法类似,

split 是我们常用的方法,经常用来从字符串中 截取 出我们想要的信息。

split 方法以参数字符串为分割符 ,将字符串 切割为多个 字符串,作为元素存入一个数组,并返回这个数组。

看看下面的例子

var str1 = '小张:79 | 小李:88 | 小赵:83'
var pos1 = str1.split('|')  

这里 split方法指定用 | 作为源字符串str1的分割符, 这样 原来的字符串 就被分成了 3个部分

小张:79

小李:88

小赵:83

最红将这个三个字符串存入一个数组(数组)中返回,返回的结果就是

[
    '小张:79 ',
    ' 小李:88 ',
    ' 小赵:83'
]

大家要注意,分隔符本身在切割后,会被丢弃掉,所以切割后的字符串中不会有分隔符。


可能有的读者会注意到上面的3个字符串不对齐,

这不是我们的笔误。

原来的字符串,被切开后,分隔符前面有的空格字符,会保留下来。

小张 前面没有空格,所以切割后,切割出来的结果就没有空格。

小李小赵 前面是有空格的,切割出来的结果就有空格


不一定非要用 竖线分割, 我们可以指定任何其他的分隔符来分割字符串,比如

'小张:79 | 小李:88 | 小赵:83'.split('小赵')

这样就是以 小赵 这个字符串为界 ,分割。返回结果如下

[
    '小张:79 | 小李:88 | ',
    ':83'
]

trim、trimStart、trimEnd

trim 方法可以 删除 字符串前面和后面的空白字符,比如空格、tab符, 以及行终结符, 比如回车、换行等等

但是不会删除字符串中间的空白字符。

比如

'      小  李:88       '.trim() 

返回的就是 '小  李:88',去掉了前后的空格,但是中间的空格不会去掉

trimStart 方法 将 字符串前面 (左边) 的空格删除,但是不会删除字符串中间和右边的空格

比如

'      小  李:88       '.trimStart() 

返回的就是 '小  李:88       '

trimEnd 方法 将 字符串后面 (右边) 的空格删除,但是不会删除字符串中间和左边的空格

比如

'      小  李:88       '.trimEnd() 

返回的就是 '      小  李:88'

替换

replace 也是常用的方法,用来 替换 字符串里面 第一个 指定的 子字符串 为另一个 字符串

比如

var str1 = '我们今天不去上学,我们去踢足球';
var str2 = str1.replace('我们', '他们')  ;

注意:是返回值为新的替换后的字符串, 原来的字符串并不会改变

str2 结果就是 '他们今天不去上学,我们去踢足球'


发现了吗? 只有第一个我们被替换,后面的我们没被替换。

js 字符串对象的 replace 方法只 替换第一个 匹配。 和Python不同。


如果想要 替换所有匹配,可以使用先 split 再 join 的方法,像这样

var str1 = '我们今天不去上学,我们去踢足球';
var str2 = str1.split('我们').join('他们');

新版本的浏览器 支持 replaceAll 方法。

replaceAll 方法,用来 替换 字符串里面 所有指定的 子字符串 为另一个 字符串

比如

var str1 = '我们今天不去上学,我们去踢足球'
var str2 = str1.replaceAll('我们', '他们')  

上面的 replaceAll 方法就会把字符串中所有的我们,替换成他们

replaceAll() 方法 支持需要这些版本以后的浏览器: Chrome 85 、FireFox75、Safari 13.1、Node.js 15.0.0

startsWith 和 endsWith

startsWith 方法检查字符串是否以参数指定的字符串 开头,如果是,返回true,否则返回false

endsWith 方法检查字符串是否以指定的字符串 结尾,如果是,返回true,否则返回false

var str1 = '我们今天不去上学,我们去踢足球'
str1.startsWith('我们')  // 返回 true
str1.endsWith('我们')    // 返回 false

字符串模板

前面学过字符串的拼接,比如

var salary = 20000

// 计算出缴税额,存入变量tax
var tax =  salary *25/100  

// 计算出税后薪资,存入变量aftertax
var aftertax = salary*75/100  


console.log( 
  '税前薪资是:' + salary + '元, 缴税:' + tax + '元, 税后薪资是:' + aftertax + '元'
)

字符串的多次拼接比较麻烦,一不小心就可能 漏掉了 一个加号或者引号。

如果我们能够这样写一个模板

税前薪资是 x 元, 缴税:y 元, 税后薪资是:z 元

然后,直接将我们计算好的 税前薪资, 缴税额,税后薪资 分别作为 x, y, z 填入进去。

这样就不需要麻烦的字符串拼接了。


js 支持这样的 字符串模板 操作

就是在字符串使用 反引号 ,然后占位符使用 ${} ,里面直接放入对应的数据对象。

如下所示

`税前薪资是:${salary}元, 缴税:${tax}元, 税后薪资是:${aftertax}元`

运行一下,可以发现输出结果一样。

这种方式是不是更加的直观明了呢?

转义符

我们在代码中定义一个字符串的时候,有些字符是比较特殊的。

比如 换行符, 我们可以用 回车键 敲出来。

var a = `abcd
efg`

其中abcd 和efg之间其实就是有一个 换行字符

有时候像这样的字符出现在字符串中,可以使用转义写法来表示,比如上的字符串就等价于

var a = 'abcd\nefg'
console.log(a)

\n 就是一个转义字符,表示一个换行字符。


除了 \n,还有一些其他的字符可以用转义符表示

比如我们还可以

\t 表示tab字符,

a = 'abcd\tefg'
console.log(a)

\x41 表示 ASCII编码为0x41的字符(也就是字符 A,后面字符编码会学习到 )

a = 'abcd\x41efg'
console.log(a)

\u767d 表示 unicode编码为0x768d的字符(也就是汉字 ,后面字符编码会学习到 )

a = 'abcd\u767defg'
console.log(a)

js字符串中 转义字符都是用反斜杠 \ 开头 。

如果字符串中本身需要有反斜杠,并非转义,比如Windows下面的路径

var path = 'c:\windows\temp'
console.log(path)

其中的 \t 会被当做一个tab字符,而不是 \ 和 t 两个字符。

这时,可以在在前面再加一个反斜杠, 像下面这样

path = 'c:\\windows\\temp'
console.log(path)

也可以 使用反引号 ,在字符前面加上一个 String.raw ,表示字符串内容是raw string, 无需转义,像这样

path = String.raw`c:\windows\temp`
console.log(path)

这种写法术语叫 Tagged template literals

数字对象

数字对象Number 有如下常用的属性方法

parseInt、parseFloat

可以使用 Number 的 parseInt 方法,把字符串表示的数字转化为 整数,

可以使用 Number 的 parseFloat 方法,把字符串表示的数字转化为 数字(整数或小数),

Number.parseInt('34')   // 返回 34
Number.parseInt('34.4') // 还是返回 34
Number.parseFloat('34') // 返回 34
Number.parseFloat('34.4') // 返回 34.4

js 的全局函数 parseInt 就是 Number.parseInt ,

parseFloat 就是 Number.parseFloat

所以可以更简单

parseInt('34')   // 返回 34
parseInt('34.4') // 还是返回 34
parseFloat('34') // 返回 34
parseFloat('34.4') // 返回 34.4

toString

可以使用 Number 的 toString 方法,把字符串表示的数字转化为 整数,

var num = 4545
console.log(num.toString())

// 直接调用数字的方法,需要加括号
(23423.44).toString()

您需要高效学习,找工作? 点击咨询 报名实战班

点击查看学员就业情况