前言
- ECMAScript 缺少传统的面向对象编程语言所具备的某些基本结构,包括类和接口。引用值与传统面向对象编程语言中的类相似,但实现不同。
- 对象被认为是某个特定引用类型的实例。
- 新对象通过使用
new操作符后跟一个构造函数(constructor) 来创建。构造函数就是用来创建新对象的函数。
一、Date
- 要创建日期对象,就使用
new操作符来调用 Date 构造函数:
let now = new Date(); // 创建的对象将保存当前日期和时间
Date.parse()方法接收一个表示日期的字符串参数,尝试将这个字符串转换为表示该日期的毫秒数。
let someDate = new Date(Date.parse("May 23, 2019"));
// 等价于
let someDate = new Date("May 23, 2019");
Date.now()方法返回表示方法执行时日期和时间的毫秒数。toLocaleString()方法返回与浏览器 运行的本地环境一致的日期和时间。toString()方法通常返回带时区信息的日期和时间。
let newDate = new Date("2/14/2022")
console.log(newDate.toLocaleString()); // 2022/2/14 00:00:00
console.log(newDate.toString()); // Mon Feb 14 2022 00:00:00 GMT+0800 (中国标准时间)
Date类型的valueOf()方法根本就不返回字符串,这个方法被重写后返回的是日期的毫秒表示。
二、RegExp
-
表示匹配模式的标记:
g:全局模式,表示查找字符串的全部内容,而不是找到第一个匹配的内容就结束。i:不区分大小写,表示在查找匹配时忽略 pattern 和字符串的大小写。m:多行模式,表示查找到一行文本末尾时会继续查找。y:粘附模式,表示只查找从 lastIndex 开始及之后的字符串。u:Unicode 模式,启用 Unicode 匹配。s:dotAll 模式,表示元字符.匹配任何字符(包括\n或\r)。
-
RegExp 构造函数接收两个参数:模式字符串和(可选的)标记字符串。
// 匹配第一个"bat"或"cat",忽略大小写
let pattern1 = /[bc]at/i;
// 跟 pattern1 一样,只不过是用构造函数创建的
let pattern2 = new RegExp("[bc]at", "i");
三、原始值包装类型
-
ECMAScript 提供了 3 种特殊的引用类型:
Boolean、Number和String。特点是:- 每种包装类型都映射到同名的原始类型。
- 以读模式访问原始值时,后台会实例化一个原始值包装类型的对象,借助这个对象可以操作相应的数据。
- 涉及原始值的语句执行完毕后,包装对象就会被销毁。
-
每当用到某个原始值的方法或属性时,后台都会创建一个相应原始包装类型的对象,从而暴露出操作原始值的各种方法。在以读模式访问字符串值的任何时候,后台都会执行以下三步:
- 创建一个
String类型的实例 - 调用实例上的特定方法
- 销毁实例
- 创建一个
let s1 = "some text";
let s2 = s1.substring(2);
// 让原始值拥有对象的行为
let s1 = new String("some text");
let s2 = s1.substring(2);
s1 = null;
- 引用类型与原始值包装类型的主要区别在于对象的生命周期。
Object构造函数作为一个工厂方法,能够根据传入值的类型返回相应原始值包装类型的实例。
let obj = new Object("some text");
console.log(obj instanceof String); // true
- 理解原始布尔值和
Boolean对象之间的区别非常重要,强烈建议永远不要使用后者。
let falseObject = new Boolean(false);
let falseValue = false;
// typeof 操作符对原始值返回 "boolean",
// 但对引用值返回 "object"。
console.log(typeof falseObject); // object
console.log(typeof falseValue); // boolean
// Boolean 对象是 Boolean 类型的实例,
// 在使用 instaceof 操作符时返回 true,
// 但对原始值则返回 false。
console.log(falseObject instanceof Boolean); // true
console.log(falseValue instanceof Boolean); // false
toFixed()方法返回包含指定小数点位数的数值字符串,toExponential()返回以科学记数法(也称为指数记数法),toPrecision()方法会根据情况返回最合理的输出结果。- ES6 新增了
Number.isInteger()方法,用于辨别一个数值是否保存为整数。
console.log(Number.isInteger(1)); // true
// 小数位的0可能会让人误以为数值是一个浮点值。
console.log(Number.isInteger(1.00)); // true
- 每个
String对象都有一个length属性,表示字符串中字符的数量。 concat()用于将一个或多个字符串拼接成一个新字符串,更常用的方式是使用加号操作符(+)。- 三个从字符串中提取子字符串的方法:
slice()、substr()和substring(),区别如下:
let stringValue = "hello world";
console.log(stringValue.slice(3)); // "lo world"
console.log(stringValue.substring(3)); // "lo world"
console.log(stringValue.substr(3)); // "lo world"
// 对 slice() 和 substring() 而言,第二个参数是提取结束的位置
console.log(stringValue.slice(3, 7)); // "lo w"
console.log(stringValue.substring(3, 7)); // "lo w"
// substr() 的第二个参数表示返回的子字符串数量
console.log(stringValue.substr(3, 7)); // "lo worl"
// -3 会被转换为 8 (长度 11 加上负参数)
console.log(stringValue.slice(-3)); // "rld"
// -3 会转换为 0 ,返回整个字符串
console.log(stringValue.substring(-3)); // "hello world"
// -3 会被转换为 8 (长度 11 加上负参数)
console.log(stringValue.substr(-3)); // "rld"
// slice() 方法将所有负值参数都当成字符串长度加上负参数值
// 第二个参数转换为 7
console.log(stringValue.slice(3, -4)); // "lo w"
// substring() 方法会将所有负参数值都转换为 0
// 第二个参数转换为 0, 等价于 substring(0, 3)
console.log(stringValue.substring(3, -4)); // "hel"
// substr() 方法将第一个负参数值当成字符串长度加上该值,
// 将第二个负参数值转换为 0,即返回的字符串包含零个字符
console.log(stringValue.substr(3, -4)); // "" (empty string)
- 有两个方法用于在字符串中定位子字符串:
indexOf()和lastIndexOf(),indexOf()方法从字符串开头开始查找子字符串,而lastIndexOf()方法从字符串末尾开始查找子字符串。 - 判断字符串中是否包含另一个字符串的方法:
startsWith()、endsWith()和includes()。 - 字符串的原型上暴露了一个
@@iterator方法。
let message = "abc";
// 手动使用迭代器
let stringIterator = message[Symbol.iterator]();
console.log(stringIterator.next()); // {value: "a", done: false}
console.log(stringIterator.next()); // {value: "b", done: false}
console.log(stringIterator.next()); // {value: "c", done: false}
console.log(stringIterator.next()); // {value: undefined, done: true}
- 字符串可以通过解构操作符来解构:
let message = "abcde";
console.log([...message]); // ["a", "b", "c", "d", "e"]
- 模式匹配的方法:
match()、search()、replace()与split()方法:
let text = "cat, bat, sat, fat";
let pattern = /.at/;
// 等价于pattern.exec(text)
let matches = text.match(pattern);
console.log(matches);
// ['cat', index: 0, input: 'cat, bat, sat, fat', groups: undefined]
let pos = text.search(/at/);
console.log(pos); // 1
let result = text.replace("at", "ond");
console.log(result); // "cond, bat, sat, fat"
result = text.replace(/at/g, "ond");
console.log(result); // "cond, bond, sond, fond"
四、单例内置对象
- ECMA-262 对内置对象的定义是“任何由 ECMAScript 实现提供、与宿主环境无关,并在 ECMAScript 程序开始执行时就存在的对象”。两个单例内置对象:
Global和Math。 Global对象为一种兜底对象,它所针对的是不属于任何对象的属性和方法。- 不存在全局变量或全局函数这种东西。在全局作用域中定义的变量和函数都会变成
Global对象的属性。 - 浏览器将
window对象实现为Global对象的代理。 - 调用一个简单返回
this的函数是在任何执行上下文中获取Global对象的通用方式。
// 当一个函数在没有明确指定 this 值的情况下执行时,this 值等于 Global 对象
let global = function() {
return this;
}();