自定义方法
三种包装对象还可以在原型上添加自定义方法和属性,供原始类型的值直接调用。
比如,我们可以新增一个double方法,使得字符串和数字翻倍。
String.prototype.double = function () {
return this.valueOf() + this.valueOf();
};
'abc'.double()
// abcabc
Number.prototype.double = function () {
return this.valueOf() + this.valueOf();
};
(123).double()
// 246
Boolean对象
Boolean对象除了可以作为构造函数,还可以单独使用,将任意值转为布尔值。这时Boolean就是一个单纯的工具方法。
Boolean(undefined) // false
Boolean(null) // false
Boolean(0) // false
Boolean('') // false
Boolean(NaN) // false
Boolean(1) // true
Boolean('false') // true
Boolean([]) // true
Boolean({}) // true
Boolean(function () {}) // true
Boolean(/foo/) // true
Number对象
Number.prototype.toFixed()
toFixed方法用于将一个数转为指定位数的小数,返回这个小数对应的字符串。
(10).toFixed(2) // "10.00"
10.005.toFixed(2) // "10.01"
上面代码分别将10和10.005转成2位小数的格式。其中,10必须放在括号里,否则后面的点运算符会被处理小数点,而不是表示调用对象的方法;而10.005就不用放在括号里,因为第一个点被解释为小数点,第二个点就只能解释为点运算符。
toFixed方法的参数为指定的小数位数,有效范围为0到20,超出这个范围将抛出RangeError错误。
String对象
concat方法用于连接两个字符串,返回一个新字符串,不改变原字符串。
var s1 = 'abc';
var s2 = 'def';
s1.concat(s2) // "abcdef"
s1 // "abc"
该方法可以接受多个参数。
'a'.concat('b', 'c') // "abc"
、
substring()
substring方法用于从原字符串取出子字符串并返回,不改变原字符串。它与slice作用相同,但有一些奇怪的规则,因此不建议使用这个方法,优先使用slice。
trim()
trim方法用于去除字符串两端的空格,返回一个新字符串,不改变原字符串。
' hello world '.trim()
// "hello world"
该方法去除的不仅是空格,还包括制表符(\t、\v)、换行符(\n)和回车符(\r)。
'\r\nabc \t'.trim() // 'abc'
toLowerCase(),toUpperCase()
toLowerCase方法用于将一个字符串全部转为小写,toUpperCase则是全部转为大写。它们都返回一个新字符串,不改变原字符串。
'Hello World'.toLowerCase()
// "hello world"
'Hello World'.toUpperCase()
// "HELLO WORLD"
这个方法也可以将布尔值或数组转为大写字符串,但是需要通过call方法使用。
String.prototype.toUpperCase.call(true)
// 'TRUE'
String.prototype.toUpperCase.call(['a', 'b', 'c'])
// 'A,B,C'
match()
match方法用于确定原字符串是否匹配某个子字符串,返回一个数组,成员为匹配的第一个字符串。如果没有找到匹配,则返回null。
'cat, bat, sat, fat'.match('at') // ["at"]
'cat, bat, sat, fat'.match('xt') // null
返回数组还有index属性和input属性,分别表示匹配字符串开始的位置和原始字符串。
var matches = 'cat, bat, sat, fat'.match('at');
matches.index // 1
matches.input // "cat, bat, sat, fat"
match方法还可以使用正则表达式作为参数,详见《正则表达式》一节。
search()
search方法的用法等同于match,但是返回值为匹配的第一个位置。如果没有找到匹配,则返回-1。
'cat, bat, sat, fat'.search('at') // 1
search方法还可以使用正则表达式作为参数,详见《正则表达式》一节。
replace()
replace方法用于替换匹配的子字符串,一般情况下只替换第一个匹配(除非使用带有g修饰符的正则表达式)。
'aaa'.replace('a', 'b') // "baa"
replace方法还可以使用正则表达式作为参数,详见《正则表达式》一节。
split()
split方法按照给定规则分割字符串,返回一个由分割出来的子字符串组成的数组。
'a|b|c'.split('|') // ["a", "b", "c"]
Math对象
Math对象提供以下一些数学方法。
Math.abs():绝对值Math.ceil():向上取整Math.floor():向下取整Math.max():最大值Math.min():最小值Math.pow():指数运算Math.sqrt():平方根Math.log():自然对数Math.exp():e的指数Math.round():四舍五入Math.random():随机数
任意范围的随机整数生成函数如下。
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
getRandomInt(1, 6) // 5
get类方法
Date对象提供了一系列get*方法,用来获取实例对象某个方面的值。
getTime():返回距离1970年1月1日00:00:00的毫秒数,等同于valueOf方法。getDate():返回实例对象对应每个月的几号(从1开始)。getDay():返回星期几,星期日为0,星期一为1,以此类推。getYear():返回距离1900的年数。getFullYear():返回四位的年份。getMonth():返回月份(0表示1月,11表示12月)。getHours():返回小时(0-23)。getMilliseconds():返回毫秒(0-999)。getMinutes():返回分钟(0-59)。getSeconds():返回秒(0-59)。getTimezoneOffset():返回当前时间与UTC的时区差异,以分钟表示,返回结果考虑到了夏令时因素。
所有这些get*方法返回的都是整数,不同方法返回值的范围不一样。
需要注意的是,凡是涉及到设置月份,都是从0开始算的,即0是1月,11是12月。
RegExp对象
test()
正则对象的test方法返回一个布尔值,表示当前模式是否能匹配参数字符串。
/cat/.test('cats and dogs') // true
exec()
正则对象的exec方法,可以返回匹配结果。如果发现匹配,就返回一个数组,成员是每一个匹配成功的子字符串,否则返回null。
var s = '_x_x';
var r1 = /x/;
var r2 = /y/;
r1.exec(s) // ["x"]
r2.exec(s) // null
上面代码中,正则对象r1匹配成功,返回一个数组,成员是匹配结果;正则对象r2匹配失败,返回null。
如果正则表示式包含圆括号(即含有“组匹配”),则返回的数组会包括多个成员。第一个成员是整个匹配成功的结果,后面的成员就是圆括号对应的匹配成功的组。也就是说,第二个成员对应第一个括号,第三个成员对应第二个括号,以此类推。整个数组的length属性等于组匹配的数量再加1。
var s = '_x_x';
var r = /_(x)/;
r.exec(s) // ["_x", "x"]
上面代码的exec方法,返回一个数组。第一个成员是整个匹配的结果,第二个成员是圆括号匹配的结果。
exec方法的返回数组还包含以下两个属性:
input:整个原字符串。index:整个模式匹配成功的开始位置(从0开始计数)。
var r = /a(b+)a/;
var arr = r.exec('_abbba_aba_');
arr // ["abbba", "bbb"]
arr.index // 1
arr.input // "_abbba_aba_"
字符串对象的方法
字符串对象的方法之中,有4种与正则对象有关。
match():返回一个数组,成员是所有匹配的子字符串。search():按照给定的正则表达式进行搜索,返回一个整数,表示匹配开始的位置。replace():按照给定的正则表达式进行替换,返回替换后的字符串。split():按照给定规则进行字符串分割,返回一个数组,包含分割后的各个成员。
String.prototype.match()
字符串对象的match方法对字符串进行正则匹配,返回匹配结果。
var s = '_x_x';
var r1 = /x/;
var r2 = /y/;
s.match(r1) // ["x"]
s.match(r2) // null
从上面代码可以看到,字符串的match方法与正则对象的exec方法非常类似:匹配成功返回一个数组,匹配失败返回null。
如果正则表达式带有g修饰符,则该方法与正则对象的exec方法行为不同,会一次性返回所有匹配成功的结果。
var s = 'abba';
var r = /a/g;
s.match(r) // ["a", "a"]
r.exec(s) // ["a"]
String.prototype.search()
字符串对象的search方法,返回第一个满足条件的匹配结果在整个字符串中的位置。如果没有任何匹配,则返回-1。
'_x_x'.search(/x/)
// 1
上面代码中,第一个匹配结果出现在字符串的1号位置。
该方法会忽略g修饰符。
var r = /x/g;
r.lastIndex = 2; // 无效
'_x_x'.search(r) // 1
上面代码中,正则表达式使用g修饰符之后,使用lastIndex属性指定开始匹配的位置,结果无效,还是从字符串的第一个字符开始匹配。
String.prototype.replace()
字符串对象的replace方法可以替换匹配的值。它接受两个参数,第一个是搜索模式,第二个是替换的内容。
str.replace(search, replacement)
搜索模式如果不加g修饰符,就替换第一个匹配成功的值,否则替换所有匹配成功的值。
'aaa'.replace('a', 'b') // "baa"
'aaa'.replace(/a/, 'b') // "baa"
'aaa'.replace(/a/g, 'b') // "bbb"
上面代码中,最后一个正则表达式使用了g修饰符,导致所有的b都被替换掉了。
replace方法的一个应用,就是消除字符串首尾两端的空格。
var str = ' #id div.class ';
str.replace(/^\s+|\s+$/g, '')
// "#id div.class"
RegExp对象
修饰符
修饰符(modifier)表示模式的附加规则,放在正则模式的最尾部。
修饰符可以单个使用,也可以多个一起使用。
(1)g修饰符
默认情况下,第一次匹配成功后,正则对象就停止向下匹配了。g修饰符表示全局匹配(global),加上它以后,正则对象将匹配全部符合条件的结果,主要用于搜索和替换。
var regex = /b/;
var str = 'abba';
regex.test(str); // true
regex.test(str); // true
regex.test(str); // true
上面代码中,正则模式不含g修饰符,每次都是从字符串头部开始匹配。所以,连续做了三次匹配,都返回true。
var regex = /b/g;
var str = 'abba';
regex.test(str); // true
regex.test(str); // true
regex.test(str); // false
上面代码中,正则模式含有g修饰符,每次都是从上一次匹配成功处,开始向后匹配。因为字符串“abba”只有两个“b”,所以前两次匹配结果为true,第三次匹配结果为false。
(2)i修饰符
默认情况下,正则对象区分字母的大小写,加上i修饰符以后表示忽略大小写(ignorecase)。
/abc/.test('ABC') // false
/abc/i.test('ABC') // true
上面代码表示,加了i修饰符以后,不考虑大小写,所以模式abc匹配字符串ABC。
(3)m修饰符
m修饰符表示多行模式(multiline),会修改^和$的行为。默认情况下(即不加m修饰符时),^和$匹配字符串的开始处和结尾处,加上m修饰符以后,^和$还会匹配行首和行尾,即^和$会识别换行符(\n)。
/world$/.test('hello world\n') // false
/world$/m.test('hello world\n') // true
上面的代码中,字符串结尾处有一个换行符。如果不加m修饰符,匹配不成功,因为字符串的结尾不是“world”;加上以后,$可以匹配行尾。
/^b/m.test('a\nb') // true
上面代码要求匹配行首的b,如果不加m修饰符,就相当于b只能处在字符串的开始处。
JSON对象
JSON.stringify()
JSON.stringify方法用于将一个值转为字符串。该字符串符合 JSON 格式,并且可以被JSON.parse方法还原。
如果原始对象中,有一个成员的值是undefined、函数或 XML 对象,这个成员会被过滤。
var obj = {
a: undefined,
b: function () {}
};
JSON.stringify(obj) // "{}"
上面代码中,对象obj的a属性是undefined,而b属性是一个函数,结果都被JSON.stringify过滤。
如果数组的成员是undefined、函数或 XML 对象,则这些值被转成null。
var arr = [undefined, function () {}];
JSON.stringify(arr) // "[null,null]"
上面代码中,数组arr的成员是undefined和函数,它们都被转成了null。
正则对象会被转成空对象。
JSON.stringify(/foo/) // "{}"
JSON.stringify方法会忽略对象的不可遍历属性。
var obj = {};
Object.defineProperties(obj, {
'foo': {
value: 1,
enumerable: true
},
'bar': {
value: 2,
enumerable: false
}
});
JSON.stringify(obj); // "{"foo":1}"
上面代码中,bar是obj对象的不可遍历属性,JSON.stringify方法会忽略这个属性。
JSON.parse()
JSON.parse方法用于将JSON字符串转化成对象。
JavaScript 属性描述对象
JavaScript提供了一个内部数据结构,用来描述一个对象的属性的行为,控制它的行为。这被称为“属性描述对象”(attributes object)。每个属性都有自己对应的属性描述对象,保存该属性的一些元信息。
下面是属性描述对象的一个实例。
{
value: 123,
writable: false,
enumerable: true,
configurable: false,
get: undefined,
set: undefined
}
属性描述对象提供6个元属性。
(1)value
value存放该属性的属性值,默认为undefined。
(2)writable
writable存放一个布尔值,表示属性值(value)是否可改变,默认为true。
(3)enumerable
enumerable存放一个布尔值,表示该属性是否可枚举,默认为true。如果设为false,会使得某些操作(比如for...in循环、Object.keys())跳过该属性。
(4)configurable
configurable存放一个布尔值,表示“可配置性”,默认为true。如果设为false,将阻止某些操作改写该属性,比如,无法删除该属性,也不得改变该属性的属性描述对象(value属性除外)。也就是说,configurable属性控制了属性描述对象的可写性。
(5)get
get存放一个函数,表示该属性的取值函数(getter),默认为undefined。
(6)set
set存放一个函数,表示该属性的存值函数(setter),默认为undefined。
Object.getOwnPropertyDescriptor()
Object.getOwnPropertyDescriptor方法可以读出对象自身属性的属性描述对象。
var o = { p: 'a' };
Object.getOwnPropertyDescriptor(o, 'p')
// Object { value: "a",
// writable: true,
// enumerable: true,
// configurable: true
// }
上面代码表示,使用Object.getOwnPropertyDescriptor方法,读取o对象的p属性的属性描述对象。