JS 中有对象字面量。对象是花括号及其中的内容,其中的内容非常类似键值对的形式。属性名和方法名作键(字符串类型," 可以省略),属性值和方法定义作值。键和值用冒号( : )分隔,键值对间用逗号( , )分隔。
除了使用对象字面量创建对象外,还可以使用 new 关键字创建对象。使用 new 关键字 和 Object() 构造函数可以创建一个对象。不过这个对象是空对象,随后使用 点语法 向该对象添加属性和方法。
为对象不存在的属性赋值,即为向对象中添加该属性。
除了『天然』存在的 Object 构造函数外,你也可以自定义一个构造函数,随后使用自定义的构造函数创建对象
# 1. JavaScript 类和对象
实例化对象有几种方式:
| # | 方式 | 
|---|---|
| 1 | 使用内置类 | 
| 2 | new Object | 
| 3 | 对象字面量 | 
| 4 | 构造函数 | 
| 5 | 原型对象模式 | 
# 使用内置类
JavaScript 有几个内置类,例如:Number 、Array 、String 、Date 和 Math 。这些内置类都有自己的属性和方法。此外,JavaScript 还提供了一种非常优秀的面向对象编程结构,所以我们也可以创建自己的自定义类。
使用对象语法:
var x = new Number("5");
# new Object
new Object() 方式利用了『为对象不存在的属性赋值,即为该对象动态添加属性』的语法点。
var obj = new Object(); // 创建一个无属性的空对象
obj.name = 'tom';
obj.age = 20;
obj.sayHello = function () {
  ...
};
# 对象字面量
还可以使用 { } 语法创建对象(及对象字面量语法),此时可以直接为对象属性和方法赋值:
var obje = {
  name : "tom",
  age: 20,
  sayHello : function () {
    console.info('hello');
  }
}
除了 点语法 ,还可以通过 []语法 来访问对象的成员。
# 构造函数
function Human(first, last) {
  this.first = first;
  this.last = last;
}
var benjamin = new Human('Franklin', 'Benjamin');
benjaminS.sayHello = function() {
  ...
};
# 利用原型对象模式定义类
如果想定义一个具有可重用性的类,可以结合构造函数和原型对象两种方式共同实现(其实,单独一种也可以实现,不过不建议如此)。
通常,是在构造方法中定义类的属性,并对其初始化:
function Circle(r) {  
  this.r = r; // 实例属性
}  
Circle.PI = 3.14159; // 静态属性
通过原型对象定义其所具有的的方法:
Circle.prototype.area = function() {  
  return Circle.PI * this.r * this.r;  
};
如果有多个方法需要定义,protorype 也可以写成如下形式:
Circle.prototype = {
  area: function () { ... },
  xxx: function() { ... },
  yyy: function() { ... },
  zzz: function() { ... }
};
# 2. JavaScript 继承
由于 JavaScript 语言本身的缺陷,导致 JavaScript 本身并没有提供 class 关键字,而语法层面继承更是无从谈起。
因此,如何实现继承有各种不同的方案。其中,截至目前为止(不考虑 ES6、ES7 语法的改进),最好的继承实现方案是:寄生组合式继承 。
寄生组合式继承实现继承需要完成两部分工作:
- 构造函数属性的继承 
- 建立子类和父类原型的链接 
要实现第一部分工作可以在子类中调用超类的构造函数:
SuperType.apply(this, arguments);
要实现第二部分工作则可以使用业内通用的 inherit 方法。
inherit 方法逻辑上干了类似如下工作:
function object(o) {
    function F() {}
    F.prototype = o;
    return new F();
}
/**
 * 子类的原型对象是父类原型对象的一个实例。
 * 否则,多个子类公用父类的同一个原型对象,会有潜在隐患:一个子类改变了其父类原型对象中的内容,对其它子类都有影响。
 */
function inherit(subType, superType) {
    var prototype = Object.create(superType.prototype);
    prototype.constructor = subType; // 增强对象
    subType.prototype = prototype; // 指定对象
}
function SuperType(name) {
    this.name = name;
}
SuperType.prototype.sayName = function () {
    console.log(this.name)
};
function SubType(name, age) {
    SuperType.call(this, name);
    this.age = age;
}
inherit(SubType, SuperType);
# 3. 内置类
# String 类
| # | 说明 | 
|---|---|
| length 属性 | 返回字符串中的字符数 | 
| .chatAt 方法 | 以索引为参数, 返回指定位置的字符 | 
| .indexOf 方法 | 在字符串中查找指定字符串, 返回它首次出现的索引位置 | 
| .lastIndexOf 方法 | 在字符串中查找指定字符串, 返回它最后一次出现的索引位置 | 
| .substring 方法 | 返回两个索引之间的字符串, 两个参数前闭后开 | 
| .split 方法 | 以参数指定符号分割字符串, 返回字符串数组 | 
| .trim 方法 | 去掉字符串前后空格 | 
| .replace 方法 | 在字符串中查找指定字符,替换成另一个参数。 只替换第一个。 | 
# Number 类
| # | 说明 | 
|---|---|
| isNaN 全局函数 | 检擦参数是否是数字, 返回 boolean 值o | 
| .toFixed 方法 | 将当前数字对象四舍五入至指定小数位数, 返回字符串 | 
# 全局 Math 对象
| 方法 | 说明 | 
|---|---|
| round(n) | 将参数 n 四舍五入至离它最近的整数 | 
| sqrt(n) | 求参数 n 的平方根 | 
| random() | 获得一个 0 到 1 之间的随机数 | 
# Array 对象
Array 对象用于在单个的变量中存储多个值。
创建 Array 对象的语法:
new Array();	// 返回的数组为空,length 字段为 0。
new Array(size); // 指定个数、元素为 undefined 的数组。
new Array(element0, element1, ..., elementn);
- length 属性 - 设置或返回数组中元素的数目
 
- concat 方法 - 连接两个或更多的数组,并返回结果。 
- arrayObject.concat(array1, array2, ......, arrayN) 
 
- join 方法 - 把数组的所有元素放入一个字符串。元素通过指定的分隔符进行分隔。 
- arrayObject.join(separator) 
 
- pop 方法 - 删除并返回数组的最后一个元素 
- arrayObject.pop() 
 
- push 方法 - 向数组的末尾添加一个或更多元素,并返回新的长度。 
- arrayObject.push(newelement1, newelement2, ....,newelementN) 
 
- sort 方法 - 对数组的元素进行排序 
- 如果想按照其他标准进行排序,就需要提供比较函数作为参数。 
- arrayObject.sort(sortby) 
 
- reverse 方法 - 颠倒数组中元素的顺序。 
- 该方法会改变原来的数组,而不会创建新的数组。 
 
- shift 方法 - 删除并返回数组的第一个元素 
- 该方法不创建新数组,而是直接修改原有的 arrayObject。 
- 要删除并返回数组的最后一个元素,请使用 pop() 方法。 
- arrayObject.shift() 
 
- toString 方法 - 把数组转换为字符串,并返回结果。 
- 当数组用于字符串环境时,JavaScript 会调用这一方法将数组自动转换成字符串。 
- arrayObject.toString() 
 
- slice 方法 - 切片,从数组中截取指定一部分 
- arrayObject.slice(start,end) 
 
# RegExp 对象
RegExp 对象表示正则表达式,它是对字符串执行模式匹配的强大工具。
创建 RegExp 对象的语法:
var reg1 = new RegExp(pattern);
var reg2 = new RegExp(pattern, attributes);
使用 test 方法检测参数字符串是否符合/匹配指定模式:
reg1.test('...');
reg2.test('...');
例如:
var str = "hello world";
var patt1 = new RegExp("ll");
var result = patt1.test(str);
console.info(result);
# 时间与日期
JavaScript 提供了 Date 类的对象来表示和处理时间/日期。
Date 类型内置了一系列获取和设置日期时间信息的方法。
# Date 类型
Date 类型使用 UTC(国际协调时间,又称世界统一时间) 1970 年 1 月 1 日午夜(零时)开始经过的毫秒来保存日期。
创建一个日期对象,使用 new 运算符和 Date 构造函数即可。在构造方法不传递参数的情况下,新建的对象自动获取当前的时间和日期。
JavaScript 提供了两个方法,Date.parse() 和 Date.UTC()。Date.parse() 方法接收一个表示日期的字符串参数,然后尝试根据这个字符串返回相应的毫秒数。
常见的字符串格式为:
- '月/日/年',如 '6/13/2011';
- '英文月名 日, 年',如 'May 25, 2004';
如果 Date.parse() 没有传入或者不是标准的日期格式,那么就会返回 NaN。
如果想输出指定的日期,那么把 Date.parse() 传入 Date 构造函数里。
Date 对象及其在不同浏览器中的实现有许多奇怪的行为。其中有一种倾向是将超出的逻辑范围的值替换成当前的值,以便生成输出。
Date.UTC() 方法同样也返回表示日期的毫秒数,但它与 Date.parse() 在构建值时使用不同的信息。(年份,月[0-11],日[1-31],小时数[0-23] ,分钟,秒以及毫秒)。只有前两个参数是必须的。
如果 Date.UTC() 参数传递错误,那么就会出现负值或者 NaN 等非法信息。
如果要输出指定日期,那么直接把 Date.UTC() 传入 Date 构造方法里即可。
# 格式化方法
Date 类型还有一些专门用于将日期格式化为字符串的方法。
var box = new Date();
box.toDateString();     // 以特定的格式显示星期几、月、日和年
box.toTimeString();     // 以特定的格式显示时、分、秒和时区
box.toUTCString();      // 以特定的格式显示完整的 UTC 日期。
# 组件方法
组件方法,是为我们单独获取你想要的各种时间/日期而提供的方法。
var box = new Date();
box.getTime();     // 获取日期的毫秒数,和 valueOf()返回一致
box.setTime(100);  // 以毫秒数设置日期,会改变整个日期
box.getFullYear(); // 获取四位年份
box.setFullYear(2012);  // 设置四位年份,返回的是毫秒数
box.getMonth();     // 获取月份,没指定月份,从 0 开始算起
box.setMonth(11);   // 设置月份
box.getDate();  // 获取日期
box.setDate(8); // 设置日期,返回毫秒数
box.getDay();   // 返回星期几,0 表示星期日,6 表示星期六
box.setDay(2);  // 设置星期几
box.getHours();     // 返回时
box.setHours(12);   // 设置时
box.getMinutes();   // 返回分钟
box.setMinutes(22); // 设置分钟
box.getSeconds();   // 返回秒数
box.setSeconds(44);     // 设置秒数
box.getMilliseconds();  // 返回毫秒数
box.setMilliseconds();  // 设置毫秒数
box.getTimezoneOffset()); // 返回本地时间和 UTC 时间相差的分钟数
以上方法除了 getTimezoneOffset(),其他都具有 UTC 功能,例如 setDate() 及 getDate() 获取星期几,那么就会有 setUTCDate() 及 getUTCDate() 。