2.1 语法错误和通用错误
- 语法错误一旦抛出,会影响到整个程序,导致整个程序都不会被执行
console.log(1);
console.log(2); // 如果这个分号是中文字符的分号,则会语法错误(Uncaught SyntaxError:Invalid or unexpected token),会导致整个程序都不会被执行
console.log(3);
console.log(4);
- 通用错误一旦抛出,不会影响到之前的代码输出,但是会中断之后的代码运行
console.log(1);
console.log(a); //Uncaught ReferenceError: a is not defined 未定义错误,之后的代码都不会输出,但是之前的代码能够输出
console.log(b);
- 代码块的问题:不同脚本引用代码块之间的代码互不影响,其中过一个引用代码块报错不影响其他脚本引用的代码块
<script type="text/javascript">
console.log(a); // 报错,但是不会影响下面的代码块执行
</script>
<script type="text/javascript">
console.log(1);
</script>
错误或是死循环只是中断自身的js 解析html是浏览器需要调度不用的进程来协同完成的 js是单线程,也就是同步的方式 浏览器是多进程的
2.2 JavaScript的基本运算符(基本运算从左自右运算,赋值运算从右往左)
- 赋值运算
赋值运算顺序是从右往左依此赋值;
var x = y = z = 1;
console.log(x, y, z); // 1 1 1
var x = 1,
y = z = 1;
console.log(x, y, z); // 1 1 1
- 运算逻辑
var a = 1,
b = 2,
c = 3;
var d = ( a + b ) * c;
// 运算的过程:
// 1.声明变量c
// 2.变量a的值和变量b的值相加,再与变量c的值相乘得出值
// 3.再将该值赋值给变量d
// 优先级:括号运算 > 普通运算 > 赋值运算
- 加法运算 (任何数据类型的值加上字符串都是字符串)
var d = 'str' + 1 + 1;
console.log(d); // str11 字符串类型
var c = 1 + 1 + 'str' + 1 + undefined;
console.log(c); // 2str1undefined 字符串类型
// 隐式转换
var a = null,
b = 2;
console.log(a + b); // Number(0) + 2 = 2;
// 未定义
console.log(c + '1'); // 报错:Uncaught ReferenceError: c is not defined
- 除法运算 (被除数 / 除数 = 商)
NaN ---> 表示Not a Number(非数)-->但是也是Number类型值
Infinity --->表示无限大的数-->也是Number类型值
-Infinity--->表示无限小的数-->也是Number类型值
console.log(0 / 0); // NaN
console.log(1 / 0); // Infinity
console.log(-1 / 0); // -Infinity
console.log('str' / 0); // NaN
console.log(0 / 2); // 0
console.log(-0 / 1); // -0
// 隐式转换
console.log('1' / 1); // 1
console.log(null / 1); // 0
console.log('null' / 1); // NaN
console.log(true / 1); // 1
console.log('true' / 1); // NaN
- 模运算(取余运算,被余数 / 余数 = 剩余数)
余数不能为0,否则是NaN,两个Infinity除外
2.3JavaScript变量交换值的问题
通常我们需要两个值进行交换,那么解决的办法是什么呢?
- 通过创建新的变量,作为中间值实现
var a = 2,
b = 3,
temp; // 1.创建中间变量
temp = a; // 2.将a的值赋值给temp变量
a = b; // 3.再将b的值赋值给a
b = temp; // 4.再将temp的值赋给b
console.log(a,b); //3 2
// 在栈内存stack中操作过程是什么样子的呢?
// 1.创建变量并且赋值a = 2,b = 3,temp;
// 2.将变量a的值2赋值给变量temp,此时变量temp的值就是2,temp = 2;
// 3.再将变量b的值赋值给变量a,此时变量a的值被变量b的值3覆盖,a = 3;
// 4.将变量temp=2的值赋值给变量b,此时temp值覆盖最初的值3,此时b = 2;
- 不创建新的变量,实现交换的效果
// 通过两个值进行相加,然后再做相对应的操作即可
var a = 2,
b = 3;
a = a + b; // a = 5;
b = a - b; // b = 2;
a = a - b; // a = 3;
2.4 运算符++a和a++或者--a和a--的操作
- ++a就是先加减后运算
- a++就是先运算后加减
var a = 3;
console.log(a++); // 3
console.log(++a); // 5 为什么这里打印的是5呢?不应该是4吗?
// 因为在执行a++后,a++ ==> a = a + 1 ==> a = 3 + 1 = 4;
// 所以再执行++a的时候,a的值已经等于4,所以自增1的话就是5;
// 对应分别输出a和b的值(每个b都是独立存在的,不影响其他运算)
var a = 5,
b;
b = a++ + 1; // b:6 a:6
b = ++a + 1; // b:7 a:6
b = --a + --a; // b:7 a:3
b = --a + a++; // b:8 a:5
b = a++ + a++; // b:11 a:7
b = ++a + ++a; // b:13 a:7
b = a++ + ++a; // b:12 a:7 // b = 5 + 7 ==>在++a之前,a的值变量a = 5 + 1 = 6;因为a++执行后
2.5 比较运算符(> < >= <= == === != !==)
- 返回值是boolean,只存在true或false
- 对于比较的值中存在Number类型数据,那么需要将另一方的值转为Number类型进行比较
- 如果在转化Number的过程中,最后转化的值为NaN,那么返回的布尔值就是false
var a = 1,
b = '2';
console.log(a > b);// false 字符串转化为number类型的值
var c = 2,
b = 'str';
console.log(c > b); // false 因为b转为number类型是NaN
var c = '89',
d = true;
console.log(c > d); // true Number('89')--> 89 Number(true)--> 1
- 如果二者比较的类型都是字符串的话,那么比较的就是ASCII码表上的十进制的值
var a = 'a', // 97
b = 'b'; // 98
console.log(a > b); // false
var c = '11',
d = '2',
console.log(c > d); // false 这是为什么呢?难道11不是大于2吗?
// 因为字符串比较,比较的是ACSII码表上的值
// ACSII码表上,字符串'11'的第一位'1'值为49
// 字符串'2'的第一位'2'值为50
// 所以返回false
- ==相等和===或者!=和!==的区别
==相等是不比较数据类型的,而===是比较数据类型和值的。
!=和!==也是同理
var a = 3;
var b = '3';
var d = 3;
console.log(a == b); // true
console.log(a === b); // false 全等既要比较值还要比较数据类型
NaN == NaN 吗?
console.log(NaN == NaN); // false 因为NaN与包括自己在内的任何东西都不相等
2.6 逻辑运算与(&&) 或(||) 非(!)
- 返回值是逻辑成立后的值
- 布尔值是false的有: undefined null NaN ''(空字符串) 0 false ,除了这些值,以上都是true
&&运算
var a = 1;
var c = '';
var b = 0;
console.log(a && b); // 0
console.log(c && a); // ''
// 当执行&&运算时,
// 遇到真就往后执行
// 遇到假或走到最后就返回当前的值
// 相当于遇到假的值就直接返回当前值
||运算
var a = 1;
var b = 2;
var c = '';
var d = undefined;
console.log(b || a); // 1
console.log(c || d); // undefined
// 当执行||运算时,
// 遇到假的就往后执行,
// 遇到真的或者走到最后就返回当前的值
// 相当于遇到真的就直接返回当前值
// 实践中:
ele.onclick = function(e) {
//兼容IE低版本,因为IE低版本没有事件对象e参数
var event = e || window.event;
}
!运算
var a = 1;
var b = undefined;
var c = NaN;
console.log(!a); // false
console.log(!b); // true
console.log(!c); // true
// 相当于取当前值的对立值
2.7 if语句和switch语句
if语句和switch语句不是因为性能的问题导致大多数使用的if语句。而是使用的环境不同,对于if语句来说,如果判断条件是互斥的情况,那么多数使用的if语句。如果结果是多个确定的值,就使用switch语句,二者绝不是性能问题导致使用率不同,而是使用的场景不同。
- 成绩评定实例
----------第一种写法-----------
var score = 68;
if (score >= 90 && score <= 100) {
console.log('您的成绩为A');
}
if (score >= 80 && score < 90) {
console.log('您的成绩为B');
}
if (score >= 70 && score < 80) {
console.log('您的成绩为C');
}
if (score >= 60 && score < 70) {
console.log('您的成绩为D');
}
if (score < 60) {
console.log('您的成绩不及格');
}
---------第二种写法--------------
if (score >= 90 && score <= 100) {
console.log('您的成绩为A');
}else if (score >= 80 && score < 90) {
console.log('您的成绩为B');
}else if (score >= 70 && score < 80) {
console.log('您的成绩为C');
}else if (score >= 60 && score < 70) {
console.log('您的成绩为D');
}else if (score < 60) {
console.log('您的成绩不及格');
}else {
console.log('您的成绩查询出现异常');
}
// 两种写法有什么区别呢?
// 对于第一种写法来说:需要进行5次的if语句的判断,然后寻找满足的条件
// 对于第二种写法来说:只需要进行一次if语句的判断,然后再寻找满足的条件
- 实例
var city = window.prompt('您的工作城市?');
switch(city) {
case '北京':
console.log('北京平均工资为:20k');
break;
case '上海':
console.log('上海平均工资为:18k');
break;
case '深圳':
console.log('深圳平均工资为:16k');
break;
default:
console.log(city + '城市的工资为:10k');
break;
}
- 对if成绩实例进行switch改写
var score = 68;
switch(true) {
case score >= 90 && score <= 100: // case 不仅仅可以写变量还可以是判断语句,不过switch语句的变量设为true,才能进入语句
console.log('您的成绩为A');
break;
case score >= 80 && score < 90:
console.log('您的成绩为B');
break;
case score >= 70 && score < 80:
console.log('您的成绩为C');
break;
case score >= 60 && score < 70:
console.log('您的成绩为D');
break;
default:
console.log('您的成绩不及格');
break;
}