Live2D

JavaScript从入门到放弃 第二步

二. 运算符与流程控制

1. 赋值运算符与算术运算符

let a = 1; // 赋值语句 a等于1
a => 1

let a = 1 + 2; // 加法
let b = 1 - 2; // 减法
let c = 1 * 2; // 乘法
let d = 2 / 1; // 除法

let a = 1;

1.
a = a + 5;
a += 5; // 上面的简写

2.
a = a * 5;
a *= 5; // 上面的简写

3.
a = a / 5;
a /= 5; // 上面的简写

4.
a = a / 5;
a /= 5; // 上面的简写

2. 一元运算符的前置与后置操作

let n = 1;
++n; // 相当于n = n + 1;
=> n = 2

n++; // 也是相当于n = n + 1;
=> n = 2

# 如果不参与表达式运算两者没什么差距,如果参与运算就不同了,请看下面例子

// 前置加加
let a = 1;
let b = 2;
let c = a + ++b; // c = a + (b = b + 1);
c => 4
b => 3

// 后置加加
let a = 1;
let b = 2;
let c = a + b++; // 等于第一步c = a + b; 第二部在b++ b自增
c = > 3
b => 3

# 总结: 前加加就是先加,然后才用这个变量;后加加就是先用这个变量,然后在对这个变量自增。

3. 比较运算符的注意事项

// 比较运算符结果返回的是boolean值
// 有 >, <, >=, <=, ==, ===比较运算符
const a = 1; // number类型
const b = 2;
let c = '1'; // 字符串类型

a > b;
=> false

a < b;
=> true

a == b;
=> false

a == c;
=> true // 注意俩个等于号是弱比较,计算机内部会将字符串转为number类型,在比较数值

a === c;
=> false // 注意三个等于号是强比较既比较数值又比较类型

b >= 2;
=> true

a <= 2;
=> true

4. 逻辑运算符

let a = 1,
    b = 2;

1.逻辑与表达式 【&&】表示全都成立 返回boolean,全都成立返回true,有一个不成立返回false

a === 1 && b === 1;  // b === 1是不成立的返回false
=> false

2. 逻辑或表达式【||】表示至少有一个成立,返回boolean,有一个成立返回true,全都不成立返回false

a === 1 || b === 1;  // a === 1是成立的返回true
=> true

3.逻辑非【!】表示取反,真变假,假变真

a === 1 && b !== 1;  // b === 1是不成立的返回false,取反b !== 1;就是真,返回true
b === 1;使用逻辑非就是这样!(b === 1) 简写为 b !== 1;

=> true


5. 短路运算符妙用

let a = 1,
    b = 0;
a == true; // 两等于号比较的时候 
// 数字与boolean进行比较的时候换转换,boolean换转换为数字进行比较,true转换为1,false转换0;
=> true

b == false; // false转为0
=> true

if(a || b) {
    console.log('至少有一个不为0的数字');
}
// 上面这个例子他会先比较a如果a为true那么不会继续向下执行,这被称为短路运算符

if(b || a) {
    console.log('至少有一个不为0的数字');
}
// 上面这个例子他会先比较b发现b不符合为false那么继续比较a


# 利用短路符号继续赋值
let c = a || b; // 也就是说当a为假的时候取b的值,当a为真的时候取a的值
c => 1;

6. if else的关联

# if后面括号为条件分支,条件表达式都可以,只要结果为true会进入到if语句里执行代码
if(true) {
    console.log('进入了if分支');
}

如果if语句只有一行代码可以简写,如下,但一般不建议
if(true) console.log('进入了if分支');

const isChecked = false;
// 如果条件为真进入if分支,如果条件为假进入else分支
if(isChecked) {
    console.log('进入了if分支');
} else {
    console.log('进入了else分支');
}

# 但我们不推荐写if else 这样写扣钱哦 我们推荐使用下面这种写法
if(isChecked) {
    return console.log('进入了if分支');
}
console.log('进入了else分支');


如果需要判断多个条件,可以使用else if
let a = 10;
if(a > 10) {
    console.log('a大于10');
} else if( a < 5) {
   console.log('a小于5')
} else {
    console.log(a)
}

7. 三元表达式真可爱

boolean ? c : d; // 问号前边是表达式或boolean,如果为真执行c语句,如果为假执行d语句;
let a = false;
let b = a ? 1 : 0;
b = 0;

可以说三元表达式就是if else简写形式,
const isChecked = false;
if(isChecked) {
    console.log('进入了if分支');
} else {
    console.log('进入了else分支');
}

如果用三元表达式怎么写?
isChecked ? console.log('进入了if分支') : console.log('进入了else分支');

可以进一步优化为下面代码, 学废了么?
console.log(isChecked ? '进入了if分支' : '进入了else分支');

大家直呼内行,学废了,学废了,一看就会,一写就废。

8. switch的使用

1.标准语法:
let n = 2;
switch(n) {
    case 0: 
        console.log(0);
        break;
    case 1: 
        console.log(1);
        break;
    default: 
        console.log('default')
}

2. // 如果不加break他会一直执行语句,不管条件是否对应上也就是说
 先执行console.log('notice');
 在执行console.log('error');
 遇见bureak停止执行;
let type = 'notice';
switch(type) {
    case 'notice': 
        console.log('notice');
    case 'error': 
        console.log('error');
        break;
    case 'waring':
        console.log('waring');
        break;
    default: 
        console.log('default')
}


3. 我们利用这个不加break特性可以把多个条件写成下面的这种写法

匹配notice和error
let type = 'error';
switch(type) {
    case 'notice': 
    case 'error': 
        console.log('notice or error');
        break;
    case 'warning':
        console.log('warning');
        break;
    default: 
        console.log('default')
}

9. while循环控制

while(true) {
    console.log(1);
}
这样会进入死循环;电脑性能差的别这么搞哦,容易死机哦;

当然可以写个变量控制循环的次数,例如这样
let n = 10;
while(n-- && n !== 0) {
    console.log(n);
}

10. do while循环

// do while与while有些差距的,看下面例子
// 不管条件真假会执行一次(相当于你去店里买衣服,买不买不说先进店去)
do{
    console.log(1);
} while (false);

// 类似try catch的结构

let star = 0;
do{
    console.log(star);
} while(++star < 5);

11. for循环

1.
for(let i = 0; i < 10; i++) {
    console.log(i);
}

2.
for(let i = 0; i < 10;) {
    console.log(i);
    i++;
}

3.
let i = 0
for(; i < 10; ) {
    console.log(i);
    i++;
}

4.
let i = 0
for(; ; ) {
    if(i>=10) {
        break;
    }
    console.log(i);
    i++;
}
以上四种写法都可以,但一般不这么写,使用第一种的比较多

// 使用for循环打印三角形
for(let i = 0; i < 10; i++) {
    for(let j = 0; j <= i; j++) {
        document.write('*');
    }
    document.write('</br>')
}

12. break与continue

// 终止当前循环
for(let i = 0; i < 10; i++) {
    console.log(i);
    if(i===3) {
        break;
    }
}

// 结束本次循环
for(let i = 1; i < 10; i++) {
    console.log(i, 'i');
   for(let j = 1; j < 5; j++) {
      if(!(j % 2)) {
          console.log(j, '偶数');
          continue; // 此时只有一层循环使用continue的作用不大,多层循环嵌套会跳出当前循环,进入下次循环
          console.log('啦啦啦啦'); // continue后面代码不执行
      }
   }
}

13. label标签

waiceng: for(let i = 0; i < 10; i++) {
    neiceng: for(let j = 0; j <= i; j++) {
        document.write('*');
        if(i + j > 10) {
            break waiceng; // 终止整个循环
           // break neiceng; // 如果要终止当前循环,加标签和不加标签一样
        }
    }
    document.write('</br>')
}

14. for...of迭代对象

### 可迭代对象(包括Array, Map, Set, String, arguments对象, Nodelist等);

const obj = {
	z: 1,
	b: 2,
	c: 3
};
for(let value of obj) {
	console.log(value);
}
// 会报错如下图所示
那么iterable是什么,是不是有了就可以遍历了呢?我么慢慢往下看

avatar

看下面这个例子:
const num = ['z', 'b' , 'c'];
for(let value of num) {
	console.log(value);
}
=> z b c // 是可以遍历的

为什么数组可以遍历,咱们自己定义的字面量对象却不可以呢,问题出在哪里呢,我们看看数组和对象的结构

console.dir(num);
console.dir(obj);

avatar

​ 这是数组原型图,多了个这个iterator

这是对象原型图,没有这个iterator

​ 这是对象原型图,没有这个iterator

​ 知道区别了吧

问题就出在这里,谁有这个属性谁就能被for...of和迭代遍历(不包括for...in,for...in可以遍历字面量对象)
可迭代对象(包括Array, Map, Set, String, arguments对象等),都可以使用for...of遍历

15. for...in遍历数组与对象

for...in 可以遍历数组和对象(包括没有iterable的对象)

1.遍历对象
const obj = {
	z: 1,
	b: 2,
	c: 3
};
for(let key in obj) {
	console.log(key);
}
=> z b c

2.遍历数组
let arr = ['name', '18', 'big'];
for(let index in arr) {
    console.log(index); // 数组的下标,index索引为字符串型数字,不能直接进行几何运算
}

3.可以遍历原型上的可枚举的属性--对象
Object.prototype.name = 'zcy'; // 在对象的原型上添加name属性
let obj = {
	z: 1,
	b: 2,
	c: 3
};
for(let key in obj) {
	console.log(key);
}
=> z b c name

## 我们会发现把不是自身属性的name也遍历出来了,其实我们不想要遍历不是自身属性,那该怎么办呢
Object.prototype.name = 'zcy'; // 在对象的原型上添加name属性
let obj = {
	z: 1,
	b: 2,
	c: 3
};
for(let key in obj) {
    if(obj.hasOwnProperty(key)) {
        console.log(key);
    }
}
=> z b c 这样就没有name属性


4.可以遍历原型上的可枚举的属性--数组
Array.prototype.zcy = 'zcy999'
let arr = ['name', '18', 'big'];
for(let index in arr) {
    console.log(index); // '0' '1' '2' 'zcy'
    console.log(typeof index); // string
    console.log(arr[index]); // 'name' '18' 'big' 'zcy999'
}

总结:
使用for...in循环对象比for...of好用
使用for...of循环数组比for...in好用
posted @ 2021-02-07 11:15  掷轰烈喵生  阅读(84)  评论(0)    收藏  举报