6.3 直接量的包装对象
直接量所对应的对象叫作包装对象,string、number、boolean所对应的包装对象分别是String对象、Number对象和Boolean对象,它们都是function类型的对象。本节我们就来学习这三个对象。
一个对象最重要的就是它所包含的属性,而function对象的属性又分为两大类,一类是它自身的属性,另一类是它创建的object类型实例对象的属性,创建的实例对象的属性又分为实例自己的属性和function的prototype的属性。
学习function类型对象最重要的是学习两个方面的内容:function作为函数的功能和它对应的属性。对于包装类型的对象来说,作为函数使用时的功能都是将传入的参数转换为function所对应的直接量,例如,使用String("abc");可以新建值为abc的字符串类型的直接量等,其实和不使用函数的效果是一样的,所以学习包装类型对象主要是学习它所对应的属性。包装对象的属性和普通对象的属性没有什么区别,也是一共包括三部分:function对象自身拥有的属性、创建的实例对象所拥有的属性和function的prototype属性对象中的属性。下面我们就从这三个方面分别学习这三个包装对象。
本节的内容以ES5.1为主,ES2015中新增的内容会在后面给大家补充。
6.3.1 String对象
String对象是function类型的对象,对应的是字符串类型,可用来创建字符串类型的object对象,例如,new String("abc");就可以创建一个值为abc的字符串对象。最重要的还是它所对应的三种属性。
1. String自身的属性
String类型自身只有两个属性,一个是prototype,另一个是fromCharCode。对于prototype我们就不再解释了,fromCharCode方法的作用是创建由Unicode值所对应的字符组成的字符串,需要一个或多个参数,例如下面的例子。
var s = String.fromCharCode(97, 98, 99); console.log(s); //abc
在这个例子中,因为97、98、99所对应的Unicode值分别为a、b、c,所以创建出来的字符串s就是abc。
2. String.prototype中的属性
在ES5.1标准中,String的prototype有20个属性,这20个属性在使用String创建出来的object类型对象和字符串直接量中都可以直接使用,分别介绍如下。
▯ constructor:默认指向String对象本身。
▯ toString:因为String的prototype重写了toString方法,所以字符串的toString不会返回[object, Object]或者[object, String]而是返回字符串本身的值。
▯ valueOf:String的prototype也重写了valueOf方法,它会返回字符串本身。
▯ charAt:这个方法用来获取指定位置的字符,序号从0开始,例如下面的例子。
var s = "hello"; console.log(s.charAt(1)); //e
这里获取的是s字符串中序号为1的字符,也就是第二个字符,因此是e。
▯ charCodeAt:这个方法和charAt类似,但它获取的是Unicode值,例如下面的例子。
var s = "hello"; console.log(s.charCodeAt(1)); //101
在这个例子中,因为e的Unicode值为101,所以这里返回的值为101。
▯ concat:这个方法可以将多个字符串连接在一起组成一个新字符串,例如下面的例子。
var s = "hello"; var s1 = s.concat(" ECMAScript", "! "); console.log(s1); //hello ECMAScript!
在这个例子中,concat方法就将字符串s、“ECMAScript”和“! ”连接在一起。需要注意的是,连接之后s并没有发生变化,只是将连接之后的值返回给新的变量s1。
▯ indexOf:这个方法用来查找指定的字符或者字符串,它有两个参数,第一个参数是要查找的字符或字符串;第二个参数可选,代表查找的起始位置,如果省略第二个参数,那么默认会从第一个字符开始查找。如果indexOf方法查找到指定的字符(串),就会返回查找到的第一个字符在字符串中的序号(从0开始);如果找不到就会返回-1。我们来看下面的例子。
var s="prototype"; console.log(s.indexOf("o")); //2 console.log(s.indexOf("ot")); //2 console.log(s.indexOf("ot", 3)); //4 console.log(s.indexOf("a")); //-1
▯ lastIndexOf:这个方法和indexOf的用法一样,不同之处在于:indexOf是从前往后找,而lastIndexOf是从后往前找,并且lastIndexOf的第二个参数position的作用是指定要查找的字符串的结束位置(从0开始计数),例如下面的例子。
var s="prototype"; console.log(s.lastIndexOf("o")); //4 console.log(s.lastIndexOf("o", 3)); //2,在“prot”字符串中查找
▯ localeCompare:这个方法的作用是使用本地化方式比较字符串,类似于>、<的作用,但是,>、<只能依据Unicode编码来比较字符串的大小,而有些地区的字符顺序和Unicode编码并不一样,这时就需要使用localeCompare方法来比较了。如果当前对象比要比较的字符小,则返回一个小于0的数,如果当前对象比要比较的字符大,则返回一个大于0的数,如果当前对象与要比较的字符相同,则返回0,例如下面的例子。
console.log("a".localeCompare("b")); //-1 console.log("b".localeCompare("a")); //1 console.log("a".localeCompare("a")); //0
▯ match:这个方法用于匹配指定的内容,如果传入的参数为字符串,则会匹配字符串,如果传入的参数是正则表达式,则会返回与正则表达式相匹配的内容,例如下面的例子。
console.log("hello JavaScript".match("Script")); //["Script"] console.log("hello JavaScript".match("script")); //null console.log("hello JavaScript".match(/script/i)); //["Script"] console.log("hello JavaScript".match(/a+/g)); //["a", "a"] console.log("hello ECMAScript5.1 and ECMAScript2015".match(/\d+/g)); //["5", "1", "2015"]
如果直接使用字符串匹配,那么是区分大小写的,如果使用正则表达式,则可以使用i(ignore case)标示不区分大小写。还可以使用g(global)标示查找全部符合条件的内容,例如,上述例子中的最后一行代码查找了所有数字。
▯ replace:这个方法用来将字符串中指定的内容替换为新内容,要替换的内容可以是字符串也可以是正则表达式。默认只会替换第一个符合条件的内容,使用正则表达式可以使用g来替换全部符合条件的内容。我们来看个例子。
var s = "beneficial";
console.log(s.replace("e", "E")); //bEneficial console.log(s.replace(/e/, "E")); //bEneficial console.log(s.replace(/e/g, "E")); //bEnEficial console.log(s); //beneficial console.log("pwd:12345".replace(/\d/g, "*")); //pwd:*****
通过这个例子大家就可以明白replace的用法了。需要注意的是,replace并不会修改原来对象的值,而是返回新的对象,例如,这个例子中调用了s.replace("e", "E")之后s的值并没有发生变化。如果需要同时修改s的值,那么可以将返回值再赋值给s,即s =s.replace("e", "E");,这样就可以将替换后的值赋值给s。
▯ search:这个方法的功能类似indexOf方法,不同之处在于:search使用的是正则表达式而不是字符串进行查找,且不能指定起始位置,在正则表达式中也不能使用g标示,返回值和indexOf方法相同,例如下面的例子。
console.log("hello ECMAScript5.1 and ECMAScript2015".search(/\d/)); //16
▯ slice:这个方法用于截取字符串的一部分,它有两个参数,分别表示要截取的字符串的起始位置和结束位置,如果大于0,则从前面计数,如果小于0,则从后面计数,如果省略第二个参数,则会截取到字符串的末尾,例如下面的例子。
var s = "hello ECMAScript5.1 and ECMAScript2015"; console.log(s.slice(6,19)); //ECMAScript5.1 console.log(s.slice(6, -4)); //ECMAScript5.1 and ECMAScript console.log(s.slice(-14, -4)); //ECMAScript console.log(s.slice(0, -14)); //hello ECMAScript5.1 and console.log(s.slice(-14)); //ECMAScript2015
需要注意的是,slice方法也不会改变原来的字符串,同样会返回一个新的字符串。
▯ substring:这个方法和slice类似,也是截取字符串中的一部分,它的两个参数也分别表示字符串的起始位置和结束位置,所不同的是substring中如果结束位置在起始位置之前,则会自动将其调换之后再截取,当参数小于0时会按0处理,例如下面的例子。
console.log("www.excelib.com".substring(4, 11)); //excelib console.log("www.excelib.com".substring(11, 4)); //excelib console.log("www.excelib.com".substring(3, -4)); //www console.log("www.excelib.com".substring(3, 0)); //www console.log("www.excelib.com".substring(4)); //excelib.com
从这个例子可以看出,substring(4, 11)和substring(11, 4)是一样的,substring(3, -4)和substring(3, 0)也是一样的,如果省略第二个参数,则会截取到字符串末尾。
与substring类似的还有一个substr方法,但substr并不是标准里的方法。substr方法也有两个参数,第一个参数也是起始位置,第二个参数表示要截取的长度。如果第一个参数是负数,则会从字符串的后面向前面计数(同slice方法),例如下面的例子。
console.log("www.excelib.com".substr(4, 7)); //excelib
console.log("www.excelib.com".substr(-11, 7)); //excelib console.log("www.excelib.com".substr(-11)); //excelib.com
虽然现在的主流浏览器都对substr方法提供了支持,但是,因为它不是标准里的方法,随时都有可能被舍弃,所以应该尽量少使用它。
▯ split:这个方法用于按照指定分隔符将字符串转换为字符串数组。split方法有两个参数,第一个是分隔符,如果不为空则使用它来分隔字符串,如果为空则按字符分隔字符串;第二个参数可选,表示需要返回数组中元素的个数,如果省略则将分隔后的元素全部返回,例如下面的例子。
var s = "hello ECMAScript5.1 and ECMAScript2015"; console.log(s.split(" ")); //["hello", "ECMAScript5.1", "and", "ECMAScript2015"] s = "是诸法空相不生不灭不垢不净不增不减"; console.log(s.split("不")); //["是诸法空相", "生", "灭", //"垢", "净", "增", "减"] s = "hello张三丰hello老子hello王阳明"; console.log(s.split("hello")); //["", "张三丰", "老子", "王阳明"] console.log("www.excelib.com".split(".")); //["www", "excelib", "com"] console.log("excelib".split("")); //["e", "x", "c", "e", "l", "i", "b"] console.log("excelib".split("", 5)); //["e", "x", "c", "e", "l"]
从这个例子可以看出,split的分隔符不仅可以是英文字符,还可以是字符串甚至汉字。另外,如果字符串起始位置就是分隔符,那么分隔后数组的第一个元素会是空字符串。
▯ toLowerCase:这个方法的作用是将字符串转换为小写形式,例如下面的例子。
console.log("Hello Mick".toLowerCase()); //hello mick
▯ toLocaleLowerCase:这个方法的作用是使用本地语言将字符串转换为小写。有些地区有自己的大小写字符对应规则,在那种环境下就会用到此方法。一般情况下它与toLowerCase的作用一样。
▯ toUpperCase:这个方法的作用是将字符串转换为大写形式,例如下面的例子。
console.log("www.excelib.com".toUpperCase()); //WWW.EXCELIB.COM
▯ toLocaleUpperCase:一般情况下这个方法与toUpperCase相同,只有在具有自己的大小写字符对应规则的地区才会被用到。
▯ trim:这个方法的作用是去掉字符串中头部和尾部的空格,例如下面的例子。
console.log(" hello张三丰 ".trim()); //"hello张三丰"
注意,trim方法只能去掉头部和尾部的空格,而不能去掉字符串中间的空格,如果想去掉字符串中所有的空格,则可以使用replace和正则表达式来操作,例如下面的例子。
console.log(" h e l l o ".replace(/\s+/g, "")); //hello
3. String创建的对象实例的属性
String创建的实例对象一共有两个属性,一个是length属性,它代表字符串的长度;另外一个属性类似于数组,属性名为0到length-1,属性值为序号所对应的字符,例如下面的例子。
var s = "www.excelib.com"; console.log(s.length); //15 console.log(s[7]); //e
使用第二个属性我们就可以把字符串当作字符数组来使用了。
6.3.2 Number对象
Number对象是function类型的对象,对应的是数字类型,可用来创建数字类型的object对象,例如,new Number (123)就可以创建一个值为123的数字实例对象。最重要的依然是它所对应的三种属性。
1. Number自身的属性
Number共有6个属性,如下所示。
▯ prototype:这个属性我们就不再解释了。
▯ MAX_VALUE:用来表示最大的数,其值约为1.7976931348623157×10308。
▯ MIN_VALUE:用来表示最小的数,其值约为5×10-324。
▯ NaN:Not a Number的缩写,表示不是数字。
▯ NEGATIVE_INFINITY:表示负无穷大,一般使用-Infinity来表示。
▯ POSITIVE_INFINITY:表示正无穷大,一般使用Infinity来表示。
下面来看个例子。
console.log(Number("abc")); //NaN console.log(Number.MAX_VALUE); //1.7976931348623157e+308 console.log(Number.MIN_VALUE); //5e-324 console.log(Number.MAX_VALUE*2); //Infinity console.log(-Number.MAX_VALUE*2); //-Infinity console.log(1/0); //Infinity
从这个例子可以看出,将字符串“abc”转换为数字就会产生NaN,最大数乘以2就会产生正无穷大,负最大数乘以2就会出现负无穷大,0做分母也会产生无穷大。
2. Number.prototype的属性
Number的prototype一共有7个属性:constructor、toString、toLocaleString、valueOf、toFixed、toExponential和toPrecision,分别介绍如下。
▯ constructor:这个属性默认指向Number对象本身。
▯ toString:Number的prototype重写了toString方法,重写后的toString方法会返回数字的字符串形式,还可以指定要转换为数字的基数,即指定几进制,默认为十进制。下面来看个例子。
var n = 11; console.log(n.toString()); //11 console.log(n.toString(2)); //1011 console.log( (255).toString(16)); //ff console.log( (0xff).toString()); //255 console.log( (5).toString(2)); //101
▯ toLocaleString:这个方法会按照数字的本地表示法来输出,例如下面的例子。
var n = 2739297; console.log(n.toLocaleString()); //2,739,297 console.log(n.toLocaleString("zh-Hans-CN-u-nu-hanidec")); //二,七三九,二九七
ES5.1标准中的toLocaleString方法并没有参数,但在第6版(ES2015)中规定可以使用参数指定区域,并且现在大部分主流浏览器也都支持。
▯ valueOf:返回数字直接量。下面来看个例子。
var n = new Number(34290); console.log(typeof n); //object console.log(typeof n.valueOf()); //number
因为Number创建的实例对象有自动解包的功能,所以这个方法很少使用。
▯ toFixed:这个方法用来指定数字的精度,即保留几位小数。它的参数为要保留小数的位数,如果不指定则按0处理,即没有小数,并且它会按需要自动进行四舍五入。下面来看个例子。
console.log(837.346.toFixed(2)); //837.35 console.log(837.346.toFixed()); //837 console.log(837.346.toFixed(5)); //837.34600 console.log(-837.346.toFixed(2)); //-837.35 console.log( (3.17e7).toFixed(2)); //31700000.00
▯ toExponential:此方法的作用是将数字转换为科学计数法来表示,有一个可选参数,表示保留小数的位数,如果省略参数,则将输出尽可能多的数字,下面来看个例子。
console.log(24803.5.toExponential()); //2.48035e+4 console.log(24803.5.toExponential(2)); //2.48e+4 console.log(24803.5.toExponential(1)); //2.5e+4
▯ toPrecision:这个方法用于将数字格式化为指定位数(包括整数和小数)。如果指定的位数小于数字的整数部分,那么将使用科学计数法来表示。下面来看个例子。
console.log(49320.34702.toPrecision(7)); //49320.35 console.log(49320.34702.toPrecision(9)); //49320.3470
console.log(49320.34702.toPrecision(3)); //4.93e+4
3. Number创建的实例对象的属性
Number创建的实例对象没有自己的命名属性。
6.3.3 Boolean对象
Boolean对象是function类型的对象,对应的是布尔类型,可用来创建布尔类型的object实例对象。例如,new Boolean (true)就可以创建一个值为true的布尔类型实例对象。Boolean对象非常简单。
1. Boolean自身的属性
Boolean作为对象时自身只有一个prototype属性。prototype我们已经非常熟悉了,这里就不再重述了。
2. Boolean.prototype的属性
Boolean的prototype一共有三个属性:constructor、toString和valueOf。constructor指向Boolean本身,toString和valueOf都返回实例对象的值,但它们的类型不一样,toString返回string类型,而valueOf返回boolean类型。下面来看个例子。
var b = new Boolean(true); console.log(b.toString()); //true console.log(b.valueOf()); //true console.log(typeof b.toString()); //string console.log(typeof b.valueOf()); //boolean console.log(typeof b); //object
3. Boolean创建的对象实例的属性
Boolean创建的对象实例自身不包含命名属性。
多知道点
如何在浏览器中查看对象的属性
本节介绍的包装对象中的属性主要是标准中规定的属性,但不同的浏览器除了实现标准中的属性外,还可能会添加自己特有的属性,我们可以使用Object的getOwnPropertyNames方法来获取当前浏览器中对象自身的所有属性。对于function类型的对象,我们需要获取三种类型的属性:function自身的属性、function.prototype包含的属性以及使用function创建的实例对象自身所包含的属性。这三种属性都可以通过Object的getOwnPropertyNames方法来获取。例如,可以通过下面的代码来获取String对象的三种类型的属性。
console.log(Object.getOwnPropertyNames(String)); //获取String对象自身的属性 console.log(Object.getOwnPropertyNames(String.prototype)); //获取String的prototype的属性 console.log(Object.getOwnPropertyNames(new String())); //获取String创建的对象实例的属性
通过上述方法可以获取当前浏览器中某个具体function对象的相关属性。对于所有function类型的对象都可以使用这个方法,包括Object对象和浏览器中的Window对象。注意Window对象不可以用来创建新的实例对象。