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:类型化数组

略。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容