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()
。