《JavaScript高级程序设计》五、引用类型(基本包装类型)
目录:
Boolean类型
Number类型
String类型
字符方法字符位置方法字符操作方法字符大小转换方法字符串的模式匹配方法
总结XMind图
更多本系列文章点击 :回顾《JavaScript高级程序设计》目录篇
为了方便操作基本类型值,提供3个特殊的引用类型:Boolean、Number、String;这些类型与其他引用类型类似,但是同时具有与各自的基本类型相对应的特殊行为。
实际上每当读取一个基本类型值的时候,后台就会创建一个对应的基本包装类型的对象,让我们能够调用一些方法来操作数据。
例如:
var s1 = "hello fur"var s2 = s1.substring(2) //llo fur
实际上后台运行相当于下面:
var s1 = new String('hello fur')//创建实例var s2 = s1.substring(2) //llo fur 在实例上调用方法s1 = null //销毁这个实例
引用类型与基本包装类型主要区别在于对象的生存期。
引用类型:使用new创建的引用类型的实例,在执行流离开当前作用域之前一直保留在内存中
基本包装类型:自动创建的基本包装类型的对象,则只存在于一行代码执行瞬间,然后立即销毁。这意味着我们不能在运行时为基本类型值添加属性和方法。
例如
var s1 = "hello fur"s1.firstWord = 'h'console.log(s1.firstWord)//undefined
解释:问题在于第二行创建的String对象在执行第三行代码已经被摧毁了,第三行代码有创建了自己的String对象,而该对象没有firstWord属性。
当然,可以显式地调用Boolean、Number、String来创建基本包装类型的对象,但是应该在绝对必要的情况下再这样做,否则容易分不清是基本类型还是引用类型的值。
对基本包装类型的实例调用typeof会返回’object’,而且所以基本包装类型的对象在转换为布尔类型是值都是true。
Object函数也会根据传入值类型返回相应基本包装类型的实例
var obj = new Object('fur')console.log(obj instanceof String)//true
注意,使用new调用基本包装类型的构造函数,与直接调用同名的转型函数不同。
var number = 1var value = undefined//转型函数var num1 = Number(number) var num2 = Number(value) console.log(num1) //1console.log(num2) //NaNconsole.log(typeof (num1)) //numberconsole.log(typeof (num2)) //number//构造函数var objNum = new Object(number) var objVal = new Object(value) console.log(objNum) //[Number: 1]console.log(objVal) //{}console.log(typeof (objNum)) //objectconsole.log(typeof (objVal)) //object
Boolean类型
Boolean类型实例重写了valueOf()方法,返回基本类型true或false,重写toString()返回字符串’true’或’fasle’
由于其极易让人误解,所以不推荐使用。
例如
var falseObj = new Boolean(false)var result = falseObj && trueconsole.log(result)//truevar falseVal = falseresult = falseVal && trueconsole.log(result)//false
解释:我们用false创建一个Boolean对象,由于布尔表达式的所有对象都会被转换为true,所以结果为true。
Number类型
Number是与数字值对应的引用类型。
Number类型重写了valueOf()返回对象表示的基本类型的数值,重写了toLocaleString(),返回字符串形式的数值,重写了toString(),返回字符串形式的数值,同时可以传递一个表示基数的参数,即要求返回几进制数值的字符串形式
var num = 10console.log(typeof (num.valueOf())) //stringconsole.log(num.toLocaleString(8)) //12console.log(num.toLocaleString(16)) //a
除了继承的方法,还有用于将数值格式化为字符串的方法toFixed()、toExponential()、toPrecision()
toFixed()按照指定的小数位返回数值的字符串表示,但是不同浏览器给这个方法的舍入规则可能不同,标准实现的范围是 可以表示0到20个小数位数值,有些浏览器可能支持更多位数
var num = 10console.log(num.toFixed(3)) //10.000
toExponential()返回以指数(e)表示法,表示数字的字符串形式,也接受参数,用处同toFixed()
var num1 = 10var num2 = 1/3console.log(num1.toExponential(3)) //1.000e+1console.log(num2.toExponential(3)) //3.333e-1
toPrecision()得到表示某个数值最合适的格式,接收一个参数,表示数字的所有数字位,不包括指数;典型实现的范围是 可以表示1到21个小数位数值,有些浏览器可能支持的范围更大
var num1 = 10var num2 = 1000000000000console.log(num1.toPrecision(3)) //10.0console.log(num2.toPrecision(2)) //1.0e+12console.log(num2.toPrecision(3)) //1.00e+12
不建议直接实例化Number类型,因为在使用typeof和instanceof操作符测试时会得到不同结果。
String类型
String类型是字符串的对象包装类型,创建方法:
var strObj = new String('fur')
String类型的每个实例都有length属性,表示包含字符串个数,注意即使包含双字节字符(不是占一个字节的ASCII字符),每个字符也仍然算一个字符。
字符方法
用于访问特定字符的方法charAt()charCodeAt()
charAt()以单字符字符串的形式返回给定位置的字符串
charCodeAt()以字符编码的形式返回给定位置的字符串
可以直接用方括号表示法读取
var str = 'farfur-jiang'console.log(str.charAt(1))//aconsole.log(str[1])//aconsole.log(str.charCodeAt(1))//97
字符串位置方法
查找字符串的方法indexOf()和lastIndexOf(),都是从一个字符串中搜索给定子字符串,然后返回子字符串的位置,如果没有找到,则返回-1
区别:indexOf()从字符串开头向后搜索,lastIndexOf()从字符串末尾向前搜索。
var str = 'hello furfur'console.log(str.indexOf('a')) //-1console.log(str.indexOf('f')) //6console.log(str.lastIndexOf('f')) //9
第二个参数,表示从字符串中的哪个位置开始搜索。
var str = 'hello furfur'console.log(str.indexOf('e', 2)) //-1console.log(str.indexOf('f', 7)) //9console.log(str.lastIndexOf('f', 8)) //6
可以循环调用indexOf()或lastIndexOf()来匹配所有子字符串。
var str = 'furfur hello furfur'var arr = new Array()var position = str.indexOf('f')while (position > -1) {arr.push(position)//循环调用indexOf并将起始位置后移一位position = str.indexOf('f', position + 1)}console.log(arr) //[ 0, 3, 13, 16 ]
字符串操作方法
concat()、slice()、substr()、**substring() ** 、trim()
concat()用于将一或多个字符串拼接起来,返回新拼接的字符串,可以接收任意多个参数。不会修改原字符串。
其实也可以用+号拼接。
var str = 'hello'var result1 = str.concat(' fur', '!')var result2 = str + ' fur' + '!'console.log(str) //helloconsole.log(result1) //hello fur!console.log(result2) //hello fur!
slice()、substr()、**substring() ** 这三个方法返回被操作字符串的一个子字符串,而且也接受一或两个参数。第一个参数指定子字符串的开始位置(包括第一位)
区别在于第二个参数:slice()和 **substring() ** 第二个指定的是子字符串的最后一个字符后面的位置(不包括最后一位),substr()第二个参数是返回字符个数。如果没有第二个参数,则字符串的末尾作为结束位置。不会修改原字符串。
var str = 'hello furfur'console.log(str.slice(3)) //lo furfurconsole.log(str.substring(3)) //lo furfurconsole.log(str.substr(3)) //lo furfurconsole.log(str.slice(3,7)) //lo fconsole.log(str.substring(3,7)) //lo fconsole.log(str.substr(3,7)) //lo furf
但是如果传入的参数是负值,情况就会不同很多
slice()的参数如果为负值,就会加上字符串的长度。
substr()的第一个参数为负值会加上字符串的长度,而第二个参数为负值会转换为0。
substring()会把所有参数都转换为0。
var str = 'hello furfur'console.log(str.length)//12console.log(str.slice(-3)) //furconsole.log(str.substring(-3)) //hello furfurconsole.log(str.substr(-3)) //furconsole.log(str.slice(3,-4)) //lo fuconsole.log(str.substr(3,-4)) //helconsole.log(str.substring(3,-4)) // (空字符串)
解释:substr(3,-4)由于第二个参数为负数即变成0,小于前面的,最自动将小的数作为开始,大的数作为结束
substring由于第二个参数为负数即变成0 ,意味着零个字符串,也就是一个空字符串
trim():这个方法会常见一个副本,删除前置及后缀的所有空格,然后返回结果,部分浏览器火狐3.5+,谷歌8+等支持trimLeft和trimRight,分别删除字符串开头和末尾的空格
var str = ' hello furfur 'console.log(str.trim()) //'hello furfur'console.log(str.trimLeft()) //'hello furfur 'console.log(str.trimRight()) //' hello furfur'
字符串大小写转换
toUpperCase、toLocaleUpperCase、转为大写,后者针对特定地区的实现
toLowerCase、toLocaleLowerCase、转为小写,后者针对特定地区的实现
var str = 'hello FUR'console.log(str.toUpperCase()) //HELLO FURconsole.log(str.toLocaleUpperCase()) //HELLO FURconsole.log(str.toLowerCase()) //hello furconsole.log(str.toLocaleLowerCase()) //hello fur
字符串的模式匹配方法
match()、search()、replace ()、split()、localeCompare()、fromCharCode()
match()本质上与RegExp的exec方法相同,只接受一个参数,要么是正则表达式,要么是RegExp对象,返回一个数组,第一项是与模式匹配的字符串,之后的每一项保存着与正则表达式中的捕获组匹配的字符串
var text = 'cat, bat, sat, fur'var pattern = /.at/var matches = text.match(pattern)console.log(matches[0]) //catpattern = /.at/gmatches = text.match(pattern)console.log(matches[0]) //catconsole.log(matches) //[ 'cat', 'bat', 'sat' ]
search()唯一参数同match,返回字符串第一个匹配项的索引,如果没有找到匹配项则返回-1,始终是从字符串开头向后查找模式。
var text = 'cat, bat, sat, fur'var position = text.search(/at/)console.log(position) //1
**replace ()**字符串替换,接受两个参数,第一个可以是RegExp对象或者一个字符串(这个字符串不会被转换成正则表达式),第二个参数可以是一个字符串或者一个函数。
如果第一个参数是字符串,那么只会替换第一个子字符串,要想替换所有子字符串,唯一的办法就是提供指定全局(g)标志的正则表达式。
var text = 'cat, bat, sat, fur'var result = text.replace("at", "ur")console.log(result) //cur, bat, sat, furresult = text.replace(/at/g, 'ur')console.log(result) //cur, bur, sur, fur
如果第二个参数是字符串,还可以使用一些特殊的字符序列(区别于本系列的RegExp篇)
var text = 'cat, bat, sat, fur'var result = text.replace(/(.at)/g, "[$1]")//$n时需要在表达式加括号,不加会变成[$1], [$1], [$1], furconsole.log(result) //[cat], [bat], [sat], furresult = text.replace(/.at/g, "[$']")console.log(result) //[, bat, sat, fur], [, sat, fur], [, fur], fur
第二个参数也可以是函数,在只有一个匹配项是会传递3个参数,1.模式的匹配项,2.模式匹配项在字符串中的位置,3.原始字符串
function htmlEscape(text) {return text.replace(/[<>]/g, function (match, position, originalText) {switch (match) {case '<':return '<';case '>':return '>';}})}console.log(htmlEscape('<p> fur </p>'))//<p> fur </p>
**split()**可以基于指定的分隔符将一个字符串分割成多个子字符串,并将结果放在一个数组中。分隔符可以是字符串,也可以说RegExp对象(这个方法不会将字符串看成正则表达式);接收可选的第二个参数,用于指定数组的大小,以便确保返回的数组不会超过既定大小。
var text = 'cat, bat, sat, fur'console.log(text.split(','))//[ 'cat', ' bat', ' sat', ' fur' ]console.log(text.split(',', 2))//[ 'cat', ' bat' ]console.log(text.split(/[^\,]+/))//[ '', ',', ',', ',', '' ]
最后的一个例子通过使用正则表达式,可以去包含逗号字符的数组,但是注意,第一项和最后一项是两个空字符串,因为通过正则表达式指定的分隔符出现在了字符串的开头和结尾。
localeCompare()比较两个字符串,并返回下列其中一个
如果字符串在字母表中应该排在字符串参数之后,则返回一个正数,一般为1;
如果字符串在字母表中应该排在字符串参数之前,返回一个负数,一般为-1;
如果字符串等于字符串参数,返回0;
var str = 'fur'console.log(str.localeCompare('study')) //-1console.log(str.localeCompare('fur')) //0console.log(str.localeCompare('an')) //1console.log(str.localeCompare('Fur')) //-1
特殊:localeCompare这个方法实现所支持地区决定这个写法的行为,比如应该的大写字母在字母表中排在小写字母前头,但是不同地区可能不同。
**fromCharCode() **: String构造函数本身的一个静态方法,接受一或多个参数,然后转换为字符串,本质上与charCodeAt()相反操作。
console.log(String.fromCharCode(102,117,114))//fur
总结xmid图
更多本系列文章点击 :回顾《JavaScript高级程序设计》目录篇