RYF javascript笔记2
3. 标准库
3.1 Object对象
3.1.1 概述
js提供一个Object对象,所有其他对象都继承自它。
Object本身也是一个构造函数,可以用来生成新对象。它可以接受一个参数。如果该参数是一个对象,则直接返回这个对象;如果是一个原始类型的值,则返回该值对应的包装对象。
var o = new Object(); //与 var o = {} 等价
var o1 = {a:1};
var o2 = new Object(o1);
o1 === o2 // true
new Object(123) instanceof Number // true
在Object对象上面部署方法:
1、部署在Object对象本身
Object.print = function(o){ console.log(o) };
var o = new Object();
Object.print(o); // Object
2、部署在Object.prototype对象
定义在Object.prototype对象上面的属性和方法,将被所有实例对象共享。
Object.prototype.print = function(){ console.log(this)};
var o = new Object();
o.print(); // Object
3.1.2 Object对象的方法
3.1.2.1 Object()
Object()可以将任意值转为对象。
其中,原始类型的值转为对应的包装对象。
对象,则返回原对象。
Object() // 还有Object(undefined)、Object(null) 返回一个空对象
Object(1) // 等同于 new Number(1)
Object('foo') // 等同于 new String('foo')
Object(true) // 等同于 new Boolean(true)
Object([]) // 返回原数组
Object({}) // 返回原对象
Object(function(){}) // 返回原函数
3.1.2.2 Object.keys(),Object.getOwnPropertyNames()
Object.keys方法返回对象可枚举的属性名。
Object.getOwnPropertyNames方法返回对象所有的属性名。
var a = ["Hello", "World"];
Object.keys(a); // ["0", "1"]
Object.getOwnPropertyNames(a); // ["0", "1", "length"]
可以用Object.keys(o).length
得到对象的属性总数。
3.1.2.3 Object.observe() //chrome支持
Object.observe方法用于观察对象属性的变化。
var o = {};
Object.observe(o, function(changes) {
changes.forEach(function(change) {
console.log(change.type, change.name, change.oldValue);
});
});
o.foo = 1; // add, 'foo', undefined
o.foo = 2; // update, 'foo', 1
delete o.foo; // delete, 'foo', 2
3.1.2.4 其他方法
略
3.1.3 Object实例对象的方法
除了Object对象本身的方法,还有不少方法是部署在Object.prototype对象上的,所有Object的实例对象都继承了这些方法。
3.1.3.1 Object.prototype.valueOf()
valueOf方法的作用是返回一个对象的值,默认情况下返回对象本身。
它的主要用途是,自动类型转换时会默认调用这个方法。
var o = new Object();
1 + o // "1[object Object]"
可以用自定义方法覆盖它。
o.valueOf = function (){return 2;};
1 + o // 3
3.1.3.2 Object.prototype.toString()
toString方法的作用是返回一个对象的字符串形式。
数组、字符串和函数都部署了自己的toString方法。
[1,2,3].toString() // "1,2,3"
3.1.3.3 toString()的应用:判断数据类型
{}.toString() // "[object Object]"
上面代码返回一个字符串“object Object”,其中第2个字符串表示该值的准确类型。
实例对象的toString方法,实际上是调用Object.prototype.toString方法。使用call方法,可以在任意值上调用Object.prototype.toString方法,从而帮助我们判断这个值的类型。
var type = function (o){
var s = Object.prototype.toString.call(o);//为什么不直接使用o.toString(),因为数组、字符串和函数都部署了自己的toString方法。null调用toString会报错。
return s.match(/\[object (.*?)\]/)[1].toLowerCase();
};
type({}); // "object"
type([]); // "array"
type(5); // "number"
type(null); // "null"
type(); // "undefined"
type(/abcd/); // "regex"
type(new Date()); // "date"
3.1.4 对象的属性模型
3.1.4.1 属性的attributes对象,Object.getOwnPropertyDescriptor()
每个属性都有一个attributes对象,保存该属性的一些元信息。
var o = { p: 'a' };
Object.getOwnPropertyDescriptor(o, 'p')
// Object { value: "a",
// writable: true,
// enumerable: true,
// configurable: true
// }
enumerable: 表示该属性是否可枚举,默认为true,也就是该属性会出现在for...in和Object.keys()等操作中。
configurable:表示“可配置性”,默认为true。如果设为false,表示无法删除该属性,也不得改变attributes对象(value属性除外)
3.1.4.2 Object.defineProperty(),Object.defineProperties()
可以通过这两个方法定义或修改一个属性,然后返回修改后的对象。
var o = Object.defineProperties({}, {
p1: { value: 123, enumerable: true },
p2: { value: "abc", enumerable: true },
p3: { get: function() { return this.p1+this.p2 },
enumerable:true,
configurable:true
}
});
3.1.4.3 Object.getOwnPropertyNames()
Object.getOwnPropertyNames方法返回直接定义在某个对象上面的全部属性的名称,而不管该属性是否可枚举。
var o = Object.defineProperties({}, {
p1: { value: 1, enumerable: true },
p2: { value: 2, enumerable: false }
});
Object.getOwnPropertyNames(o)
// ["p1", "p2"]
一般来说,系统原生的属性(即非用户自定义的属性)都是不可枚举的。
// 比如,数组实例自带length属性是不可枚举的
Object.keys([]) // []
Object.getOwnPropertyNames([]) // [ 'length' ]
3.1.4.4 Object.prototype.propertyIsEnumerable()
判断一个属性是否可枚举。
o.propertyIsEnumerable("toString") // false
3.1.4.5 可写性(writable)
决定属性的值是否可变。
如果为false,那么修改属性值的时候不会有效果(也不报错)。
var o = Object.defineProperty({}, "a", { value : 37, writable : false });
o.a=88;
console.log(o.a);
3.1.5 控制对象状态
3.1.5.1 Object.preventExtensions方法
使一个对象无法再添加新的属性,但可以delete现有属性。。
var o = {id:1};
Object.preventExtensions(o);
o.name="dgl";
console.log(o.name); // undefined
delete o.id;
3.1.5.2 Object.seal方法
使一个对象既无法添加新属性,也无法删除现有属性。
3.1.5.3 Object.freeze方法
使一个对象无法添加新属性、无法删除现有属性、也无法改变属性的值,使这个对象实际上变成了常量。
3.1.5.3 局限性
上面这些方法锁定对象的可写性,但是依然可以通过改变该对象的原型对象,来为它增加属性。
解决方案是,把原型也冻结住。
3.2 Array 对象
3.2.1 概述
Array的构造函数行为很不一致,因此不建议使用Array创建新数组。
3.2.2 Array对象的静态方法
3.2.2.1 isArray方法
Array.isArray方法用来判断一个值是否为数组。它可以弥补typeof运算符的不足。
var a = [1,2,3];
typeof a // "object"
Array.isArray(a) // true
3.2.3 Array对象实例的方法
以下这些Array对象实例的方法,都是数组实例才能使用。如果不想创建实例,只是想单纯调用这些方法,可以写成 [].method.call(调用对象,参数) 的形式,或者 Array.prototype.method.call(调用对象,参数)的形式。
3.2.3.1 ivalueOf方法,toString方法
-
valueOf方法返回数组本身。
-
toString 方法返回数组的字符串形式。
var a = [1,2,3];
a.valueOf()// [1,2,3]
a.toString()// "1,2,3"
3.2.3.2 push方法,pop方法
- push方法 在数组的末端添加一个或多个元素,并返回添加后的数组的长度。
- push方法还可以用于向对象添加元素,新加入元素的键对应数组的索引,并且对象有一个length属性。
- pop方法 删除数组的最后一个元素,并返回该元素。
对空数组使用pop方法,不会报错,而是返回undefined。 - 合并两个数组 Array.prototype.push.apply
示例:
var a = new Array();
var b = {id:123};
a.push(1) // 1
a.push("a",true) // 3
console.log(a); // [1,"a",true]
[].push.call(b, 'yy');
console.log(b); // {0: "yy", id: 123, length: 1}
a.pop() // true
console.log(a);// [1,"a"]
[].pop() // undefined
Array.prototype.push.apply(a, b);
console.log(a); // [1, "a", "yy"]
3.2.3.3 join方法,concat方法
- join方法 将所有数组成员组成一个字符串返回。如果不提供参数,默认用逗号分隔。
- concat方法 连接多个数组。
示例:
var a = [1,2,3,4];
a.join() // "1,2,3,4"
a.join('') // '1234'
Array.prototype.join.call(a, '-') // "1-2-3-4"
a.concat(["world"]) // [1, 2, 3, 4, world]
3.2.3.4 shift方法,unshift方法
shift 删除数组的第一个元素,并返回该元素。
unshift 在数组的第一个位置添加元素,并返回数组长度。
var list = ['a','b','c'];
console.log(list.shift()); // a
console.log(list.unshift(0)); // 3
console.log(list); // [0, "b", "c"]
3.2.3.5 reverse方法
反转
var a = ['a', 'b', 'c'];
a.reverse() // ["c", "b", "a"]
3.2.3.6 slice方法
1、作用相当于substring。
第一个参数为起始位置(从前往后,0开始;从后往前,-1开始),
第二个参数为终止位置(但不包括该位置的元素)
参数是负数,表示从后向前排序;
第一个参数值大于数组成员的个数,或者第二个参数小于第一个参数,则返回空数组。
var a = ["a","b","c"];
a.slice(1,2) // ["b"]
a.slice() // ["a","b","c"]
a.slice(-2) // ["b", "c"]
a.slice(-2,-1) // ["b"]
a.slice(-2,0) // []
a.slice(-2,1) // []
a.slice(-2,2) // ["b"]
a.slice(4) // []
a.slice(2, 6) // ["c"]
2、将类似数组的对象转为真正的数组。
Array.prototype.slice.call({ 0: 'a', 1: 'b', length: 2 }) // ['a', 'b']
Array.prototype.slice.call(document.querySelectorAll("div"));
3.2.3.7 splice方法
splice方法用于删除元素,并可添加新元素。返回值是被删除的元素。
第一个参数是删除的起始位置,
第二个参数是被删除的元素个数(可以为0)。
更多的参数表示要被插入数组的新元素。
var a = ["a","b","c"];
a.splice(1,1) // ["b"] a变为["a","c"]
a.splice(1,0,'X') // ["b"] a变为["a","X","c"]
a.splice(1,2,9,8) // ["b"] a变为["a",9,8]
3.2.3.8 sort方法
排序,默认是按照字典顺序排序。排序后,原数组将被改变。
可以接受一个参数,表示按照自定义方法进行排序。
var list=[3,2,5];
list.sort(); // 2,3,5
list.sort(funtion(a,b){
return b-a;
}); // 5,3,2
3.2.4 ECMAScript 5 新加入的数组方法
map、forEach、filter、every、some、reduce、reduceRight与函数式操作有关。它们可以在数组或类似数组的对象上使用。
其参数是一个函数,这个函数本身又接受三个参数:数组的当前元素elem、该元素的位置index和整个数组arr。
另外,上下文对象(context)可以作为第二个参数,传入forEach(), every(), some(), filter(), map()方法,用来绑定函数运行时的上下文。
3.2.4.1 map方法,forEach方法
//map方法对数组的每个元素执行一个函数,所有结果返回一个新数组。
var a = [1, 2, 3]
var a2 = a.map(function(elem, index, arr){
return elem + elem;
});
console.log(a); //[1, 2, 3]
console.log(a2); //[2, 4, 6]
//通过call方法可以将map用在类似数组的对象上。
var b = [].map.call("abc", function(elem, index, arr){
return elem + elem;
});
console.log(b); //["aa", "bb", "cc"]
//forEach和map类似,区别是不返回新数组(可以改变原数组的值)。
var c = [1, 2, 3];
var c2 = c.forEach(function(elem, index, arr){
arr[index] = elem * index;
return elem;
});
console.log(c); //[0, 2, 6]
console.log(c2); //undefined
//还可以接受第二个参数,用来绑定函数中的this关键字。
[1, 2, 3].map(function(elem, index, arr){
this.push(elem * elem); //this指向out变量
}, out);
3.2.4.2 filter方法
filter对所有成员调用一个函数,所有结果为true的成员组成一个新数组返回。(c#的Where)
[1,2,3,4,5].filter(function(elem){
return (elem>3);
})
// [4,5]
filter方法还可以有两个可选参数index、arr,分别是当前数组成员的位置和整个数组。
[1, 2, 3, 4, 5].filter(function(elem, index, arr){
return index % 2 === 0;
});
// [1, 3, 5]
3.2.4.3 some方法,every方法
some 判断是否存在满足条件的元素。
[1, 2, 3, 4, 5].some(function(elem, index, arr){
return elem >= 3;
});
// 返回true
every 判断是否所有元素都满足条件。
[1, 2, 3, 4, 5].every(function(elem, index, arr){
return elem >= 3;
});
// 返回false
3.2.4.4 reduce方法(归约),reduceRight方法
reduce 依次处理数组的每个元素,最终累计为一个值。(c#的Aggregate)
[1, 2, 3, 4, 5].reduce(function(x, y,index,arr){
console.log(index); //跳过0,直接从1开始
return x*y;
});
//120
可以对对累计变量指定初值。(和Aggregate一样)
reduceRight就是从右向左执行reduce。
[1, 2, 3, 4, 5].reduceRight(function(x, y){
return x+y;
}, '---');
// ---54321
3.2.4.5 indexOf 和 lastIndexOf
indexOf方法返回给定元素在数组中第一次出现的位置,如果没有出现则返回-1。
lastIndexOf找最后一个。
['aa','bb','cc'].indexOf('b') //-1
['aa','bb','cc'].indexOf('bb') //1
3.2.4.6 链式使用
如果返回值依然是数组,当然就可以链式使用了。比如:map、forEach、filter
3.3 包装对象和Boolean对象
3.3.1 包装对象
可以将原始类型的值(数值、字符串、布尔值)变成对象,这就是“包装对象”。
var v1 = new Number(123);
var v2 = new String("abc");
var v3 = new Boolean(true);
typeof v1 // "object"
v1 === 123 // false
包装对象使原始类型也可以调用Object的原生方法。
3.3.1.1 包装对象的构造函数
Number、String和Boolean这三个原生对象有两种用。
1、构造函数
2、方法(相当于生成实例后再调用valueOf方法)
new Number(123); //[object Number]
Number(123); //123
3.3.1.2 包装对象实例的方法
1、valueOf
返回对应的原始类型的值。
new Boolean("true").valueOf()
// true
2、toString
返回对应的原始类型值的字符串形式。
new Boolean("true").toString()
// "true"
3.3.1.3 原始类型的自动转换
原始类型可以自动调用定义在其包装对象上的方法和属性。
包括三个包装对象各自定义在实例上的方法。
"abc".length // 3
'abc'.charAt === String.prototype.charAt // true
实质是字符串被JavaScript引擎自动转为String对象的实例,然后调用这个实例的length属性。得到返回值后,再自动销毁这个临时的包装对象实例。
自定义方法
还可以在原型上添加自定义方法和属性。
String.prototype.double = function (){
return this.valueOf() + this.valueOf();
};
"abc".double() // abcabc
但是,这种自定义方法和属性的机制,只能定义在包装对象的原型上,想要直接对原始类型的变量添加属性,则无效。
var s = "abc";
s.p = 123;
s.p // undefined
3.3.2 Boolean对象
3.3.2.1 构造函数
用于生成布尔值的包装对象的实例。
var b = new Boolean(true);
typeof b // "object"
b.valueOf() // true
3.3.2.2 工具方法
将任意值转为布尔值。
(undefined、null、+0、-0、''、NaN为false,其它都是true)
使用not运算符(!)也可以达到同样效果。
var a = "false";
new Boolean(a).valueOf() // true
Boolean(a) // true
!!a // true
注意:对象被自动类型转换为布尔时,结果都是true。
if (Boolean(false))
console.log('true'); // 无输出
if (new Boolean(false))
console.log('true'); // true
3.3.3 Number对象
3.3.3.1 构造函数
var n = new Number(1);
typeof n // "object"。
3.3.3.2 工具方法
请看“数据类型转换”
3.3.3.3 Number对象的属性
正无限(POSITIVE_INFINITY)
负无限(NEGATIVE_INFINITY)
NaN
MAX_VALUE
MIN_VALUE
3.3.3.4 Number对象实例的方法
1、Number.prototype.toString()
Number对象有单独的toString方法,它可以接受一个参数(表示进制)。
(3).toString() // "3"
(3).toString(2) // "11"
3.toString(2) // SyntaxError //JavaScript引擎解释成小数点
3..toString(2) // "11" //两个点就会理解成调用对象属性
3.5.toString() // "3.5" //可以直接对一个小数使用toString方法
3['toString'](2) // "11" //通过方括号运算符也可以调用toString方法。
将其他进制的数,转回十进制,需要使用parseInt方法。
2、Number.prototype.toFixed()
将一个数转为指定位数的小数。
(3).toFixed(2)// "3.00"
(3.005).toFixed(2)// "3.01"
3、Number.prototype.toExponential()
将一个数转为科学计数法形式。
(10).toExponential(1)// "1.0e+1"
(1234).toExponential(1)// "1.2e+3"
4、Number.prototype.toPrecision()
将一个数转为指定位数的有效数字。
(12.34).toPrecision(1)// "1e+1"
(12.34).toPrecision(2)// "12"
(12.34).toPrecision(3)// "12.3"
(12.34).toPrecision(5)// "12.340"
toPrecision方法用于四舍五入时不太可靠
5、自定义方法
同样,Number.prototype对象上面可以自定义方法,被Number的实例继承。
Number.prototype.add = function (x) {
return this + x;
};
(8).add(2) // 10
3.3.4 String
3.3.4.1 构造函数
var s = new String("abc");
typeof s // "object"
3.3.4.2 工具方法
String(true) // "true"
String(5) // "5"
3.3.4.3 String.fromCharCode()
该方法根据Unicode编码,生成一个字符串。
String.fromCharCode(104, 101, 108, 108, 111)
// "hello"
注意,该方法不支持编号大于0xFFFF的字符。这种情况下,只能使用四字节的UTF-16编号。
String.fromCharCode(0xD842, 0xDFB7)
// "𠮷"
3.3.4.4 实例对象的属性和方法
1、length属性
返回字符串的长度。
2、charAt 和 charCodeAt 方法
- charAt返回字符串指定位置的字符。
- charCodeAt方法返回给定位置字符的Unicode编码(十进制表示)。
- 如果给定位置为负数,或者过大,则这两个方法返回NaN(或"")。
示例:
"abc".charAt(1) // "b"
"abc".charAt(-1) // ""
"abc".charAt(3) // ""
"abc".charCodeAt(1) // 98
"abc".charCodeAt(-1) // NaN
"abc".charCodeAt(3) // NaN
chatAt可以用下标代替:
"abc"[1] // "b"
注意:如果遇到Unicode大于65536的字符(即第一个字节在U+D800到U+DBFF之间),就要连续使用两次charCodeAt。
"张".charCodeAt(0) // 23534
"张".charCodeAt(1) // 65533
3、concat方法
连接多个字符串(原来的字符串不受影响)。
"a".concat("bb") // abb
"a".concat("bb","c") // abbc
其实字符串连接用加号(+)就好。
4、substring方法,substr方法和slice方法
- substring(a,b) 取从a到b(不包括b)位置的子串。如果a小于b,则两个参数互换。
- slice(a,b) 和substring唯一不同是,如果a小于b,两个参数不互换,返回空字符串。
- substr(a,b) 取从a开始长度为b的子串。
示例:
var s = "abcde";
s.substring(2, 3); // "c"
s.substring(3, 2); // "c"
s.slice(2, 3); // "c"
s.slice(3, 2); // ""
s.substr(2, 3); // "cde"
s.substr(3, 2); // "de"
- 如果没有第二个参数,表示一直取到字符串结束。
- 如果参数为负:
substring,自动将负数转为0。
slice,负数表示从尾部开始计算。
substr,第一个参数是负数表示从尾部开始计算;负第二个参数是负数将被转为0。
示例:
"Hello World".slice(-3) // "rld"
"Hello World".slice(4,-3) // "o Wo"
"Hello World".substring(-3) // "Hello World"
"Hello World".substring(4,-3) // "Hell"
"Hello World".substr(-3) // "rld"
"Hello World".substr(4,-3) // ""
5、indexOf 和 lastIndexOf 方法
都用来确定一个字符串在另一个字符串中的位置。lastIndexOf从尾部开始匹配。
"hello world".indexOf("o") // 4
"hello world".lastIndexOf("o") // 7
它们还可以接受第二个参数,表示从该位置开始匹配。
"hello world".indexOf("o", 6) // 7
"hello world".lastIndexOf("o", 6) // 4
6、trim 方法
去除字符串两端的空格。(不改变原字符串)
" hello ".trim() // "hello"
7、toLowerCase 和 toUpperCase 方法
toLowerCase转小写,toUpperCase转大写。
"Hello".toLowerCase() // "hello"
"Hello".toUpperCase() // "HELLO"
8、localeCompare方法
比较两个字符串。返回值小于0,表示第一个字符串小;大于0,表示第一个字符串大;等于0,表示相等。
'apple'.localeCompare('banana') // -1
'apple'.localeCompare('apple') // 0
9、搜索和替换
- match:返回匹配的子字符串数组(默认只返第一个)。找不到则返回null。
- search:返回第一个匹配的位置。找不到则返回-1。
- replace:替换匹配的字符串(默认只替换第一个)。
- split:分割字符串,返回分割后的数组。
(如省略分割规则,则返回数组的唯一成员就是原字符串。)
示例:
var matchs="abcdefabcdef".match("bc");
console.log(matchs); // ["bc"]
console.log(matchs.index); // 1
console.log(matchs.input); // "abcdefabcdef"
var matchs2="abcdefabcdef".match(/bc/g);
console.log(matchs2); // ["bc", "bc"]
//matchs2就没有index和input了
console.log("abcdefabcdef".search("bc")); // 1
console.log("Cat,dog cat,mice".replace(/cat/gi,"*")); // "*,dog *,mice"
console.log("|a,b|c".split()); // ["|a,b|c"]
console.log("|a,b|c".split(/,|\|/)); // ["", "a", "b", "c"]
3.4 Math对象
Math是JavaScript的内置对象,提供一系列数学常数和数学方法。它不能作为构造函数或工具函数使用。
3.4.1 属性
E:常数e。。
PI:常数Pi。
3.4.2 方法
1、round 四舍五入。(注意:负数和正数有不同)
console.log(Math.round(1.4)); //1
console.log(Math.round(1.5)); //2
console.log(Math.round(-1.5)); //-1
console.log(Math.round(-1.6)); //-2
2、abs方法,max方法,min方法
Math.abs(-1) // 1
Math.max(2, -1, 5) // 5
Math.min(2, -1, 5) // -1
3、floor(小于参数的最大整数),ceil(大于参数的最小整数)
Math.floor(3.2) // 3
Math.floor(-3.2) // -4
Math.ceil(3.2) // 4
Math.ceil(-3.2) // -3
4、pow(指数),sqrt(平方根)
Math.pow(2, 2) // 4
Math.pow(2, 3) // 8
Math.sqrt(4) // 2
Math.sqrt(-4) // NaN //如第一参数是负值,则返回NaN。
5、log(e的自然对数),exp方法(10的对数)
6、random 0到1之间的伪随机数。(左闭右开)
Math.random() // 0.7151307314634323
// 返回给定范围内的随机数
Math.random() * (max - min) + min;
7、三角函数方法
3.5 Date对象
3.5.1 概述
3.5.1.1 Date()
返回当前日期和时间的字符串。
3.5.1.2 new Date()
返回值为当前时间的Date对象。
var date1 = Date();
var date2 = new Date();
typeof date1; // string
typeof date2; // object
3.5.1.3 new Date(milliseconds)
参数为从1970年1月1日UTC开始计算的毫秒数。
new Date(3600*24*1000); // 1970年1月2日
3.5.1.4 new Date(datestring)
参数是Date.parse()能接受的字符串。
new Date("2013-02-15")
3.5.1.5 new Date(year, month [, day, hours, minutes, seconds, ms])
注意:如果只有一个数值参数,那将被当做毫秒数。
月从0开始计算,0表示1月 (可为负数或很大的数)
天从1开始计算,0表示上个月最后一天 (可为负数或很大的数)
年的0,表示1900年;负数,则表示公元前。
new Date(2015); // 1970.1.1 8点多
new Date(2015,0); // 2015.1.1
new Date(2015,1); // 2015.2.1
new Date(2015,0,-1); // 2014.12.30
new Date(2015,0,0); // 2014.12.31
new Date(2015,0,1); // 2015.1.1
new Date(2015,1,0); // 2015.1.31
new Date(2015,1,1); // 2015.2.1
new Date(2015,1,29); // 2015.3.1
new Date(1,0); // 1901.1.1
new Date(0,0); // 1900.1.1
new Date(-1,0); // -1.1.1
3.5.1.6 日期的运算
两个日期对象进行减法,返回的是间隔毫秒数;
进行加法,返回的是两个字符串的连接。
3.5.2 Date对象的方法
3.5.2.1 Date.now()
返回距离1970年1月1日的毫秒数。
Date.now() // 1364026285194
另:window.performance.now()返回页面加载到命令运行时已经过去的毫秒数。
3.5.2.2 Date.parse()
返回字符串表示的时间距离1970年1月1日UTC的毫秒数或NaN。
Date.parse("Aug 9, 1995") // 807897600000
3.5.2.3 Date.UTC()
默认Date对象返回的是当前时区的时间。Date.UTC方法可以返回UTC时间。
用法与Date构造函数完全一致。
3.5.3 Date实例对象的方法
3.5.3.1 Date.prototype.toString()
toString是默认的调用方法,所以如果直接读取Date对象实例,就相当于调用实例的toString方法。
new Date().toString(); // Mar 04 2015 17:56:06
new Date(); // Mar 04 2015 17:56:06
3.5.3.1 Date.prototype.toUTCString(),Date.prototype.toISOString()
new Date().toUTCString(); // Mar 04 2015 9:56:06
3.5.3.1 Date.prototype.toDateString(),Date.prototype.toTimeString()
toDateString返回日期部分的字符串,
toTimeString返回时间部分的字符串。
new Date().toDateString(); // Mar 04 2015
3.5.3.1 Date.prototype.toLocaleDateString(),Date.prototype.toLocaleTimeString()
toLocaleDateString返回日期的当地写法;
toLocaleTimeString返回时间的当地写法。
new Date().toLocaleDateString(); // 2015/3/4
new Date().toLocaleTimeString(); // 下午6:11:04
3.5.3.1 Date.prototype.valueOf()
返回距离1970年1月1日UTC的毫秒数,等同于getTime方法。
new Date().valueOf() // 1362790014817
new Date().getTime() // 1362790014817
3.5.3.1 Date.prototype.get系列方法
- .getTime():返回距离1970年1月1日的毫秒数,等同于valueOf方法。
- .getDate():返回对应每个月的几号(从1开始)。
- .getDay():返回星期(0-6),星期日为0。
- .getFullYear():返回四位的年份。
- .getMonth():返回月份(0-11)。
- .getHours():返回小时(0-23)。
- .getMilliseconds():返回毫秒(0-999)。
- .getMinutes():返回分钟(0-59)。
- .getSeconds():返回秒(0-59)。
上面的方法返回的都是当前时区的时间,Date对象还提供了这些方法对应的UTC版本,比如getUTCFullYear()等。
3.5.3.1 Date.prototype.set系列方法
.setDate(date):设置实例对象对应的每个月的几号(1-31),返回改变后毫秒时间戳。
.setFullYear(year [, month, date]):设置四位年份。
.setHours(hour [, min, sec, ms]):设置小时(0-23)。
.setMilliseconds():设置毫秒(0-999)。
.setMinutes(min [, sec, ms]):设置分钟(0-59)。
.setMonth(month [, date]):设置月份(0-11)。
.setSeconds(sec [, ms]):设置秒(0-59)。
.setTime(milliseconds):设置毫秒时间戳。
new Date().setFullYear(0,0,1)); // 0年1月1日 18:24:44
3.5.3.1 Date.prototype.toJSON()
返回JSON格式的日期对象。
jsonDate = new Date().toJSON();
console.log(jsonDate); // 2015-03-04T10:28:54.215Z
var backToDate = new Date(jsonDate);
console.log(backToDate); // Date对象
3.6 RegExp对象
3.6.1 概述
创建正则表达式有两种方法:
1、使用字面量,以斜杠表示开始和结束。
2、使用RegExp构造函数
var regex = /xyz/ig; // ig是修饰符
var regex = new RegExp("xyz","ig");
3.6.2 正则对象的属性和方法
3.6.2.1 属性
- ignoreCase:只读 表示是否设置了i修饰符。
- global:只读 表示是否设置了g修饰符。
- lastIndex:可读可写,只有设置了g才有意义 返回下一次开始搜索的位置。
- source:只读 返回正则表达式的字符串形式(不包括反斜杠)。
- multiline:只读 表示是否设置了m修饰符。
示例:
var r = /abc/igm;
r.ignoreCase // true
r.global // true
r.multiline // true
r.lastIndex // 0
r.source // "abc"
3.6.2.2 test方法
1、验证字符串是否符合某个模式。
/CAT/i.test('cats and dogs') // true
2、如果正则表达式带有g修饰符,则每次test方法都从上一次结束的位置开始向后匹配。
显然这个是通过闭包实现的,如果不能对同一个RegExp对象交叉传入不同的参数,以免出错。
var r = /x/g;
var s = '_x_x';
r.lastIndex // 0
r.test(s) // true
r.lastIndex // 2
r.test(s) // true
r.lastIndex // 4
r.test(s) // false
r.lastIndex // 0
3、如果正则模式是一个空字符串,则匹配所有字符串。
new RegExp("").test("abc")// true
3.6.2.3 exec方法
返回匹配结果。
匹配成功,返回数组,里面包括(匹配结果、input、index)。匹配失败,返回null。
var reg = /x/g ;
var r = reg.exec('_x_x') // ["x"] //r.index是1
r = reg.exec('_x_x') // ["x"] //r.index是3
r = reg.exec('_x_x') // null
如果RegExp里包含圆括号,则返回的数组会包括多个元素。第一个元素是整个匹配结果,后面的元素就是圆括号对应的匹配结果。整个返回数组的length属性等于匹配成功的组数+1。
var s = 'x_x';
var r = /(x)/;
r.exec(s) // ["_x", "x"]
上面代码的exex方法,返回一个数组。第一个元素是整个匹配的结果,第二个元素是圆括号匹配的结果。
var r = /a(b+)a/g;
var s = "_abbba_aba_";
while(true) {
var match = r.exec(s);
if (!match) break;
console.log(match,match[1]);
}
//["abbba", "bbb"] "bbb"
//["aba", "b"] "b"
如果正则对象是一个空字符串,则exec方法会匹配成功,但返回的也是空字符串。
3.6.3 字符串对象的方法
3.6.3.1 match:查找匹配的子字符串。
'_x_x'.match(/x/) // ["x"]
与正则对象的exec方法非常类似:匹配成功返回一个数组,失败返回null。
但如果正则带有g修饰符,则会返回所有匹配成功的结果。
'_x_x'.match(/x/g) // ["x","x"]
3.6.3.2 search:搜索。
返回第一个满足条件的匹配结果的位置,或-1。
该方法会忽略g参数。
'_x_x'.search(/x/)// 1
3.6.3.3 replace:替换。
replace的第一个参数是搜索模式,第二个是要替换为的内容。
搜索模式如果不加g修饰符,就替换第一个匹配成功的值,否则替换所有。
"aaa".replace("a", "B") // "Baa"
"aaa".replace(/a/, "B") // "Baa"
"aaa".replace(/a/g, "B") // "BBB"
replace方法的第二个参数可以使用美元符号$,用来指代所替换的内容。
- $& 指代匹配的子字符串。
- $` 指代匹配结果前面的文本。
- $' 指代匹配结果后面的文本。
- $n 指代匹配成功的第n组内容,n从1开始计数(当然了,因为第0组是全部匹配结果啊)。
- $$ 指代美元符号$。
示例:
"abc".replace("b", "[$`-$&-$']")// "a[a-b-c]c"
"hello world".replace(/(\w+)\s(\w+)/,"$2 $1")// "world hello"
第二个参数还可以是一个函数,将匹配内容替换为函数返回值。
3.6.3.4 split:分割。
split的第一个参数是分隔规则,第二个是返回数组的最大成员数。
'a, b,c, d'.split(',') // [ 'a', ' b', 'c', ' d' ]
'a, b,c, d'.split(/, */) // [ 'a', 'b', 'c', 'd' ]
'a, b,c, d'.split(/, */, 2) // [ 'a', 'b' ]
如果正则表达式带有括号,则括号匹配的部分也会作为数组成员返回。
"aaa*a*".split(/(a*)/)// [ '', 'aaa', '*', 'a', '*' ]
'a, b , '.split(/ *(,) */)// ["a", ",", "b", ",", ""]
3.6.4 匹配规则
3.6.4.1 字面量字符和元字符
大部分字符在正则表达式中,就是字面的含义,比如/a/匹配a,/b/匹配b。它们都叫做“字面量字符”(literal characters)。
还有一部分字符有特殊含义,不代表字面的意思。它们叫做“元字符”(metacharacters)。
1、点(.)
匹配除回车(\r)、换行(\n)、行分隔符(\u2028)和段分隔符(\u2029)以外的所有字符。
2、位置字符
^ 表示字符串的起首。
$ 表示字符串的行尾。
3、选择符(|)
/11|22/.test("911") // true
3.6.4.2 字符类
字符类(class)表示有一系列字符可供选择,只要匹配其中一个就可以了。所有可供选择的字符都放在方括号内。
/[abc]/.test("apple") // true
1、脱字符(^)
如果方括号内的第一个字符是[^],则表示除了字符类之中的字符,其他字符都可以匹配。
/[^abc]/.test("xyz"); // true
/[^abc]/.test("xyc"); // true
/[^abc]/.test("ac"); // false
注意,脱字符只有在字符类的第一个位置才有特殊含义,否则就是字面含义。
2、连字符(-)
当-
不出现在方括号之中,就不是连字符。
/a-c/.test(" a-c "); // true //这个-不是连接符
/a-c/.test("-"); // false //这个-不是连接符
/[3-5]/.test("a3b"); // true //这个-是连接符
[1-31] //这个不代表1到31,只代表1到3。
3、重复类
{} 表示模式的重复次数。{n}表示重复n次,{n,}表示至少重复n次,{n,m}表示重复不少于n次,不多于m次。
/lo{2}k/.test("look") // true
/lo{2,5}k/.test("looook") // true
4、量词符
? 表示某个模式出现1次或0次,等同于{0, 1}。
- 表示某个模式出现0次或多次,等同于 {0,}。
- 表示某个模式出现1次或多次,等同于 {1,}。
以上三个量词符,默认都是贪婪模式。比如,对于字符串“aaa”来说,/a+/将会匹配“aaa”,而不会匹配“aa”。
如果要改为非贪婪模式,可以在量词符后面加一个问号。比如,/a+?/将会只匹配“a”。
/a+/.exec("aa"); // ["aa"]
/a+?/.exec("aa"); // ["a"]
/^a+?/.exec("aa"); // ["a"]
5、转义符
正则模式中,需要用斜杠转义的,一共有12个字符:^、.、[、$、(、)、|、、+、?、{、\。
注意:如果使用RegExp创建正则对象,转义需要使用两个斜杠*,因为字符串内部会先转义一次。
/1\+1/.test("1+1") // true
(new RegExp("1\\+1")).test("1+1") // true
6、修饰符
- g(global) 全局匹配
默认第一次匹配成功后,正则对象就停止向下匹配。
加上g后,每次都是从上一次匹配成功处继续向后匹配。
var regex = /b/g;
regex.test('abba'); // true
regex.test('abba'); // true
regex.test('abba'); // false
- i(ignorecase) 忽略大小写
默认正则对象区分大小写。
加上i后忽略大小写。
/abc/.test("ABC") // false
/abc/i.test("ABC") // true
- m(multiline) 多行模式
默认正则对象会将换行符当作算入字符串的开头或结尾。
加上m后,正则对象会忽略字符串头部或尾部的换行符,即^和$会忽略换行符。
/world$/.test("hello world\n") // false
/world$/m.test("hello world\n") // true
7、预定义模式
预定义模式指的是某些常见模式的简写方式。
\d 匹配0-9之间的任一数字,相当于[0-9]。
\D 匹配所有0-9以外的字符,相当于[^0-9]。
\w 匹配任意的字母、数字和下划线,相当于[A-Za-z0-9_]。
\W 除所有字母、数字和下划线以外的字符,相当于/[^A-Za-z0-9_]/ 。
\s 匹配空格(包括制表符、空格符、断行符等),相等于[\t\r\n\v\f]。
\S 匹配非空格的字符,相当于[^\t\r\n\v\f]。
\b 匹配词的边界。
\B 匹配非词边界,即在词的内部。
8、特殊字符
正则对象对一些不能打印的特殊字符,提供了表达形式。
\n 匹配换行键。
\r 匹配回车键。
\t 匹配制表符tab(U+0009)。
\v 匹配垂直制表符(U+000B)。
\f 匹配换页符(U+000C)。
\0 匹配null字符(U+0000)。
9、组匹配
正则表达式的括号表示分组匹配,括号中的模式可以用来捕获分组的内容。
var m = "abcabc".match(/(.)b(.)/);
m // ["abc", "a", "c"]
注意,使用组匹配时,不宜同时使用g修饰符,否则match方法不会捕获分组的内容。
var m = "abcabc".match(/(.)b(.)/g);
m // ["abc", "abc"]
上面代码使用带g修饰符的正则表达式,结果match方法只捕获了匹配整个表达式的部分。
在正则表达式内部,可以用\n引用括号匹配的内容,n是从1开始的自然数,表示对应顺序的括号。
/(.)b(.)\1b\2/.test("abcabc");
/(.)b(.)\1b\2/.test("abcXbc");
- 非捕获组 (?:x)
表示不返回该组匹配的内容。
var m = "abc".match(/(?:.)b(.)/);
m[1] // "c" //如果是match(/(.)b/)则m[1]是"a"
var url = /(http|ftp):\/\/([^/\r\n]+)(\/[^\r\n]*)?/;
url.exec("http://google.com/"); // ["http://google.com/", "http", "google.com", "/"]
var url = /(?:http|ftp):\/\/([^/\r\n]+)(\/[^\r\n]*)?/;
url.exec("http://google.com/"); // ["http://google.com/", "google.com", "/"]
- 先行断言 x(?=y)
表示x只有在y前面才匹配,y不会被计入返回结果。
var m = "abc".match(/b(?=c)/);
m // "b"
- 后行断言 x(?!y)
表示x只有不在y前面才匹配,y不会被计入返回结果。
var m = "abd".match(/b(?!c)/);
m // ["b"]
3.7 JSON对象
3.7.1 JSON格式
对象:是一个无序的“‘名称/值’对”集合。
{string:value, ...string:value}
数组:是值(value)的有序集合。
[value, ...value]
值:
字符串(必须双引号)、
数值(必须十进制)、
布尔值、
null、
JSON格式的对象、
JSON格式的数组。
3.7.2 JSON对象
JSON.stringify()
将一个值转为JSON字符串。
正则对象会被转成空对象。
JSON.stringify方法还可以接受一个数组参数,指定需要转成字符串的属性。还可以接受一个函数来更改默认的字符串化的行为。
JSON.parse()
将JSON字符串转化成值。
var aaa={id:123,name:"dgl"};
JSON.stringify(aaa); // "abc"
JSON.stringify("abc"); // {"id":123,"name":"dgl"}
JSON.parse('"abc"'); // abc
JSON.parse('{"id":123,"name":"dgl"}'); //对象{id: 123, name: "dgl"}
3.8 ArrayBuffer:类型化数组
略。