3.1 语法
3.1.1 区分大小写
test和Test表示两个不同的变量
3.1.2 标识符
标识符:指变量,函数,属性的名字或者函数的参数
标识符命名规则:
1.第一个字母必须是一个字母,下划线(_),或一个美元符号$
2.其他字符可以是字母,下划线,美元符号或数字
3.不可以使用关键字作为标识符
4。推荐使用驼峰命名法,比如:changeColor
3.1.3 注释
//单行注释
/*
* 多行注释
*
*/
3.1.4 严格模式
ECMAScript5 引入了严格模式概念
在顶部添加代码:'user strict';
3.1.5 语句:
不能省略语句结尾分号原因:
- 如果省略,将会由解析器确定语句的结尾,
- 加上分号,会避免很多错误(例如不完整的输入)
- 代码结尾没有分号,会导致压缩错误;
- 提高性能,解析器不用在推测哪里插入分号耗费时间
if (test)
alert(test) //有效,但容易出错,不推荐使用
if (test) {
alert(test) //推荐使用
}
3.2 关键字和保留字
关键字和保留字都不能作为标识符或者属性
3.3 变量
js中每个变量仅仅是一个用来保存值的占位符而已
3.4 数据类型
3.4.1 typeof操作符
typeof是一个操作符,而不是函数
用来检测基本类型变量的数据类型
typeof 15 ==> number
3.4.2 Undefined 类型
//声明了未初始化的message,和未声明的age,都返回undefined
var message;
alert(message) ==> "undefined";
alert(age) ==> "undefined";
3.4.3 Null类型
typeof null ==> 'object' ==> 从逻辑上讲,null表示一个空对象指针,所以会返回object
null 和 undefined 关系:
- undefined 派生自null ,所以 null == undefined ==> true;
- 无论什么情况下,都没有必要把一个变量的值显式的设置为undefined;
- 如果定义的变量准备在将来用于保存对象,那么最好将该变量初始化为null而不是其他值;
3.4.4 Boolean 类型
Boolean类型的字面值true和false是区分大小写的,也就是说True和False都不是Boolean值,只是标识符;
3.4.5 Number类型
八进制字面量在严格模式下是无效的,会导致报错
- 浮点数值
浮点数:该数值中必须包含一个小数点,并且小数点后面必须至少有一位数字
var floatNum = .1 //有效,但不推荐
浮点数存在的问题:
0.1 + 0.2 ==> 0.30000000000000004
解决方案: 使用toFixed() 来保留小数点后几位
这是基于IEEE754数值的浮点计算通病,其他语言也会出现这样的问题
if (a + b == 0.3){ //这样的判断在浮点数下,会导致错误
alert('you got 0.3')
}
数值范围:
Infinity和-InfinityNaN
非数值,是一个特殊的数值,用来表示一个本来要返回数值的操作数未返回数值的情况(防止错误)
var aa = 'ww';
0/aa ==> NaN
js中,任何数值除以非数值会返回NaN,因此不会影响代码执行
NaN拥有两个非同寻常的特点:
- 任何涉及NaN的操作,都会返回NaN
- NaN与任何值都不相等,包括自己;
isNaN() 检测是否是数值有问题:
isNaN('') ==> false
isNaN()把空字符串或空格当作0处理
- 数值转换
有三个函数可以把非数值转换为数值
Number() ==> 用于任何数据类型
由于Number在转换字符串时比较复杂而且不够合理,因此在处理整数上常用
parseInt()函数;
parseInt()和parseFloat() ==> 用于把字符串转为数值
parseInt原理:
parseInt()函数在转换字符串时,更多的是看其是否符合数值模式。会忽略字符串前面的空格,直至找到第一个非空字符。如果第一个字符不是
数字或者负号,parseInt()会返回NaN。也就是说,parseInt()转换空字符串会返回NaN,如果第一个是数字字符,parseInt()会继续解析第二个字符,
直到解析完所有后续字符或者遇到一个非数字字符
例如:
parseInt('123blue') ==> 123
parseInt('') ==> NaN
parseInt(22.5) ==> 22
parseInt接收第二个参数,表示转换时使用的基数
parseInt(12,10) ==> 表示用十进制来解析
不指定基数意味着让parseInt()自己决定如何解析输入的字符串,为了避免错误的解析,建议无论什么情况下都明确指定基数;
parseFloat()和parseInt()区别:
- 都是字符串中第一个小数点有效,第二个无效
parseInt('22.34.45') ==》 22
parseFloat('22.34.45') ==> 22.34
2.parseFloat() 始终会忽略前导的0,且parseFloat()只解析十进制的值
parseFloat('1234blue') ==》 1234
parseFloat('oxA') ==》 0
parseFloat('22.5') ==> 22.5
parseFloat('22.34.5') ==> 22.34
parseFloat('0908.5') ==> 908.5
3.4.6 String类型
1.转义字符:
\n 换行 ==》 'he said, \n'
\' 单引号 ==》 'he said,\'hey.\''
\" 双引号 ==》 'he said,\"hey.\''
2.转换为字符串
toString() ==> var num = 123; num.toString() ==> '123'
toString()问题:null和undefined没有这个方法,调用时会报错
如果不确定需要转换的字符串是不是null和undefined,则建议使用String()
String()详解:
- 如果值有toString(),则调用;
- 如果值为null,则返回null;
- 如果值为undefined,则返回undefined;
3.4.7 Object 类型
Object类型所具有的任何属性和方法也同样存在于更具体的对象中
3.5 操作符
3.5.1 一元操作符
只能操作一个值的操作符叫一元操作符
- 递增和递减操作符
前置型:变量的值在语句被求值以前改变
++age == age = age + 1;
--age == age = age - 1;
后置型:递增递减操作是在语句被求值之后才执行
var num1 = 2;
var num2 = 20;
var num3 = num1-- + num2 ==> 22;
var num4 = num1 + num2 ==> 21
- 一元加和减操作符
一元加操作符
+'01' ==> 1
+'1.1' ==> 1.1
+'z' ==> NaN
+false ==> 0
一元减操作符
-‘01’ ==》 -1
-‘1.1’ ==》 -1.1
-‘z’ ==> NaN
-false ==> -0
3.5.2 布尔操作符
- 逻辑非
!{} ==> false
!{name:'wang'} ==> false
逻辑与
&&
逻辑与操作符属于短路操作,如果第一个操作数能决定结果,那么就不会再对第二个操作数求值逻辑或
||
逻辑或也是短路操作;
3.5.3 乘性操作符
- 乘法
var result = 44 * 45;
- 除法
var result = 66 / 11;
3.求模(求余数)
var result = 26 % 5;
3.5.4 加法操作符
- 加法
var result = 66 + 1;
- 减法
var result = 66 - 1;
3.5.5 关系操作符
< > <= >=
3.5.6 相等操作符
- 相等和不相等
== !=
null == undefined ==> true
NaN == NaN ==》 true
true == 1 ==> true
true == 2 ==> false
- 全等和不全等
=== !==
3.5.7 条件操作符
var flag = this.value ? true : false;
3.5.8 赋值操作符
var num = 10;
num = num + 10;
可转换为:
var num = 10;
num += 10;
类似的还有:
num *= 10 == num = num * 10;
num /= 10 == num = num / 10;
num %= 10 == num = num % 10;
num -= 10 == num = num - 10;
3.5.9 逗号操作符
var num,age,name;
3.6 语句
3.6.1 if语句
if( condition ){ // ECMAScript会自动调用Boolean()转换函数将这个表达式结果转换为一个布尔值
//
}
3.6.2 do-while 语句
后测试循环语句,只有在循环体中代码执行之后,才会测试出口条件
var i = 0;
do {
i += 2
} while ( i < 10 );
3.6.3 while 语句
前测试循环语句,在循环体内代码被执行之前,就会对出口条件求值;
var i = 0;
while( i < 10 ){
i += 2;
}
3.6.4 for语句
前测试循环语句
for(;;){ //无限循环,会导致浏览器崩溃,可以试试;
console.log(11)
}
3.6.5 for in 语句
用来枚举对象的属性
如果要迭代的对象是null, undefined,则会终止循环
所以在使用for in之前,要确保该对象不是null或undefined
3.6.6 break 和 continue 语句
break: 立即退出循环,强制继续执行循环后的语句;
continue: 立即退出循环,从循环的顶部继续执行;
3.6.7 with语句
with语句作用主要是将代码的作用域设置到一个特定的对象中,定义with语句主要是为了简化多次编写同一个对象的工作;
var qs = location.search.substring(1);
var hostName = location.hostname;
var url = location.href;
使用with语句改写:
with(location){
var qs = search.substring(1);
var hostName = hostname;
var url = href;
}
缺点:严格模式下不允许使用with语句,否则将会视为语法错误
一般情况下,作用域链只会被with和catch语句影响。当使创建用with的时候,函数会创建一个新的活动对象,推到最前端,该对象就是with的对象。这就意味着所有的局部变量都处于第二个作用域链对象中去了,这也就是为什么要避免使用with的原因。
由于大量使用with语句会导致性能下降,同时也会造成调试代码困难,因此不建议使用with
3.6.8 switch语句
省略break关键字,会导致执行完当前case后,继续执行下一个case
3.7 函数
3.7.1 理解参数
ECMAScript不介意传递进来多少个参数,也不在乎传进来参数是什么数据类型。
在函数体内,可以通过arguments对象来访问这个参数数组,从而获取传递给函数的每一个参数
获取函数的参数数量:arguments.length;
function nums(num1,num2) {
console.log(arguments)
}
nums(1,2,3)
可以看到打印结果:
3.7.2 没有重载
其他语言(Java)中,可以为一个函数编写两个定义,只要这两个定义的签名(接受的参数的类型和数量)不同即可,ECMAScript函数没有签名,
因为其参数是由包含零或多个值的数组来表示的,而没有函数签名,真正的重载是不可能做到的;
如果在ECMAScript中定义了两个名字相同的函数,则该名字只属于后定义的函数;