首先,思考一个问题:我们定义一个字符串,这个字符串是一个原始值,那么为什么我们可以对其使用方法呢?如下
let a = "ss"
let b = a.substring(2)
答案是: ECMAScript 提供了三种特殊的引用类型 Boolean Number String。每当用到某个原始值的方法或属性时,后台都会创建一个相应原始包装类型的对象。
后台处理实际上经过了如下的过程:
let a = new String("ss") //创建一个String类型实例
let b = a.substring(2) // 调用实例上的方法
a = null // 销毁实例
给原始值添加属性可以吗?也就是定义一个字符串,能给字符串添加属性吗?
let s = "some"
s.name = "test"
console.log(s.name) // undefined
第二行运行会创建一个String对象,但在第三行执行前,已经被销毁了。
第三行也创建了一个String对象,但是没有name属性。
原始包装类的typeof会是什么?
其实这个问题多余问,都是引用类型了。执行typeof 一定是object类型。
看两行代码
let string = new String("ss")
typeof string // object
if(string){
console.log(11)
} // 11
打印了11,说明什么?说明if(string)
括号内的条件是true。所有的原始包装类都会转换为布尔值true。
Boolean(string) //true
因为Object构造函数作为一个工厂方法,可以根据传入的类型返回相应的原始包装类型(下面是用instanceof 检测具体的引用类型,因为typeof对于引用类型的检测都是object,当然除了函数)
let obj = new Object("some")
console.log(obj instanceof String) // true
类型转换
let value = "24"
let number = Number(value)
而如果在前面加一个new关键字,就是构造函数了。
let obj = new Number("24")
typeof obj //object
重写了valueOf(),返回原始数据类型。toString()返回字符串
创建
传入true或false。当然你传入字符串:"true","false"也是可以的,因为他自己会处理。
let bool = new Boolean(true)
let bool1 = new Boolean(false)
很少使用
Boolean对象在ECMAScript中很少使用。
let booleanObj = new Boolean(false)
let result = booleanObj && true // 前面说过Boolean对象都会转为true
console.log(result) // true
一般这种情况下我们都是声明原始值的boolean类型
let falseValue = false
let result = falseValue && true
console.log(result) // false
重写了valueOf()、toLocalString()、toString()方法。
其他方法 之所以原始类型能使用方法,是因为原始包装类型
返回指定小数点位数的数值字符串
let num = 10
console.log(num.toFixed(2)) // "10.00"
如果小数的位数大于 指定的小数位数,则四舍五入
let num = 10.005
console.log(num.toFixed(2)) // "10.01"
对了,这里提一下 一个特殊的求和,好像是计算机二进制上的问题。所有语言执行都会这样
0.1+0.2 = 0.30000000000000004
返回科学计数法表示的数值字符串。参数表示结果中的小数的位数。
一般来说,这么小的数不会使用科学计数法
let num =10
num.toExponential() // "1.0e+1"
根据情况返回最合理的输出结果
let num = 99;
console.log(num.toPrecision(1)); // "1e+2"
console.log(num.toPrecision(2)); // "99"
console.log(num.toPrecision(3)); // "99.0"
ES6新增,用于检测是否是整数。有时候,1.00也会被认为是浮点数
console.log(Number.isInteger(1)) // true
console.log(Number.isInteger(1.0)) // true
console.log(Number.isInteger(1.01)) // false
3个继承的方法
valueOf()、toLocaleString()和 toString()都返回对象的原始字符串值。
length属性
字符串都具有length属性
let str = "hello"
str.length // "5"
找到指定位置的字符
let str = "hello"
console.log(charAt(2)) "l"
查看指定码元的字符编码。Unicode码
"A".charCodeAt() //65
我觉得不是很常用。
用于将一个或多个字符串拼接成一个新字符串,可以接收多个参数。但我们常用的拼接方式都是用 + 加号
let a1 ="bro"
let a2 ="ther"
let a3 = a1.concat(a2,"!") // 'brother!'
let a4 = a1 + a2
都是截取字符串的方法
两个参数
let str = "hello world"
str.slice(3) // "lo world"
str.substring(3) // "lo world"
str.substr(3) // "lo world"
str.slice(3,7) // "lo w" 不包括7位置上的o
str.substring(3,7) // "lo w"
str.substr(3,7) // "lo w"
当参数是负数,就不同了
str.slice(-3) // "rld" 从右侧开始 是-1
str.substr(-3) // "rld" 第一个负参数当成字符串长度+这个值 11 +(-3)= 8 相当于 str.substr(8)
str.substring(-3) // "hello world" 负数被替换为0
str.slice(3,-4) // "lo w"
str.substr(3,-4) // "" 第二个负参数转为0 (3,0)所以是空
str.substring(3,-4) // "hello world"
ES6新增
let str ="start"
str.startsWith("s") // true
str.startsWith("a") // false
str.includes("s") // true
str.includes("srt") // false
startsWith() 和 endsWith() 有第二个参数。
let a = "cat"
a.padStart(6,"!") // '!!!cat' 以补位字符开始
a.padStart(6) // ' cat' 不传第二个参数就是空格
a.padEnd(6,"!") // 'cat!!!' 以补位字符结束
a.padEnd(6) // 'cat '
a.padStart(3) // 'cat' 等于原字符串长度就相当于复制
a.padStart(2) // 'cat' 小于原字符串长度相当于复制
字符串的原型上暴露了一个@@iterator,表示可以迭代字符串的每个字符。
let a = "cat"
let itera = a[Symbol.iterator]
console.log(itera.next()) // {value: 'c', done: false}
console.log(itera.next()) // {value: 'a', done: false}
console.log(itera.next()) // {value: 't', done: false}
console.log(itera.next()) // {value: undefined, done: true} done:true 结束了
解构也是因为这个迭代器才可以实现的
let a ="cat"
console.log([...a]) // ['c', 'a', 't']
地区特定方法和通用方法一样。如不知道代码涉及什么语言,最好使用Local的
let world = "Hello World"
world.toLocaleLowerCase() // 'hello world'
world.toLowerCase() // 'hello world'
world.toLocaleUpperCase() // 'HELLO WORLD'
world.toUpperCase() //'HELLO WORLD'