js文档笔记2——标准库

栏目: JavaScript · 发布时间: 4年前

内容简介:(1)Object对象本身的方法(静态方法)所谓“本身的方法”就是直接定义在上面代码中,
  1. JavaScript 的所有其他对象都继承自 Object 对象,即那些对象都是 Object 的实例。
  2. Object 对象的原生方法分成两类: Object 本身的方法与 Object 的实例方法。

(1)Object对象本身的方法(静态方法)

所谓“本身的方法”就是直接定义在 Object 对象的方法。

Object.print = function (o) { console.log(o) };
复制代码

上面代码中, print 方法就是直接定义在 Object 对象上。

(2)Object的实例方法

所谓实例方法就是定义在 Object 原型对象 Object.prototype 上的方法。它可以被 Object 实例直接使用。

Object.prototype.print = function () {
  console.log(this);
};

var obj = new Object();
obj.print() // Object
复制代码

1.Object()

Object本身是一个函数,可以当作 工具 方法使用,将任意值转为对象。这个方法常用于保证某个值一定是对象。

Object

利用这一点,可以写一个判断变量是否为对象的函数。

function isObject(value) {
  return value === Object(value);
}

isObject([]) // true
isObject(true) // false
复制代码

2.Object 构造函数

  1. Object(value)与new Object(value)两者的语义是不同的,Object(value)表示将value转成一个对象,new Object(value)则表示新生成一个对象,它的值是value。
  2. 通过var obj = new Object()的写法生成新对象,与字面量的写法var obj = {}是等价的。或者说,后者只是前者的一种简便写法。

3.静态方法

Object.keys()方法的参数是一个对象,返回一个数组。该数组的成员都是该对象自身的所有属性名。(可枚举) Object.getOwnPropertyNames()返回一个数组,包含了该对象自身的所有属性名(不可枚举)

(1)对象属性模型的相关方法 Object.getOwnPropertyDescriptor():获取某个属性的描述对象。 Object.defineProperty():通过描述对象,定义某个属性。 Object.defineProperties():通过描述对象,定义多个属性。

(2)控制对象状态的方法 Object.preventExtensions():防止对象扩展。 Object.isExtensible():判断对象是否可扩展。 Object.seal():禁止对象配置。 Object.isSealed():判断一个对象是否可配置。 Object.freeze():冻结一个对象。 Object.isFrozen():判断一个对象是否被冻结。

(3)原型链相关方法 Object.create():该方法可以指定原型对象和属性,返回一个新的对象。 Object.getPrototypeOf():获取对象的Prototype对象。

4.Object 的实例方法

除了静态方法,还有不少方法定义在 Object.prototype 对象。它们称为实例方法, 所有 Object 的实例对象 都继承了这些方法。

Object实例对象的方法,主要有以下六个。

Object.prototype.valueOf():返回当前对象对应的值。 Object.prototype.toString():返回当前对象对应的字符串形式。 Object.prototype.toLocaleString():返回当前对象对应的本地字符串形式。 Object.prototype.hasOwnProperty():判断某个属性是否为当前对象自身的属性,还是继承自原型对象的属性。 Object.prototype.isPrototypeOf():判断当前对象是否为另一个对象的原型。 Object.prototype.propertyIsEnumerable():判断某个属性是否可枚举。

技巧:只做一个精确的类型判断方法

var type = function (o){
  var s = Object.prototype.toString.call(o);
  return s.match(/\[object (.*?)\]/)[1].toLowerCase();
};
复制代码

延伸:判断具体类型的方法

var type = function (o){
  var s = Object.prototype.toString.call(o);
  return s.match(/\[object (.*?)\]/)[1].toLowerCase();
};

['Null',
 'Undefined',
 'Object',
 'Array',
 'String',
 'Number',
 'Boolean',
 'Function',
 'RegExp'
].forEach(function (t) {
  type['is' + t] = function (o) {
    return type(o) === t.toLowerCase();
  };
});

type.isObject({}) // true
type.isNumber(NaN) // true
type.isRegExp(/abc/) // true
复制代码

二.属性描述对象

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

1.enumerable

如果一个属性的 enumerablefalse ,下面三个操作不会取到该属性。

for..in
Object.keys
JSON.stringify

因此, enumerable 可以用来设置“秘密”属性。

2.存取器

正常写法

var obj = Object.defineProperty({}, 'p', {
  get: function () {
    return 'getter';
  },
  set: function (value) {
    console.log('setter: ' + value);
  }
});
复制代码

特殊写法

JavaScript 还提供了存取器的另一种写法。

var obj = {
  get p() {
    return 'getter';
  },
  set p(value) {
    console.log('setter: ' + value);
  }
};
复制代码

3.对象的拷贝

属性的元对象设置都会拷贝

var extend = function (to, from) {
  for (var property in from) {
    if (!from.hasOwnProperty(property)) continue;
    Object.defineProperty(
      to,
      property,
      Object.getOwnPropertyDescriptor(from, property)
    );
  }

  return to;
}

extend({}, { get a(){ return 1 } })
复制代码

三.控制对象状态

有时需要冻结对象的读写状态,防止对象被改变。JavaScript 提供了三种冻结方法,最弱的一种是 Object.preventExtensions ,其次是 Object.seal ,最强的是 Object.freeze

Object.preventExtensions

1. Object.preventExtensions 方法可以使得一个对象无法再添加新的属性。

Object.isExtensible 方法用于检查一个对象是否使用了 Object.preventExtensions 方法。也就是说,检查是否可以为一个对象添加属性。

Object.seal

2. Object.seal 方法使得一个对象既无法添加新属性,也无法删除旧属性。

Object.isSealed 方法用于检查一个对象是否使用了 Object.seal 方法。

Object.freeze

3. Object.freeze 方法可以使得一个对象无法添加新属性、无法删除旧属性、也无法改变属性的值,使得这个对象实际上变成了常量。

Object.isFrozen 方法用于检查一个对象是否使用了 Object.freeze 方法。

局限

上面的三个方法锁定对象的可写性有一个漏洞:可以通过改变原型对象,来为对象增加属性。

一种解决方案是,把 obj 的原型也冻结住。

另外一个局限是,如果属性值是对象,上面这些方法只能冻结属性指向的对象,而不能冻结对象本身的内容。

var obj = {
  foo: 1,
  bar: ['a', 'b']
};
Object.freeze(obj);

obj.bar.push('c');
obj.bar // ["a", "b", "c"]
复制代码

上面代码中, obj.bar 属性指向一个数组, obj 对象被冻结以后,这个指向无法改变,即无法指向其他值,但是所指向的数组是可以改变的。

四.Array对象

1.构造函数

Array 是 JavaScript 的原生对象,同时也是一个构造函数,可以用它生成新的数组。

Array 构造函数有一个很大的缺陷,就是不同的参数,会导致它的行为不一致。

// 无参数时,返回一个空数组
new Array() // []

// 单个正整数参数,表示返回的新数组的长度
new Array(1) // [ empty ]
new Array(2) // [ empty x 2 ]

// 非正整数的数值作为参数,会报错
new Array(3.2) // RangeError: Invalid array length
new Array(-3) // RangeError: Invalid array length

// 单个非数值(比如字符串、布尔值、对象等)作为参数,
// 则该参数是返回的新数组的成员
new Array('abc') // ['abc']
new Array([1]) // [Array[1]]

// 多参数时,所有参数都是返回的新数组的成员
new Array(1, 2) // [1, 2]
new Array('a', 'b', 'c') // ['a', 'b', 'c']
复制代码

所以不建议使用构造函数创建数组,推荐用字面量创建

2.静态方法

Array.isArray 方法返回一个布尔值,表示参数是否为数组。它可以弥补 typeof 运算符的不足。

3.实例方法

  1. valueOf 方法是一个所有对象都拥有的方法,表示对该对象求值。不同对象的 valueOf 方法不尽一致,数组的 valueOf 方法返回数组本身。

  2. toString 方法也是对象的通用方法,数组的 toString 方法返回数组的字符串形式。

  3. push 方法用于在数组的末端添加一个或多个元素,并返回添加新元素后的数组长度。注意,该方法会改变原数组。

  4. pop 方法用于删除数组的最后一个元素,并返回该元素。注意,该方法会改变原数组。

pushpop 结合使用,就构成了“后进先出”的栈结构(stack)。

  1. shift() 方法用于删除数组的第一个元素,并返回该元素。注意,该方法会改变原数组。

push()shift() 结合使用,就构成了“先进先出”的队列结构(queue)。

  1. unshift() 方法用于在数组的第一个位置添加元素,并返回添加新元素后的数组长度。注意,该方法会改变原数组。

  2. join() 方法以指定参数作为分隔符,将所有数组成员连接为一个字符串返回。如果不提供参数,默认用逗号分隔。

  3. concat 方法用于多个数组的合并。它将新数组的成员,添加到原数组成员的后部,然后返回一个新数组,原数组不变。

  4. reverse 方法用于颠倒排列数组元素,返回改变后的数组。注意,该方法将改变原数组。

  5. slice 方法用于提取目标数组的一部分,返回一个新数组,原数组不变。

    它的第一个参数为起始位置(从0开始),第二个参数为终止位置(但该位置的元素本身不包括在内)。如果省略第二个参数,则一直返回到原数组的最后一个成员。

  6. splice 方法用于删除原数组的一部分成员,并可以在删除的位置添加新的数组成员,返回值是被删除的元素。注意,该方法会改变原数组。

    splice 的第一个参数是删除的起始位置(从0开始),第二个参数是被删除的元素个数。如果后面还有更多的参数,则表示这些就是要被插入数组的新元素。

  7. sort 方法对数组成员进行排序,默认是按照字典顺序排序。排序后,原数组将被改变。

  8. map 方法将数组的所有成员依次传入参数函数,然后把每一次的执行结果组成一个新数组返回。

    map 方法还可以接受第二个参数,用来绑定回调函数内部的 this 变量(详见《this 变量》一章)。

    var arr = ['a', 'b', 'c'];
    
    [1, 2].map(function (e) {
      return this[e];
    }, arr)
    // ['b', 'c']
    复制代码

    上面代码通过 map 方法的第二个参数,将回调函数内部的 this 对象,指向 arr 数组。

    如果数组有空位, map 方法的回调函数在这个位置不会执行,会跳过数组的空位。

    var f = function (n) { return 'a' };
    
    [1, undefined, 2].map(f) // ["a", "a", "a"]
    [1, null, 2].map(f) // ["a", "a", "a"]
    [1, , 2].map(f) // ["a", , "a"]
    复制代码
  9. filter 方法用于过滤数组成员,满足条件的成员组成一个新数组返回。

  10. some 方法是只要一个成员的返回值是 true ,则整个 some 方法的返回值就是 true ,否则返回 false

  11. some 方法是只要一个成员的返回值是 true ,则整个 some 方法的返回值就是 true ,否则返回 false

  12. reduce 方法和 reduceRight 方法依次处理数组的每个成员,最终累计为一个值。它们的差别是, reduce 是从左到右处理(从第一个成员到最后一个成员), reduceRight 则是从右到左(从最后一个成员到第一个成员),其他完全一样。

    reduce 方法和 reduceRight 方法的第一个参数都是一个函数。该函数接受以下四个参数。

    1. 累积变量,默认为数组的第一个成员
    2. 当前变量,默认为数组的第二个成员
    3. 当前位置(从0开始)
    4. 原数组
  13. indexOf 方法返回给定元素在数组中第一次出现的位置,如果没有出现则返回 -1

  14. lastIndexOf 方法返回给定元素在数组中最后一次出现的位置,如果没有出现则返回 -1

链式使用

返回值是数组的可以进行链式使用

五.包装对象

1.简介

对象是 JavaScript 语言最主要的数据类型,三种原始类型的值——数值、字符串、布尔值——在一定条件下,也会自动转为对象,也就是原始类型的“包装对象”(wrapper)。

所谓“包装对象”,指的是与数值、字符串、布尔值分别相对应的 NumberStringBoolean 三个原生对象。这三个原生对象可以把原始类型的值变成(包装成)对象。

上面代码中,基于原始类型的值,生成了三个对应的包装对象。可以看到, v1v2v3 都是对象,且与对应的简单类型值不相等。

包装对象的设计目的,首先是 使得“对象”这种类型可以覆盖 JavaScript 所有的值,整门语言有一个通用的数据模型 ,其次是使得原始类型的值也有办法调用自己的方法。

NumberStringBoolean 这三个原生对象,如果不作为构造函数调用(即调用时不加 new ),而是作为普通函数调用,常常用于将任意类型的值转为数值、字符串和布尔值。

2.原始类型与实例对象的自动转换

某些场合,原始类型的值会自动当作包装对象调用,即调用包装对象的属性和方法。这时,JavaScript 引擎会自动将原始类型的值转为包装对象实例,并在使用后立刻销毁实例。

比如,字符串可以调用 length 属性,返回字符串的长度。

'abc'.length // 3
复制代码

上面代码中, abc 是一个字符串,本身不是对象,不能调用 length 属性。JavaScript 引擎自动将其转为包装对象,在这个对象上调用 length 属性。调用结束后,这个临时对象就会被销毁。这就叫原始类型与实例对象的自动转换。

自动转换生成的包装对象是只读的,无法修改。所以,字符串无法添加新属性。

var s = 'Hello World';
s.x = 123;
s.x // undefined
复制代码

上面代码为字符串 s 添加了一个 x 属性,结果无效,总是返回 undefined

另一方面,调用结束后,包装对象实例会自动销毁。这意味着,下一次调用字符串的属性时,实际是调用一个新生成的对象,而不是上一次调用时生成的那个对象,所以取不到赋值在上一个对象的属性。如果要为字符串添加属性,只有在它的原型对象 String.prototype 上定义(参见《面向对象编程》章节)。

3.自定义方法

除了原生的实例方法,包装对象还可以自定义方法和属性,供原始类型的值直接调用。(标准规范不推荐的)

String.prototype.double = function () {
  return this.valueOf() + this.valueOf();
};

'abc'.double()
// abcabc

Number.prototype.double = function () {
  return this.valueOf() + this.valueOf();
};

(123).double() // 246
复制代码

上面代码在 StringNumber 这两个对象的原型上面,分别自定义了一个方法,从而可以在所有实例对象上调用。注意,最后一张的 123 外面必须要加上圆括号,否则后面的点运算符( . )会被解释成小数点。

六.Boolean对象

Number 对象是数值对应的包装对象

七.Number对象

1.静态属性

  • Number.POSITIVE_INFINITY :正的无限,指向 Infinity
  • Number.NEGATIVE_INFINITY :负的无限,指向 -Infinity
  • Number.NaN :表示非数值,指向 NaN
  • Number.MIN_VALUE :表示最小的正数(即最接近0的正数,在64位浮点数体系中为 5e-324 ),相应的,最接近0的负数为 -Number.MIN_VALUE
  • Number.MAX_SAFE_INTEGER :表示能够精确表示的最大整数,即 9007199254740991
  • Number.MIN_SAFE_INTEGER :表示能够精确表示的最小整数,即 -9007199254740991

2.实例方法

​ Number.prototype.toString()

Number 对象部署了自己的 toString 方法,用来将一个数值转为字符串形式。

(10).toString() // "10"
复制代码

Number 对象部署了自己的 toString 方法,用来将一个数值转为字符串形式。

(10).toString() // "10"
复制代码

​ Number.prototype.toFixed()

toFixed() 方法先将一个数转为指定位数的小数,然后返回这个小数对应的字符串。

(10).toFixed(2) // "10.00"
复制代码

由于浮点数的原因,小数 5 的四舍五入是不确定的,使用的时候必须小心。

(10.055).toFixed(2) // 10.05
(10.005).toFixed(2) // 10.01
复制代码

​ Number.prototype.toExponential()

toExponential 方法用于将一个数转为科学计数法形式。

toExponential 方法的参数是小数点后有效数字的位数,范围为0到20,超出这个范围,会抛出一个 RangeError 错误。

​ Number.prototype.toPrecision()

toPrecision 方法用于将一个数转为指定位数的有效数字。

(12.34).toPrecision(1) // "1e+1"
(12.34).toPrecision(2) // "12"
(12.34).toPrecision(3) // "12.3"
(12.34).toPrecision(4) // "12.34"
(12.34).toPrecision(5) // "12.340"
复制代码

toPrecision 方法的参数为有效数字的位数,范围是1到21,超出这个范围会抛出 RangeError 错误。

八.String对象

1.静态方法

String.fromCharCode()

String 对象提供的静态方法(即定义在对象本身,而不是定义在对象实例的方法),主要是 String.fromCharCode() 。该方法的参数是一个或多个数值,代表 Unicode 码点,返回值是这些码点组成的字符串。

2.实例方法

  1. charAt 方法返回指定位置的字符,参数是从 0 开始编号的位置。

    如果参数为负数,或大于等于字符串的长度, charAt 返回空字符串。

  2. charCodeAt 方法返回字符串指定位置的 Unicode 码点(十进制表示),相当于 String.fromCharCode() 的逆操作。

  3. concat 方法用于连接两个字符串,返回一个新字符串,不改变原字符串。

  4. slice 方法用于从原字符串取出子字符串并返回,不改变原字符串。它的第一个参数是子字符串的开始位置,第二个参数是子字符串的结束位置(不含该位置)。

  5. substring 方法用于从原字符串取出子字符串并返回,不改变原字符串,跟 slice 方法很相像。它的第一个参数表示子字符串的开始位置,第二个位置表示结束位置(返回结果不含该位置)

  6. substring 方法用于从原字符串取出子字符串并返回,不改变原字符串,跟 slice 方法很相像。它的第一个参数表示子字符串的开始位置,第二个位置表示结束位置(返回结果不含该位置)

  7. indexOf 方法用于确定一个字符串在另一个字符串中第一次出现的位置,返回结果是匹配开始的位置。如果返回 -1 ,就表示不匹配。

  8. trim 方法用于去除字符串两端的空格,返回一个新字符串,不改变原字符串。

  9. 该方法去除的不仅是空格,还包括制表符( \t\v )、换行符( \n )和回车符( \r )。

    '\r\nabc \t'.trim() // 'abc'
    复制代码
  10. toLowerCase 方法用于将一个字符串全部转为小写, toUpperCase 则是全部转为大写。它们都返回一个新字符串,不改变原字符串。

  11. match 方法用于确定原字符串是否匹配某个子字符串,返回一个数组,成员为匹配的第一个字符串。如果没有找到匹配,则返回 null

  12. search 方法的用法基本等同于 match ,但是返回值为匹配的第一个位置。如果没有找到匹配,则返回 -1

  13. replace 方法用于替换匹配的子字符串,一般情况下只替换第一个匹配(除非使用带有 g 修饰符的正则表达式)。

  14. split 方法按照给定规则分割字符串,返回一个由分割出来的子字符串组成的数组。

    上面代码中, split 方法的第二个参数,决定了返回数组的成员数。

    split 方法还可以使用正则表达式作为参数,详见《正则表达式》一节。

八.Date对象

Date.parse()方法解析的字符串,都可以当作Date构造函数的参数

new Date('2013-2-15')
new Date('2013/2/15')
new Date('02/15/2013')
new Date('2013-FEB-15')
new Date('FEB, 15, 2013')
new Date('FEB 15, 2013')
new Date('February, 15, 2013')
new Date('February 15, 2013')
new Date('15 Feb 2013')
new Date('15, February, 2013')
复制代码

多参数模式

new Date(2013, 0)
// Tue Jan 01 2013 00:00:00 GMT+0800 (CST)
new Date(2013, 0, 1)
// Tue Jan 01 2013 00:00:00 GMT+0800 (CST)
new Date(2013, 0, 1, 0)
// Tue Jan 01 2013 00:00:00 GMT+0800 (CST)
new Date(2013, 0, 1, 0, 0, 0, 0)
// Tue Jan 01 2013 00:00:00 GMT+0800 (CST)
复制代码

上面代码中,不管有几个参数,返回的都是2013年1月1日零点。

最后,各个参数的取值范围如下。

  • 年:使用四位数年份,比如 2000 。如果写成两位数或个位数,则加上 1900 ,即 10 代表1910年。如果是负数,表示公元前。
  • 月: 0 表示一月,依次类推, 11 表示12月。
  • 日: 131
  • 小时: 023
  • 分钟: 059
  • 秒: 059
  • 毫秒: 0999

日期计算

var d1 = new Date(2000, 2, 1);
var d2 = new Date(2000, 3, 1);

d2 - d1
// 2678400000
d2 + d1
// "Sat Apr 01 2000 00:00:00 GMT+0800 (CST)Wed Mar 01 2000 00:00:00 GMT+0800 (CST)"
复制代码

静态方法

Date.now 方法返回当前时间距离时间零点(1970年1月1日 00:00:00 UTC)的毫秒数,相当于 Unix 时间戳乘以1000。

Date.parse 方法用来解析日期字符串,返回该时间距离时间零点(1970年1月1日 00:00:00)的毫秒数。

Date.UTC 方法接受年、月、日等变量作为参数,返回该时间距离时间零点(1970年1月1日 00:00:00 UTC)的毫秒数。

实例方法

to类方法

toJSON 方法返回一个符合 JSON 格式的 ISO 日期字符串,与 toISOString 方法的返回结果完全相同。

toDateString 方法返回日期字符串(不含小时、分和秒)。

toTimeString 方法返回时间字符串(不含年月日)。

Date.prototype.toLocaleString()
Date.prototype.toLocaleDateString()
Date.prototype.toLocaleTimeString()
var d = new Date(2013, 0, 1);

// 时间格式
// 下面的设置是,星期和月份为完整文字,年份和日期为数字
d.toLocaleDateString('en-US', {
  weekday: 'long',
  year: 'numeric',
  month: 'long',
  day: 'numeric'
})
// "Tuesday, January 1, 2013"

// 指定时区
d.toLocaleTimeString('en-US', {
  timeZone: 'UTC',
  timeZoneName: 'short'
})
// "4:00:00 PM UTC"

d.toLocaleTimeString('en-US', {
  timeZone: 'Asia/Shanghai',
  timeZoneName: 'long'
})
// "12:00:00 AM China Standard Time"

// 小时周期为12还是24
d.toLocaleTimeString('en-US', {
  hour12: false
})
// "00:00:00"

d.toLocaleTimeString('en-US', {
  hour12: true
})
// "12:00:00 AM"
复制代码

get 类方法

  • getTime() :返回实例距离1970年1月1日00:00:00的毫秒数,等同于 valueOf 方法。
  • getDate() :返回实例对象对应每个月的几号(从1开始)。
  • getDay() :返回星期几,星期日为0,星期一为1,以此类推。
  • getFullYear() :返回四位的年份。
  • getMonth() :返回月份(0表示1月,11表示12月)。
  • getHours() :返回小时(0-23)。
  • getMilliseconds() :返回毫秒(0-999)。
  • getMinutes() :返回分钟(0-59)。
  • getSeconds() :返回秒(0-59)。
  • getTimezoneOffset() :返回当前时间与 UTC 的时区差异,以分钟表示,返回结果考虑到了夏令时因素。

面这些 get* 方法返回的都是当前时区的时间, Date 对象还提供了这些方法对应的 UTC 版本,用来返回 UTC 时间。

getUTCDate()
getUTCFullYear()
getUTCMonth()
getUTCDay()
getUTCHours()
getUTCMinutes()
getUTCSeconds()
getUTCMilliseconds()

set 类方法

setDate(date)
setFullYear(year [, month, date])
setHours(hour [, min, sec, ms])
setMilliseconds()
setMinutes(min [, sec, ms])
setMonth(month [, date])
setSeconds(sec [, ms])
setTime(milliseconds)

set* 系列方法除了 setTime() ,都有对应的 UTC 版本,即设置 UTC 时区的时间。

setUTCDate()
setUTCFullYear()
setUTCHours()
setUTCMilliseconds()
setUTCMinutes()
setUTCMonth()
setUTCSeconds()

九.RegExp 对象

JavaScript 的正则表达式体系是参照 Perl 5 建立的

新建正则表达式有两种方法。一种是使用字面量,以斜杠表示开始和结束。

var regex = /xyz/;
复制代码

另一种是使用 RegExp 构造函数。

var regex = new RegExp('xyz');
复制代码

它们的主要区别是,第一种方法在引擎编译代码时,就会新建正则表达式,第二种方法在运行时新建正则表达式,所以前者的效率较高。而且,前者比较便利和直观,所以实际应用中,基本上都采用字面量定义正则表达式。

RegExp 构造函数还可以接受第二个参数,表示修饰符(详细解释见下文)。

var regex = new RegExp('xyz', 'i');
// 等价于
var regex = /xyz/i;
复制代码

实例属性

  • RegExp.prototype.ignoreCase :返回一个布尔值,表示是否设置了 i 修饰符。
  • RegExp.prototype.global :返回一个布尔值,表示是否设置了 g 修饰符。
  • RegExp.prototype.multiline :返回一个布尔值,表示是否设置了 m 修饰符。
  • RegExp.prototype.flags :返回一个字符串,包含了已经设置的所有修饰符,按字母排序。

上面四个属性都是只读的。

var r = /abc/igm;

r.ignoreCase // true
r.global // true
r.multiline // true
r.flags // 'gim'
复制代码
RegExp.prototype.lastIndex
RegExp.prototype.source
var r = /abc/igm;

r.lastIndex // 0
r.source // "abc"
复制代码

实例方法

RegExp.prototype.test()

正则实例对象的 test 方法返回一个布尔值,表示当前模式是否能匹配参数字符串。

/cat/.test('cats and dogs') // true
复制代码

如果正则表达式带有 g 修饰符,则每一次 test 方法都从上一次结束的位置开始向后匹配。

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
复制代码

带有 g 修饰符时,正则表达式内部会记住上一次的 lastIndex 属性,这时不应该更换所要匹配的字符串,否则会有一些难以察觉的错误。

RegExp.prototype.exec()

正则实例对象的 exec 方法,用来返回匹配结果。如果发现匹配,就返回一个数组,成员是匹配成功的子字符串,否则返回 null

var s = '_x_x';
var r1 = /x/;
var r2 = /y/;

r1.exec(s) // ["x"]
r2.exec(s) // null
复制代码

字符串的实例方法

String.prototype.replace()

replace 方法的一个应用,就是消除字符串首尾两端的空格。

var str = '  #id div.class  ';

str.replace(/^\s+|\s+$/g, '')
// "#id div.class"
复制代码

replace 方法的第二个参数可以使用美元符号 $ ,用来指代所替换的内容。

  • $& :匹配的子字符串。
  • `$``:匹配结果前面的文本。
  • $' :匹配结果后面的文本。
  • $n :匹配成功的第 n 组内容, n 是从1开始的自然数。
  • $$ :指代美元符号 $
'hello world'.replace(/(\w+)\s(\w+)/, '$2 $1')
// "world hello"

'abc'.replace('b', '[$`-$&-$\']')
// "a[a-b-c]c"
复制代码

上面代码中,第一个例子是将匹配的组互换位置,第二个例子是改写匹配的值。

replace 方法的第二个参数还可以是一个函数,将每一个匹配内容替换为函数返回值。

'3 and 5'.replace(/[0-9]+/g, function (match) {
  return 2 * match;
})
// "6 and 10"

var a = 'The quick brown fox jumped over the lazy dog.';
var pattern = /quick|brown|lazy/ig;

a.replace(pattern, function replacer(match) {
  return match.toUpperCase();
});
// The QUICK BROWN fox jumped over the LAZY dog.
复制代码

下面是一个网页模板替换的例子。

var prices = {
  'p1': '$1.99',
  'p2': '$9.99',
  'p3': '$5.00'
};

var template = '<span id="p1"></span>'
  + '<span id="p2"></span>'
  + '<span id="p3"></span>';

template.replace(
  /(<span id=")(.*?)(">)(<\/span>)/g,
  function(match, $1, $2, $3, $4){
    return $1 + $2 + $3 + prices[$2] + $4;
  }
);
// "<span id="p1">$1.99</span><span id="p2">$9.99</span><span id="p3">$5.00</span>"
复制代码

上面代码的捕捉模式中,有四个括号,所以会产生四个组匹配,在匹配函数中用 $1$4 表示。匹配函数的作用是将价格插入模板中。

十.JSON 对象

JSON 格式(JavaScript Object Notation 的缩写)是一种用于数据交换的文本格式,2001年由 Douglas Crockford 提出,目的是取代繁琐笨重的 XML 格式。

每个 JSON 对象就是一个值,可能是一个数组或对象,也可能是一个原始类型的值。总之,只能是一个值,不能是两个或更多的值。

JSON 对值的类型和格式有严格的规定。

  1. 复合类型的值只能是数组或对象,不能是函数、正则表达式对象、日期对象。
  2. 原始类型的值只有四种:字符串、数值(必须以十进制表示)、布尔值和 null (不能使用 NaN , Infinity , -Infinityundefined )。
  3. 字符串必须使用双引号表示,不能使用单引号。
  4. 对象的键名必须放在双引号里面。
  5. 数组或对象最后一个成员的后面,不能加逗号。

JSON.stringify()

JSON.stringify 方法用于将一个值转为 JSON 字符串。该字符串符合 JSON 格式,并且可以被 JSON.parse 方法还原。

如果对象的属性是 undefined 、函数或 XML 对象,该属性会被 JSON.stringify 过滤。

如果数组的成员是 undefined 、函数或 XML 对象,则这些值被转成 null

第二个参数

JSON.stringify 方法还可以接受一个数组,作为第二个参数,指定需要转成字符串的属性。

var obj = {
  'prop1': 'value1',
  'prop2': 'value2',
  'prop3': 'value3'
};

var selectedProperties = ['prop1', 'prop2'];

JSON.stringify(obj, selectedProperties)
// "{"prop1":"value1","prop2":"value2"}"
复制代码

这个类似白名单的数组,只对对象的属性有效,对数组无效。

第二个参数还可以是一个函数,用来更改 JSON.stringify 的返回值。

第三个参数

JSON.stringify 还可以接受第三个参数,用于增加返回的 JSON 字符串的可读性。如果是数字,表示每个属性前面添加的空格(最多不超过10个);如果是字符串(不超过10个字符),则该字符串会添加在每行前面。

JSON.stringify({ p1: 1, p2: 2 }, null, 2);
/*
"{
  "p1": 1,
  "p2": 2
}"
*/

JSON.stringify({ p1:1, p2:2 }, null, '|-');
/*
"{
|-"p1": 1,
|-"p2": 2
}"
*/
复制代码

参数对象的 toJSON 方法

如果参数对象有自定义的 toJSON 方法,那么 JSON.stringify 会使用这个方法的返回值作为参数,而忽略原对象的其他属性。

var user = {
  firstName: '三',
  lastName: '张',

  get fullName(){
    return this.lastName + this.firstName;
  },

  toJSON: function () {
    return {
      name: this.lastName + this.firstName
    };
  }
};

JSON.stringify(user)
// "{"name":"张三"}"
复制代码

toJSON 方法的一个应用是,将正则对象自动转为字符串。因为 JSON.stringify 默认不能转换正则对象,但是设置了 toJSON 方法以后,就可以转换正则对象了。

var obj = {
  reg: /foo/
};

// 不设置 toJSON 方法时
JSON.stringify(obj) // "{"reg":{}}"

// 设置 toJSON 方法时
RegExp.prototype.toJSON = RegExp.prototype.toString;
JSON.stringify(/foo/) // ""/foo/""
复制代码

JSON.parse()

为了处理解析错误,可以将 JSON.parse 方法放在 try...catch 代码块中。

try {
  JSON.parse("'String'");
} catch(e) {
  console.log('parsing error');
}
复制代码

JSON.parse 方法可以接受一个处理函数,作为第二个参数,用法与 JSON.stringify 方法类似。

function f(key, value) {
  if (key === 'a') {
    return value + 10;
  }
  return value;
}

JSON.parse('{"a": 1, "b": 2}', f)
// {a: 11, b: 2}
复制代码

可以做反向操作


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

编程匠艺

编程匠艺

(美)古德利弗(Goodliffe, P.)著 / 韩江,陈玉译 / 电子工业出版社 / 2008-9 / 79.00元

如果你可以编写出合格的代码,但是想更进一步、创作出组织良好而且易于理解的代码,并希望成为一名真正的编程专家或提高现有的职业技能,那么《编程匠艺——编写卓越的代码》都会为你给出答案。本书的内容遍及编程的各个要素,如代码风格、变量命名、错误处理和安全性等。此外,本书还对一些更广泛的编程问题进行了探讨,如有效的团队合作、开发过程和文档编写,等等。本书各章的末尾均提供一些思考问题,这些问题回顾了各章中的一......一起来看看 《编程匠艺》 这本书的介绍吧!

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具