JavaScript简介
JavaScript是一种网络脚本语言。在Web应用开发中,JavaScript被广泛应用于表单校验、浏览器事件响应、HTML页面中嵌入动态文本等等。因此对于web开发人员来说,了解JavaScript是很有必要的。
我们常说的JavaScript实际是包含三个部分:
ECMAScript
,描述该语言的语法和对象;- 文档对象模型(
DOM
),描述处理网页内容的方法和接口; - 浏览器对象模型(
BOM
),描述与浏览器进行交互的方法和接口。
向HTML页面中插入JavaScript脚本的主要方法,就是使用
script
元素。我们可以直接在script
标签中定义脚本内容,也可以通过script
元素的src
属性导入外部的脚本内容。
JavaScript的基本概念
JavaScript语法
标识符,指的是变量、函数、属性的名字,或者函数的参数。
- JavaScript中的所有变量、函数名和操作符都是区分大小写的。
- 标识符的定义可以是字母、下划线、美元符号或数字的组合,但标识符的首字母不能是数字。
- 标识符不能是关键字或保留字。
JavaScript中的数据类型
ECMAScript中有5种基本数据类型(Undefined/Null/Boolean/Number/String)和一种复杂数据类型Object。通过操作符typeof
可以检测变量的数据类型。
测试效果图如下所示:
typeof操作符的返回值结果可能是:undefined,boolean,number,string,function,object等等。但函数在ECMAScript中是对象,并不是一种数据结构。但是函数是一些特殊属性的,因此能够使用
typeof
操作符区分函数和对象是很有必要的。
Undefined类型
Undefinded类型的取值只有一个undefinded
,表示用var声明但未初始化的变量的值。
Null类型
Null类型的取值只有一个null
,表示的是一个空对象指针。表示对象的变量还没有真正保存对象。
实际上,undefined
值是派生自null
值的,null == undefined
表达式的结果就是true
。
Boolean类型
Boolean类型只有两个字面值:true
和false
。
通过Boolean()
转型函数,能把其他类型的值,变为Boolean类型的值,转换规则如下:
数据类型 | 转换为true的值 | 转换为false的值 |
---|---|---|
String | 任何非空字符串 | “”,空字符串 |
Number | 任何非零数值 | 0和NaN |
Object | 任何对象 | null |
Undefined | 不适用 | undefined |
测试效果图如下:
Number类型
Number类型,默认表示的是十进制数值。表示八进制时第一位必须是“0”,表示十六进制时必须以“0x”开头。
还可以用科学计数法表示数值(“3e4”表示的是“3 * 10 * 10 * 10 * 10”)。
数值表示的范围是:“5e-324” 到 “1.798e+308”,如果超出范围,即表示是正无穷(Infinity)或负无穷(-Infinity)。
通过isFinite()
函数可以检测一个数值是否有穷,通过isNaN()
函数可以检测一个表示是否非数字。
测试结果说明如下:
- 用八进制或十六进制表示的数字,浏览器会默认转换成十进制的数字进行表示。(八进制“017”表示十进制的15,十六进制“0xF”表示十进制的15)。
- JS里面的运算结果并不是那么准确。如 0.1 + 0.2 = 0.300…04,而且当数值超过范围时,即正负无穷是无法进行运算的的。
isNaN()
函数测试时,会默认尝试对测试内容进行类型转换,无法转换为Number类型的,返回结果才是true。
将其他类型的变量转换成Number类型时,常用的方法有parseInt()
和parseFloat()
。
parseInt()
的解析规则是:从第一个数字字符开始,到最后一个非数字字符为止,如果无法解析就会返回NaN;同时还可以传入第二个参数表示要解析内容使用的进制基数(解析内容有可能会导致困惑,可以通过基数来指定使用的进制)。
parserFloat()
的解析规则是:从第一个字符开始,到一个无效的浮点数字字符为止,如果无法解析就会返回NaN。而且只能解析十进制数字,但可以解析科学计算法表示的数字。
String类型
String类型,用单引号(’’)或双引号("")包含起来的字符序列。如果需要表示特殊符合,可以用转义字符表示(如"\n"表示换行)。通过字符串的length
属性可以获取该字符串的长度。
Object类型
ECMAScript中的对象其实就是一组数据和功能的集合。Object中的所有属性和方法也存在于更具体的对象中(和Java一样)。
Object中的实例和方法如下:
constructor
: 构造函数。hasOwnProperty(propertyName)
: 检查当前对象是否含有给定的属性。isPrototypeOf(object)
: 用于检查传入的对象是否是传入对象的原型。propertyIsEnumerable(propertyName)
: 检查给定的属性是否能够使用for-in
语句来枚举。toLocaleString()
: 返回对象的字符串表示,与当前环境相关。toString()
: 返回对象的字符串表示。valueOf()
: 返回对象的字符串、数值或布尔值表示。
函数
ECMAScript中的函数不介意传递进来多少个参数,也不在乎传进来参数是什么数据类型。
可以在函数内用arguments获取或操作实际传入的参数数组。
测试效果图如下:
由于函数与实际传入的参数无关,也就是说不存在方法重载一说。如果同一个作用域内的两个方法重名,实际上是进行了方法的重写。
这里需要说明的是:JS里面有一个“声明提升”的概念。只要在对应的作用域内,JavaScript中可以先使用再声明变量和方法。这里就是,第二次testOverload()
的方法声明覆盖了第一个声明,所以实际调用的是第二次声明的方法。
JavaScript中的引用类型
ECMAScript提供了很多原生引用类型(例如Object),以便开发人员用以实现常见的计算任务。下面来进行这些引用类型的学习总结。
Object类型
Object类型的实例可以通过new
关键字构建,也可以通过字面量构建。
测试效果图如下:
Array类型
Array类型的创建非常简单,可以使用new
关键字,也可以给定所有元素。同时可以通过length
属性获取该数组的长度。
测试效果如下:
Array中常用的工具方法汇总说明如下:
方法名称 | 方法描述 |
---|---|
join() | 返回所有的数组项,可接收一个参数作为数组项之间的分隔符,默认是逗号 |
push() | 往数组末尾添加多个元素,并返回修改后数组的长度 |
pop() | 取出数组末尾的最后一个元素,并返回修改后数组的长度 |
shift() | 从数组头部取出一个元素,并返回这个元素 |
unshift() | 从数组头部添加多个元素,并返回修改后数组的长度 |
reverse() | 反转数组项的顺序 |
sort() | 按首字母的升序进行排序数组,允许接收一个方法参数作为实际排序的方法 |
concat() | 将参数中的数据项加入数组中,并返回新数组—不会改变原数组 |
slice() | 截取“起始位置”到“截止位置”的所有元素,返回新数组。不会影响原始数组,截取时是“包头不包尾”。 |
splice() | 对原始数组进行操作,返回从原始数组删除的元素。第一个参数是开始操作的数组下标,第二个参数是要删除元素个数,后面的参数就是要添加的参数 |
indexOf() | 从第二个参数对应的下标开始,从前往后查找数组中与第一个参数内容相同的元素对应的下标 |
lastIndexOf() | 从第二个参数对应的下标开始,从后往前查找数组中与第一个参数内容相同的元素对应的下标 |
every() | 对数组中的每一项运行给定函数,如果都返回true,则返回结果为true |
filter() | 对数组中的每一项运行给定函数,返回结果为true的项组成的数组 |
forEach() | 对数组中的每一项运行给定函数,无返回值 |
map() | 对数组中的每一项运行给定函数,返回结果组成的数组 |
some() | 运行给定函数,只要数组中某一项结果为true,则返回结果为true |
reduce() | 从第一项到最后一项,归并所有元素,返回最终的结果 |
reduceRight() | 从最后一项到第一项,归并所有元素,返回最终的结果 |
操作数组元素方法的效果图如下:
与Array中元素排序相关方法的效果图如下:
与Array中元素下标相关方法的效果图如下:
Array中元素迭代相关方法效果图如下:
Date类型
JavaScript中Date类型保存的日期范围是: 1970年1月1日之前或之后的285616年。
常用的方法汇总如下:
方法名称 | 描述 |
---|---|
new Date() | 获取当前时间 |
toDateString() | 显示星期几、月、日和年 |
toTimeString() | 显示时、分、秒和时区 |
toLocaleDateString() | 基于当前地区的格式显示星期几、月、日和年 |
toLocaleTimeString() | 基于当前地区的格式显示时、分、秒 |
toUTCString() | 显示格式完整的UTC日期 |
getTime() | 获取时间毫秒数 |
getFullYear() | 返回四位数的年份 |
getMonth() | 返回日期中的月份,其中0表示一月,11表示十二月 |
getDate() | 返回日期月份中的天数(1到31) |
getDay() | 返回日期中星期的星期几(其中0表示星期日,6表示星期六) |
getHours() | 返回日期中的小时数(0到23) |
Date相关方法的测试效果图如下:
开发中常用的一个解析日期的JavaScript方法如下:
/**
* time: Date对象或时间毫秒数
* format: 自定义输出格式
*/
function parseTime (time, format) {
if (arguments.length === 0) {
return null;
}
var tFormat = format || '{y}-{M}-{d} {H}:{m}:{s}';
var date;
if (typeof time === 'object') {
// 传入的第一个参数是Date对象时
date = time;
} else {
// 传入的第一个参数是时间毫秒数时
date = new Date(time);
}
var formatObj = {
y: date.getFullYear(),
M: date.getMonth() + 1,
d: date.getDate(),
H: date.getHours(),
h: (date.getHours() > 12) ? (date.getHours() - 12) : date.getHours(),
m: date.getMinutes(),
s: date.getSeconds(),
w: date.getDay()
}
var timeStr = tFormat.replace(/{(y|M|d|H|h|m|s|w)+}/g, (result, key) => {
var value = formatObj[key]
if (key === 'w') return ['一', '二', '三', '四', '五', '六', '日'][value - 1]
if (result.length > 0 && value < 10) {
value = '0' + value
}
return value || 0
})
return timeStr
}
这个工具方法的测试效果图如下:
RegExp类型
ECMAScript 通过RegExp类型来支持正则表达式。表达式格式如下:
var exp = /pattern/flags
pattern
,表示的是匹配的模板,语法就是正则表达式的语法。flags
,表示匹配的模式。g表示全局模式,i表示不区分大写模式,m表示多行模式。
常用的方法有:
test()
,检测是否存在模板;exec()
,执行匹配,返回匹配的结果。
测试的JS源码如下:
var message1 = "asdfghjkl123456";
// 检测message1中是否含有字符串"jkla"
var pattern1 = /jkla/g;
console.log(pattern1.test(message1));
// 检测message1中是否含有字符集合(j,k,l,a)中的某一个字符
var pattern2 = /[jkla]/g;
console.log(pattern2.test(message1));
var message2 = "AsdFGHJkL123456jKL"
var pattern3 = /jkl/gi;
var matchResult = pattern3.exec(message2);
console.log("将要检测的内容:" +matchResult.input);
console.log("匹配到的第一个元素所在下标:" + matchResult.index);
console.log("匹配到的内容:" + matchResult);
测试的效果图如下:
基本包装类型
typeof
和instanceof
的区别:typeof
是一元操作符,获取某个数据的类型(类似语句typeof a
的作用是:获取变量a的数据类型)。instanceof
,判断某个构造函数的prototype
属性是否存在于另外一个要检测对象的原型链上(类似语句a instanceof b
的作用是:判断a是否是b的实例)
Boolean,Number,String是基本类型对应的包装类型。
常用的方法汇总如下:
方法名称 | 描述 |
---|---|
Number.toString(arg) | 返回arg进制数值的字符串形式 |
Number.toFixed(arg) | 返回arg个小数位数值的字符串形式 |
Number.toExponential(arg) | 返回科学计算法表示的字符串形式,arg为小数个数 |
Number.toPrecision() | 用最合适的方法返回字符串形式的该数值(过长或过短会用科学计数法表示) |
String.charAt(arg) | 返回该字符在字符串中的下标位置 |
String.substr(arg0,arg1) | 截取部分字符串 |
测试效果图如下:
内置对象Global和Math
Global对象在某种意义上是一个“兜底儿对象”。换句话说,不属于任何其他对象的属性和方法,最终都是它的属性和方法。
Math对象里面的方法,是用于辅助完成简单和复杂的数学计算。
常用的方法汇总如下:
方法名称 | 描述 |
---|---|
Math.max() | 确定一组数值中的最大值 |
Math.min() | 确定一组数值中的最小值 |
Math.ceil() | 执行向上舍入的取整方法 |
Math.round() | 执行四舍五入的取整方法 |
Math.floor() | 执行向下舍入的取整方法 |
Math.random() | 返回一个0-1之间的随机数 |
Math.abs(num) | 返回num的绝对值 |
测试效果图如下: