本章节将开始介绍了解运算符的使用,一些常见常用的运算符将简略讲讲,重点讲一些容易忽略但十分重要的运算
主要讲讲赋值运算和算数运算
// 将数值5赋值给变量a
let a = 5;
主要包含加、减、乘、除、取余:
// 变量赋值
let a = 5, b = 3;
// >> 加法(+) <<
let c = a + b; // 8
// >> 减法(-) <<
let d = a - b; // 2
// >> 乘法(*) <<
let e = a * b; // 15
// >> 除法(/) <<
let f = a / b; // 1.6666666666666667
// >> 取余(%) <<
let g = a % b; // 2
可以使用 * =、/=、+=、-=、%= 简写算术运算。即 n*=2 等同于 n=n*2。
/*
复合运算,注意下面的每个结果是基于自身上面的
结果而继续计算得来的。
*/
// 变量赋值
let a = 5;
// >> 加(+=) <<
a += 3; // 8
// >> 减(-=) <<
a -= 3; // 5
// >> 乘(*=) <<
a *= 3; // 15
// >> 除(/=) <<
a /= 3; // 5
// >> 取余(%=) <<
a %= 3; // 2
一元运算符指的是其自身进行运算,包括自增和自减运算。并且运算符号存在前置和后置操作两种
前置操作时,运算结果将会直接返回该变量进行前置操作运算后的结果,如下:
let a = 5;
console.log(++a); // 6
console.log(--a); // 5
console.log(6+ ++a); // 12
后置操作时,运算结果将会直接返回该变量进行前置操作运算前的结果,如下:
let a = 5;
console.log(a++); // 5(实际上此时a的值为6)
console.log(a--); // 6(实际上此时a的值为5)
console.log(6+ a++); // 11(实际上此时a的值为6)
主要用来比较两个值之间的关系
比较运算符一共有下面几个:
符号 | 含义 |
---|---|
> | 大于 |
< | 小于 |
>= | 大于或等于 |
<= | 小于或等于 |
== | 强制类型转换比较 |
=== | 不强制类型转换比较 |
运算示例如下:
let a = 1, b = 2, c = '1';
console.log(typeof a); // number
console.log(typeof c); // string
// 大于(>)、大于等于(>=)、小于(<)、小于等于(<=)
console.log(a > b); // false
console.log(a >= 1); // true
console.log(a < b); // true
console.log(a <= b); // true
// 强制类型转换比较(==),在比较前该运算会先将类型不同的值进行强制转换,而后比较其值是否相等
console.log(a == b); // false
console.log(a == c); // true(虽然变量a和c之间的类型不同,但是代表的值相等,所以==判定为true)
// 不强制类型转换比较(===),比较时即会比较值也会比较类型
console.log(a === c); // false(因为变量a和c之间的类型不同,所以===判定为false)
这里贴一个小小的应用示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>js学习</title>
</head>
<body>
<input type="text" name="age"/>
<span id="msg"></span>
</body>
<script>
// 获取标签
let span = document.querySelector('#msg');
// 对输入框中的值进行监听并且设置相应的动作
document.querySelector('[name="age"]').addEventListener('keyup', function () {
span.innerHTML = this.value > 90 ? 'sorry,年龄不得大于90岁!' : '';
});
</script>
</html>
逻辑运算包含与(&&)、或(||)、非(!)三种
let a = 1, b = 1;
// 基本运算
if (a == 1 && b == 1) {
console.log('a和b都必须为1');
}
if (a == 1 || b == 2) {
console.log('a和b其中有一个为1即可');
}
if (a == 1 && b != 2) {
console.log('必须a等于1且b不等于2');
}
// 优先级问题(! > && > ||)
if (a ==1 || b != 2 && b > 3) {
console.log('[b不等于2且b大于3]与[a等于1]其中有一个成立即可');
}
再整个小应用示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>js学习</title>
</head>
<body>
<input type="text" name="password"/>
<input type="text" name="confirm_password">
<div id="msg"></div>
</body>
<script>
// 获取所有的表单
let inputs = document.querySelectorAll('input');
// 分别添加监听事件,并设置监听反馈
[...inputs].map(item => {
item.addEventListener('keyup', function () {
// 三元运算,对输入的情况进行判断,并且选择不同的提示赋值给div控件
document.querySelector('#msg').innerHTML =
inputs[0].value != inputs[1].value || this.value.length < 5
? '两次密码不一致或密码长度小于5位' : '两次密码一致且密码长度符合要求';
});
});
console.log(inputs);
</script>
</html>
当两个输入框里输入的密码不一致或者密码长度小于5位时,则提示不符合要求;否则提示符合要求:
在js中的逻辑与和逻辑或的运算中存在一个特性,即当前一个已经得出结论后,怎后面的那个运算不再进行计算,并且返回的结果为当前计算结果
let a = 2, b = 0, c = 1;
console.log(b || a); // 2 (b为假,所以需再判断a,于是返回了a的值)
console.log(a || c); // 2 (a已经为真,所以没必要再判断a,直接返回了a的值)
console.log(b && a); // 0 (b已经为假,所以没必要再判断a,直接返回了b的值)
console.log(a && b); // 0 (a为真,所以需再判断b,于是返回了b的值)
利用js的这个短路特性,我们可以简略书写我们的代码,有下面两个小例子:
【例子1】
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>js学习</title>
</head>
<body>
</body>
<script>
let sex = prompt('请输出性别') || '保密';
console.log(sex);
</script>
</html>
当输入具体的性别值时,sex
变量会取得这个值;当不输入时,则会取得值’保密’:
【例子2】
function star (num) {
return '*'.repeat(num || 3);
}
// 输入5,则在进行逻辑或判断时,前面部分已经为真,所以直接返回num的值
console.log(star(5)); // *****
// 输入为空,此时函数体中的num为undefined,所以在进行逻辑或判断时,
// 前部分为假,然后再看后一部分,因此返回的是值3
console.log(star()); // ***
当条件成立时执行成立中的代码块,当不成立时执行else中的代码块;当只有一行代码块的时候可以省略{}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>js学习</title>
</head>
<body>
<input type="text" name="password">
<div id="msg"></div>
</body>
<script>
// 获取span控件
let span = document.querySelector('#msg');
// 给input添加监听事件
document
.querySelector('[name="password"]')
.addEventListener('keyup', function () {
let length = this.value.length;
let msg = '';
if (length > 10) {
msg = '密码非常的安全';
} else if (length > 6) {
msg = '密码中等强度安全';
}else{
msg = '密码不安全';
}
span.innerHTML = msg;
});
</script>
</html>
当输入的密码长度大于10位时提示密码非常的安全;大于6位且小于等于10位时提示密码中等强度安全;小于等于6位时提示密码不安全:
(1)小于等于6位
(2)大于6位且小于等于10位
三元表达式实际上为if的简写形式
当问号前的结果为真的时候,则返回冒号前一部分的值,否则返回冒号后一部分的值:
let a = true ? '为真' : '为假';
console.log(a); // 为真
我们再来个套娃:
let a = false ? '外层为真' : (true ? '外层为假且内层为真' : '外层为假且内层为真');
console.log(a); // 外层为假且内层为真
三元表达式非常的可爱好用,下面我们简简单单整个小例子:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>js学习</title>
</head>
<body>
</body>
<script>
// 声明创建div块的函数,参数options的默认值为{}
function div (options = {}) {
let div = document.createElement('div');
// 若传递了宽度,则设置,否则使用默认宽度
div.style.width = options.width ? options.width : '200px';
// 若传递了高度,则设置,否则使用默认高度
div.style.height = options.height ? options.height : '100px';
// 若传递了背景颜色,则设置,否则使用背景颜色
div.style.backgroundColor = options.baccolor ? options.baccolor : '#456';
document.body.appendChild(div);
}
// 调用,不传递参数
div();
// 调用,传递参数
div({
height: '320px',
baccolor: '#1087'
});
</script>
</html>
在这个例子中,我们实现了一个创建div块的函数,并且利用三元表达式为其设定了默认值,效果如下:
可以将 switch 理解为 if 的另一种结构清晰的写法。
如果表达式等于 case 中的值,将执行此 case 代码段,break 关键字会终止 switch 的执行;没有任何 case匹配时将执行default 代码块;如果case执行后缺少break则接着执行后面的语句
// 定义年龄分段函数
function message (age) {
let msg = '';
switch (true) {
case age < 0:
msg = '年龄不能为负数';
break;
case age < 15:
msg = '儿童';
break;
case age < 25:
msg = '青少年';
break;
case age < 40:
msg = '青年';
break;
case age < 60:
msg = '中年';
break;
case age < 100:
msg = '老年';
break;
default:
msg = '输入非法';
break;
}
return msg;
}
// 调用
console.log(message(-67)); // 年龄不能为负数
console.log(message(12)); // 儿童
console.log(message('oji')); // 输入非法
需要指出的是,表达式和case
中均可以写一些判断逻辑,但最终判断的是表达式的值和case
最终展现的值之间的关系,切记切记
循环执行语句,需要设置跳出循环的条件否则会陷入死循环状态
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>js学习</title>
</head>
<body>
</body>
<script>
document.write('');
let tr = 5;
while (tr-- != 0) {
let td = 3;
while (td-- != 0) {
document.write(`${td} `); // 要使用变量拼接,需要用`符号,而不是单引号'
}
document.write(' ');
}
document.write('
');
</script>
</html>
效果是这样的:
后条件判断语句,无论条件是否为真都会先进行循环体。下面通过循环输出三角形示例,要注意设置循环跳出的时机来避免死循环。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>js学习</title>
</head>
<body>
</body>
<script>
function star(row = 5){
let state = 0;
do {
let n = 0;
do {
document.write('*');
} while (++n <= state);
document.write('
');
} while (++state <= row);
}
// 调用
star(10);
</script>
</html>
可以在循环前初始化初始计算变量。下面是使用for
打印倒三角的示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>js学习</title>
</head>
<body>
</body>
<script>
// 定义
function paint (row = 5) {
for (let i = row; i > 0; i--) {
for (let n = 0; n < i; n++) {
document.write('*');
}
document.write('
');
}
}
// 调用
paint(10);
</script>
</html>
break用于退出当前循环,continue用于退出当前循环返回循环起始继续执行。标签(label) 为程序定义位置,可以使用continue/break跳到该位置。
我们先来看一个continue的例子:
for (let i = 0; i < 5; i++) {
// 当i为奇数时,继续下轮循环,continue后面的语句不执行
if (i % 2) {
continue
}
console.log(i); // 0 2 4
}
再来看看break的例子:
for (let i = 0; i < 10; i++) {
// 当i等于4的时候,结束整个循环,同时本轮循环内break后面的语句不执行
if (i == 4) {
break
}
console.log(i); // 0 1 2 3
}
最后,我们利用label的功能,让嵌套循环中,在内层循环中直接结束整个嵌套循环:
// outfor为自定义的外部循环的标签
outfor: for (let i = 0; i < 5; i++) {
// infor为自定义的内部循环的标签
infor: for (let n = 0; n < 5; n++) {
if (n % 2 == 0) {
console.log(`i:${i},n:${n}`)
}
if (n + i > 3) {
// 直接结束外部循环,而不是默认的结束本循环(内部循环)
break outfor;
}
}
}
这两个主要用来方便的遍历对象或数组
for-in 用于遍历对象的所有属性,for/in主要用于遍历对象,不建议用来遍历数组。看下面遍历对象并生成对应表格的例子:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>js学习</title>
</head>
<body>
</body>
<script>
// 先定义一个对象
let data = [
{name: '张三', age: 20, home: '北京'},
{name: '李四', age: 31, home: '拉萨'},
{name: 'Angle', age: 18, home: '深圳'},
{name: 'Lisa', age: 24, home: '南京'}
]
// 绘制表格头
document.write(`
姓名
年龄
家庭住址
`);
// 循环绘制表格体
// for-of遍历数组,每次取出其中的值person
for (const person of data) {
document.write(``);
// for-in遍历对象,每次取出该对象的一个索引key
for (const key in person) {
// 判断该对象是否有该索引
if (person.hasOwnProperty.call(person, key)) {
document.write(`${person[key]} `);
}
}
document.write(` `);
}
// 绘制表格尾
document.write(`
`);
</script>
</html>
用来遍历 Arrays(数组), Strings(字符串), Maps(映射), Sets(集合)等 可迭代的数据结构。与 for/in 不同的是 for/of 每次循环取其中的值而不是索引。
先来个遍历数组的:
let arr = [1 ,2, 4];
for (const value of arr) {
console.log(value); // 1 2 4
}
再来个遍历字符串的:
for (const value of '今天是个好日子') {
console.log(value); // 今 天 是 个 好 日 子
}
再来个遍历映射的:
let map = new Map();
map.set('数学', 98);
map.set('语文', 99);
map.set('英语', 100);
for (const item of map) {
console.log(item[0]); // 数学 语文 英语
console.log(item[1]); // 98 99 100
}
最后整个遍历集合的:
// 声明一个Set对象
const set = new Set();
// 添加一些值
[1,2,3,4,5,6,5,4].forEach(value => set.add(value));
// for-of 循环遍历
for (const value of set) {
console.log(value); // 1 2 3 4 5 6
}