基础语法部分
语句和表达式
语句(statement)
是为了完成某种任务而进行的操作,通常以分号结尾,一个分号就表示一个语句结束。
表达式(expression)
,指一个为了得到返回值的计算式,不需要分号结尾。
两者的区别在于,语句主要为了进行某种操作,一般情况下不需要返回值;表达式则是为了得到返回值,一定会返回一个值。
变量
量是对“值”的引用,使用变量等同于引用一个值。
JavaScript引擎的工作方式是,先解析代码,获取所有被声明的变量,然后再一行一行地运行。这造成的结果,就是所有的变量的声明语句,都会被提升到代码的头部,这就叫做变量提升(hoisting)。
Note
:变量提升只对var命令声明的变量有效。
区块
JavaScript使用大括号,将多个相关的语句组合在一起,称为“区块”(block),区块不构成单独的作用域(scope)。也就是说,区块中的变量与区块外的变量,属于同一个作用域。
因此,单独使用的区块意义不大,区块往往用来构成例如如for、if、while等其他更复杂的语法结构。
数据类型
JavaScript的数据类型可以分为以下几种:
- 基本类型
1、 数值(number)
2、 字符串(string)
3、 布尔值(boolean) - 复杂类型
4、 对象(object)
5、 数组(array)
6、 函数(function) - 特殊类型
7、 undefined
8、 null
typeof运算符
typeof运算符可以返回一个值的数据类型,可以用来检查一个没有声明的变量,而不报错:
if (typeof a === "undefined") {
.....
}
null与undefined
null表示空值,即该处的值现在为空,例如函数传参。
undefined表示“未定义”。
布尔值转换
undefined、null、false、0、NaN以及空字符会被自动转为布尔值false,其余值包括空数组和空对象都会转换为true。
数值
JavaScript内部,所有数字都是以64位浮点数形式储存,即使整数也是如此。
Number.MAX_VALUE
与Number.MIN_VALUE
表示了最大值和最小值。
NaN是JavaScript的特殊值,表示“非数字”(Not a Number),主要出现在将字符串解析成数字出错的场合。它不等于任何值,包括它本身。可以通过isNaN
函数来判断变量是否是NaN(最好先判断一下变量类型),也可以利用NaN!=NaN的特性来判断:
function IsNaN(value) {
return value !== value;
}
字符串
字符串可以被视为字符数组,但是无法改变字符串之中的单个字符。同样,字符串也无法直接使用数组的方法,必须通过call方法间接使用。在JavaScript引擎内部,所有字符都用Unicode表示,每个字符在JavaScript内部都是以16位的UTF-16格式储存。
Base64
Base64是一种编码方法,可以将任意字符转成可打印字符。使用这种编码方法,主要不是为了加密,而是为了不出现特殊字符,简化程序的处理。
JavaScript提供了用于Base64转码ASCII字符串的相关方法:
btoa():字符串或二进制值转为Base64编码
atob():Base64编码转为原来的编码
而对于非ASCII编码的字符串,必须中间插入一个转码环节:
function b64Encode(str) {
return btoa(encodeURIComponent(str));
}
function b64Decode(str) {
return decodeURIComponent(atob(str));
}
对象
JavaScript的所有数据都可以被视为对象。创建对象的方法可以分为三种:
var o1 = {};
var o2 = new Object();
var o3 = Object.create(null);
对象的所有键名都是字符串,JavaScript规定,如果行首是大括号,一律解释为语句(即代码块)。如果要解释为表达式(即对象),必须在大括号前加上圆括号。
数组
在JavaScript中,任何类型都可以被放进数组。而本质上,数组是一种特殊的对象,因此,使用typeof
运算符获得的结果仍是object
,其特殊性体现在,它的键名是按次序排列的一组整数,而且在取键值时候同样转换为字符串。
数组的length属性,返回数组的成员数量,它是一个动态的值,因为数组的key不需要连续,所以length值等于键名中的最大整数加上1。
length属性是可写的。如果人为设置一个小于当前成员个数的值,该数组的成员会自动减少到length设置的值。将数组清空的一个有效方法,就是将length属性设为0。
值得注意的是,由于数组本质上是对象的一种,所以我们可以为数组添加属性,但是这不影响length属性的值。
检查某个键名是否存在的运算符in
,适用于对象,也适用于数组。如果键名处是空位,则返回false。
for...in
循环不仅可以遍历对象,也可以遍历数组,毕竟数组只是一种特殊对象.
Note:
但是,for...in
不仅会遍历数组所有的数字键,还会遍历非数字键,因此更推荐使用for
来遍历数组。
当数组的某个位置是空元素,即两个逗号之间没有任何值,我们称该数组存在空位,对其读取的返回值为undefined
。length属性不过滤空位,因此,使用for
进行数组遍历,要注意处理。
如果是空位,使用数组的forEach方法、for...in结构、以及Object.keys方法进行遍历,空位都会被跳过。但如果某个位置是undefined,遍历的时候就不会被跳过。
函数
在JavaScript中,函数也是一种对象。它的length
属性返回函数预期传入的参数个数,即函数定义之中的参数个数。
Javascript只有两种作用域:一种是全局作用域,变量在整个程序中一直存在,所有地方都可以读取;另一种是函数作用域,变量只在函数内部存在。
函数本身也是一个值,也有自己的作用域。它的作用域与变量一样,就是其声明时所在的作用域,与其运行时所在的作用域无关。
函数参数如果是原始类型的值(数值、字符串、布尔值),传递方式是传值传递;如果函数参数是复合类型的值(数组、对象、其他函数),传递方式是传址传递。
JavaScript通过arguments
对象来为函数提供不定数目的参数,该对象包含了函数运行时的所有参数。通过arguments对象的length属性,可以判断函数调用时到底带几个参数。
arguments
对象并不是一个数组,数组专有的方法不能在arguments对象上直接使用。而是通过apply
函数或者将它转化为数组来使用。
arguments
对象带有一个callee属性,返回它所对应的原函数,可以通过arguments.callee
,达到调用函数自身的目的。
闭包就是定义在函数内部的函数,即能够读取其他函数内部变量的函数。在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁,最大的特点,就是它可以“记住”诞生的环境。
闭包的最大用处有两个,一个是可以读取函数内部的变量,另一个就是让这些变量始终保持在内存中,即闭包可以使得它诞生环境一直存在,因此,闭包可以封装对象的私有属性和私有方法。
note:
外层函数每次运行,都会生成一个新的闭包,而这个闭包又会保留外层函数的内部变量,所以内存消耗很大。
运算符
加法运算符可以完成两种运算,既可以处理算术的加法,也可以用作字符串连接。如果运算子是对象,先自动转成原始类型的值。只要有一个运算子是字符串,则两个运算子都转为字符串,执行字符串连接运算。否则,两个运算子都转为数值,执行加法运算。
相等运算符==
比较两个值是否相等,严格相等运算符===
比较它们是否为“同一个值”。
如果两个值不是同一类型,严格相等运算符===
直接返回false,而相等运算符==
会将它们转化成同一个类型,再用严格相等运算符进行比较。
对于严格相等运算符:
- 两个值的类型不同,直接返回false.
- 同一类型的原始类型的值,相同就返回true,否则返回false。
- 复合类型的数据比较时,不是比较它们的值是否相等,而是比较它们是否指向同一个对象。
对于相等运算符:
- 原始类型的数据会转换成数值类型再进行比较
- 对象与原始类型的值比较时,对象转化成原始类型的值,再进行比较。
- undefined和null与其他类型的值比较时,结果都为false,它们互相比较时结果为true。
取反运算符有转换数据类型的作用,!!x 等同于Boolean(x).
左移运算符<<
表示将一个数的二进制值向左移动指定的位数,尾部补0,即乘以2的指定次方(最高位即符号位不参与移动)。
右移运算符>>
表示将一个数的二进制值向右移动指定的位数,头部补0,即除以2的指定次方(最高位即符号位不参与移动)。
带符号位的右移运算符>>>
表示将一个数的二进制形式向右移动,包括符号位也参与移动,头部补0。
void运算符的作用是执行一个表达式,然后不返回任何值,或者说返回undefined。
数据类型转换
强制转换主要指使用Number
、String
和Boolean
三个构造函数,手动将各种类型的值,转换成数字、字符串或者布尔值。
使用Number
函数,可以将任意类型的值转化成数值。对于原始类型(字符串、布尔值、undefined和null),它们都能被Number转成数值或NaN。对于复杂类型,默认情况下,会返回NaN。
使用Boolean函数,可以将任意类型的变量转为布尔值。除了undefined
,null
,NaN
,0
,±0
以及空字符串会返回false之外,其余的都返回true。