JS基础知识总结02
运算符
运算符( operator )也被称为操作符,是用于实现赋值、比较和执行算数运算等功能的符号。
JavaScript中常用的运算符有:算数运算符、递增和递减运算符、比较运算符、逻辑运算符、赋值运算符。
运算符优先级:
优先级 | 运算符 | 描述 |
---|---|---|
1 | () | 小括号 |
2 | ++ - - ! | 一元运算符 |
3 | 先 * / % 后 + - | 算数运算符 |
4 | > >= < <= | 关系运算符 |
5 | == != === !== | 相等运算符 |
6 | 先 && 后 ll | 逻辑运算符 |
7 | = | 赋值运算符 |
8 | , | 逗号运算符 |
一元运算符里面的逻辑非优先级很高,逻辑与比逻辑或优先级高
算数运算符
概念∶算术运算使用的符号,用于执行两个变量或值的算术运算。
运算符 | 描述 | 案例 |
---|---|---|
+ | 加 | 10 + 20 = 30 |
- | 减 | 10 - 20 = -10 |
* | 乘 | 10 * 20 = 200 |
/ | 除 | 10 / 20= 0.5 |
% | 取余数(取模) | 返回除法的余数99%2= 1 |
注意:浮点数的精度问题
//我们不能直接拿着浮点数来进行相比较 是否相等
console.log(0.1 + 0.2); // 0.30000000000000004
console.log(0.07 * 100); // 7.000000000000001
浮点数值的最高精度是17位小数,但在进行算术计算时其精确度远远不如整数。
表达式和返回值
表达式∶是由数字、运算符、变量等以能求得数值的有意义排列方法所得的组合
简单理解∶是由数字、运算符、变量等组成的式子
表达式最终都会有一个结果,返回给我们,我们成为返回值
程序中:把我们的右边表达式计算完毕把返回值给左边
递增和递减运算符
如果需要反复给数字变量添加或减去1,可以使用递增(++)和递减(-- )运算符来完成。
在JavaScript中,递增(++)和递减(-- )既可以放在变量前面,也可以放在变量后面。放在变量前面时,我们可以称为前置递增(递减)运算符,放在变量后面时,我们可以称为后置递增(递减)运算符。
注意:递增和递减运算符必须和变量配合使用。
前置递增运算符
++num前置递增,就是自加1,类似于num = num + 1,但是++num写起来更简单。
使用口诀:先自加,后返回值
后置递增运算符
num++后置递增,就是自加1,类似于num = num + 1,但是num++写起来更简单。
使用口诀:先返回原值,后自加
开发时,大多使用后置递增/减,并且代码独占一行,例如: num++;或者num–;
比较运算符
概念∶比较运算符(关系运算符)是两个数据进行比较时所使用的运算符,比较运算后,会返回一个布尔值( true / false )作为比较运算的结果。
运算符 | 描述 | 案例 | 结果 |
---|---|---|---|
< | 小于号 | 1<2 | true |
> | 大于号 | 1 >2 | false |
>= | 大于等于号(大于或者等于) | 2>= 2 | true |
<= | 小于等于号(小于或者等于) | 3<= 2 | false |
== | 判等号(会转型) | 37== 37 | true |
!= | 不等号 | 37 != 37 | false |
=== | 全等要求值和数据类型都一致 | 37=== “37” | false |
!== | 不全等要求值或数据类型不一致 | 37!== “37” | true |
注意:
-
== 默认转换数据类型 会把字符串型的数据转换为数字型 只要求值相等就可以
-
=== 全等 要求两侧的值 还有 数据类型完全一致才可以 true
-
= 单等号 赋值 把右边赋值给左边
-
== 双等号 判断 判断等式两边的值是否相等(注意:此时有隐式转换,把等式两边数据类型转为一致)
-
=== 三等号 全等 判断等式两边的值和数据类型是否完全相同
逻辑运算符
概念∶逻辑运算符是用来进行布尔值运算的运算符,其返回值也是布尔值。开发中经常用于多个条件的判断
逻辑运算符 | 描述 | 案例 |
---|---|---|
&& | “逻辑与”,简称"与" and | true && false |
|| | “逻辑或”,简称"或”or | true | | false |
! | “逻辑非”,简称"非"not | ! true |
-
逻辑与 && and 两侧都为true 结果才是 true 只要有一侧为false 结果就为false
-
逻辑或 || or 两侧都为false 结果才是假 false 只要有一侧为true 结果就是true
-
逻辑非 ! not 也叫作取反符,用来取一个布尔值相反的值,如true的相反值是false
赋值运算符
概念∶用来把数据赋值给变量的运算符
赋值运算符 | 描述 | 案例 |
---|---|---|
= | 直接赋值 | var userName = '我是值"; |
+=、-= | 加、减一个数后在赋值 | var age = 10; age+=5; // 15 |
*=、/=、%= | 乘、除、取模(取余)后在赋值 | var age = 2; age*=5; //10 |
短路运算(逻辑中断)
短路运算的原理∶当有多个表达式(值)时,左边的表达式值可以确定结果时,就不再继续运算右边的表达式的值
假值:
0 ’ ’ null undefined NaN
逻辑与
语法:表达式1&&表达式2
如果第一个表达式的值为真,则返回表达式2
如果第一个表达式的值为假,则返回表达式1
逻辑或
语法:表达式1 || 表达式2
如果第一个表达式的值为真,则返回表达式1
如果第一个表达式的值为假,则返回表达式2
重点:// 逻辑中断很重要 它会影响我们程序运行结果
var num = 0;
console.log(123 || num++); // 123
console.log(num); // 0
JavaScript流程控制(顺序/分支判断/循环)
流程控制就是来控制我们的代码按照什么结构顺序来执行,主要有三种结构,分别是顺序结构、分支结构和循环结构。
顺序结构
顺序结构是程序中最简单、最基本的流程控制,它没有特定的语法结构,程序会按照代码的先后顺序,依次执行,程序中大多数的代码都是这样执行的。
分支结构
由上到下执行代码的过程中,根据不同的条件,执行不同的路径代码(执行代码多选一的过程),从而得到不同的结果。
if 语句
// 条件成立执行代码,否则什么也不做
if(条件表达式){
语句; // 条件成立执行语句
}
if else语句(双分支语句)
// 条件成立执行语句1,条件不成立执行语句2
if(条件表达式){
语句1;
}else{
语句2;
}
switch语句
switch语句也是多分支语句,它用于基于不同的条件来执行不同的代码。当要针对变量设置一系列的特定值的选项时,就可以使用switch。
利用我们的表达式的值 和 case 后面的value选项值相匹配 如果匹配上,就执行该case 里面的语句 如果都没有匹配上,那么执行 default里面的语句
switch (表达式) {
case value1:
语句1; // 表达式等于value1时要执行的语句
break;
case value2:
语句2; // 表达式等于value2时要执行的代码
break;
...
default:
语句3; // 表达式不等于任何一个value 时要执行的代码
}
-
开发里面 表达式 我们经常写成变量
-
表达式 的值 和 case 里面的值相匹配的时候是全等,必须是值和数据类型一致
-
break 如果当前的case里面没有break 则不会退出switch 是继续执行下一个case
switch语句和if else if 语句的区别
-
一般情况下,它们两个语句可以相互替换
-
switch…case语句通常处理case为比较确定值的情况,而if…else…语句更加灵活,常用于范围判断(大于、等于某个范围)
-
switch语句进行条件判断后直接执行到程序的条件语句,效率更高。而if…else语句有几种条件,就得判断多少次。
-
当分支比较少时,if…else语句的执行效率比switch语句高。
-
当分支比较多时,switch语句的执行效率比较高,而且结构更清晰。
循环结构
循环的目的:可以重复执行某些代码
在程序中,一组被重复执行的语句被称之为循环体,能否继续重复执行,取决于循环的终止条件。由循环体及循环的终止条件组成的语句,被称之为循环语句
在Js中,主要有三种类型的循环语句∶for 循环、while循环、do…while循环
for 循环
for循环主要用于把某些代码循环若干次,通常跟计数有关系。其语法结构如下:
for(初始化变量;条件表达式;操作表达式){
//循环体
}
-
初始化变量 就是用var 声明的一个普通变量, 通常用于作为计数器使用
-
条件表达式 就是用来决定每一次循环是否继续执行 就是终止的条件
-
操作表达式 是每次循环最后执行的代码,经常用于我们计数器变量进行更新(递增或者递减)
for循环可以执行相同的代码,通过条件表达式来控制输出的次数。
for循环还可以重复不同的代码,因为计数器在每次循环过程中都会有变化。
for循环拓展案例:
利用循环实现一行打印五个星星
可以通过追加字符串的方式,打印到控制台(空串 + 字符串 == 字符串)
var num = prompt('请输入星星的个数');
var str = '';
for (var i = 1; i <= num; i++) {
str = str + '★'
}
console.log(str);
双重for循环
很多情况下,单层for循环并不能满足我们的需求,比如我们要打印一个5行5列的图形、打印一个倒直角三角形等,此时就可以通过循环嵌套来实现。
循环嵌套是指在一个循环语句中再定义一个循环语句的语法结构,例如在for循环语句中,可以再嵌套一个for循环,这样的for循环语句我们称之为双重for循环。
for (外层的初始化变量; 外层的条件表达式; 外层的操作表达式) {
for (里层的初始化变量; 里层的条件表达式; 里层的操作表达式) {
// 执行语句;
}
}
我们可以把里面的循环看做是外层循环的语句
外层循环循环一次, 里面的循环执行全部
双重for循环拓展案例:
打印n行n列的星星
var rows = prompt('请您输入行数:');
var cols = prompt('请您输入列数:');
var str = '';
for (var i = 1; i <= rows; i++) {
for (var j = 1; j <= cols; j++) {
str = str + '★';
}
str += '\n';
}
console.log(str);
外层for循环控制行,内层for循环控制列数
九九乘法表
外层的 for 循环控制行数,内层的 for 循环控制列数,核心算法:每一行 公式的个数正好和行数一致, j <= i;
var str = "";
for (var i = 1; i <= 9; i++) {
for (var j = 1; j <= i; j++) {
str += j + "*" + i + "=" + i * j + "\t";
}
str += "\n";
}
console.log(str);
for循环总结:
for循环可以重复执行某些相同代码
for循环可以重复执行些许不同的代码,因为我们有计数器
for循环可以重复执行某些操作,比如算术运算符加法操作
双重for循环可以做更多、更好看的效果
双重for循环,外层循环一次,内层for循环全部执行
for循环是循环条件和数字直接相关的循环
while循环
while语句可以在条件表达式为真的前提下,循环执行指定的一段代码,直到表达式不为真时结束循环。while语句的语法结构如下:
while(条件表达式){
//循环体代码
}
注意:条件表达式中的变量要能够自增或自减,避免死循环。
执行思路∶
先执行条件表达式,如果结果为true,则执行循环体代码;如果为false,则退出循环,执行后面代码。执行循环体代码,循环体代码执行完毕后,程序会继续判断执行条件表达式,如条件仍为true,则会继续执行循环体,直到循环条件为false 时,整个循环过程才会结束
While循环拓展案例:
弹出一个提示框, 你爱我吗? 如果输入我爱你,就提示结束,否则,一直询问。
var message = prompt('你爱我吗?');
while (message !== '我爱你') {
message = prompt('你爱我吗?');
}
alert('我也爱你啊!');
do…while循环
do… while语句其实是while语句的一个变体。该循环会先执行一次代码块,然后对条件表达式进行判断,如果条件为真,就会重复执行循环体,否则退出循环。
do… while语句的语法结构如下:
do {
//循环体代码–条件表达式为true时重复执行循环体代码]
}while(条件表达式);
注意:条件表达式中的变量要能够自增或自减,避免死循环。
执行思路:
先执行一次循环体代码,再执行条件表达式,如果结果为true,则继续执行循环体代码,如果为false,则退出循环,继续执行后面代码
注意∶先再执行循环体,再判断,我们会发现 do…while循环语句至少会执行一次循环体代码
do…while拓展案例:
弹出一个提示框, 你爱我吗? 如果输入我爱你,就提示结束,否则,一直询问。
do {
var message = prompt('你爱我吗?');
} while (message !== '我爱你')
alert('我也爱你啊');
循环总结
JS中循环有for . while、do while三个循环很多情况下都可以相互替代使用
如果是用来计次数,跟数字相关的,三者使用基本相同,但是我们更喜欢用forwhile和do…while可以做更复杂的判断条件,比for循环灵活一些
while和do…while执行顺序不一样,while先判断后执行,do…while先执行一次,再判断执行
while和do…while执行次数不一样,do…while至少会执行一次循环体,而while可能一次也不执行
实际工作中,我们更常用for循环语句,它写法更简洁直观,所以要重点学习
continue break
continue关键字用于立即跳出本次循环,继续下一次循环(本次循环体中continue之后的代码就会少执行一次)。
continue跳出当前循环拓展案例:
求1~100 之间, 除了能被7整除之外的整数和
var sum = 0;
for (var i = 1; i <= 100; i++) {
if (i % 7 == 0) {
continue;
}
sum += i;
}
console.log(sum);
break 关键字用于立即跳出整个循环(循环结束)。
break退出循环拓展案例:
打印我吃的包子,当我吃到第3个时发现虫子,不在吃了,即停止打印
for (var i = 1; i <= 5; i++) {
if (i == 3) {
break;
}
console.log('我正在吃第' + i + '个包子');
}
三元表达式
三元表达式也能做一些简单的条件选择。有三元运算符组成的式子称为三元表达式
语法结构:条件表达式 ? 表达式1 : 表达式2
例如:var result = num > 5 ? ‘是的’ : ‘不是的’;
如果条件表达式结果为真 则 返回 表达式1 的值 如果条件表达式结果为假 则返回 表达式2 的值
数组
数据存储:可以使用数组(Array)。数组可以把一组相关的数据一起存放,并提供方便的访问(获取)方式。
数组:是指一组数据的集合,其中的每个数据被称作元素,在数组中可以存放任意类型的元素。数组是种将一组数据存储在单个变量名下的优雅方式。
数组的创建:
-
利用new 创建数组 var arr = new Array();
-
利用数组字面量创建数组 var arr = [];
声明数组并赋值称为数组的初始化,数组里面的数据一定用逗号分隔
注意:数组元素 数组名[索引号] 索引号从 0开始
数组的索引:
索引(下标):用来访问数组元素的序号(数组下标从О开始)。
var arr=['小白','小黑','大黄','瑞奇'];
索引号: 0 1 2 3
数组可以通过索引来访问、设置、修改对应的数组元素,我们可以通过“数组名[索引”的形式来获取数组中的元素。(这里的访问就是获取得到的意思)
遍历数组:
就是把数组的元素从头到尾访问一次
通过 “数组名[索引引]” 的方式一项项的取出来。
从数组中取出每一个元素时,代码是重复的,有所不一样的是索引值在递增,所以我们取数组元素时使用for循环进行遍历
数组的长度:
“数组名.length”可以访问数组元素的数量(数组长度)。
arr.length 动态监测数组元素的个数
数组拓展案例:
求数组 [2,6,1,7, 4] 里面所有元素的和以及平均值。
var arr = [2, 6, 1, 7, 4];
var sum = 0;
var average = 0;
for (var i = 0; i < arr.length; i++) {
sum += arr[i]; // 我们加的是数组元素 arr[i] 不是计数器 i
}
average = sum / arr.length; // 求平均值
console.log(sum, average); // 想要输出多个变量,用逗号分隔即可
将数组 ['red', 'green', 'blue', 'pink'] 转换为字符串,并且用 | 或其他符号分割
var arr = ['red', 'green', 'blue', 'pink'];
var str = '';
var sep = '*';
for (var i = 0; i < arr.length; i++) {
str += arr[i] + sep;
}
console.log(str);
- 新增数组
可以通过修改length长度以及索引号增加数组元素
- 通过修改length长度新增数组元素
可以通过修改length长度来实现数组扩容的目的(length 属性是可读写的)
var arr = ['red', 'green', 'blue'];
console.log(arr.length);
arr.length = 5; // 把我们数组的长度修改为了 5 里面有5个元素,多出的两个元素为空
- 新增数组元素 修改索引号 追加数组元素
arr[4] = 'hotpink'; // 新增数组元素,追加
console.log(arr1);
Arr[0] = 'yellow'; // 这里是替换原来的数组元素
arr1 = '有点意思';
console.log(arr1); // 不要直接给 数组名赋值 否则里面的数组元素都没有了
新增数组拓展案例:
新建一个数组,里面存放10个整数( 1~10)
var arr = [];
for (var i = 0; i < 100; i++) {
// arr = i; 不要直接给数组名赋值 否则以前的元素都没了
arr[i] = i + 1;
}
console.log(arr);
将数组 [2, 0, 6, 1, 77, 0, 52, 0, 25, 7] 中大于等于 10 的元素选出来,放入新数组
var arr = [2, 0, 6, 1, 77, 0, 52, 0, 25, 7];
var newArr = [];
// 刚开始 newArr.length 就是 0
for (var i = 0; i < arr.length; i++) {
if (arr[i] >= 10) {
// 新数组索引号应该从0开始 依次递增
newArr[newArr.length] = arr[i];
}
}
console.log(newArr);
将数组[2, 0, 6, 1, 77, 0, 52, 0, 25, 7]中的 0 去掉后,形成一个不包含 0 的新数组
var arr = [2, 0, 6, 1, 77, 0, 52, 0, 25, 7];
var newArr = [];
for (var i = 0; i < arr.length; i++) {
if (arr[i] != 0) {
newArr[newArr.length] = arr[i];
}
}
console.log(newArr);
数组翻转:将数组 [‘red’, ‘green’, ‘blue’, ‘pink’, ‘purple’] 的内容反过来存放
var arr = ['red', 'green', 'blue', 'pink', 'purple', 'hotpink'];
var newArr = [];
for (var i = arr.length - 1; i >= 0; i--) {
newArr[newArr.length] = arr[i]
}
console.log(newArr);
冒泡排序
冒泡排序∶是一种算法,把一系列的数据按照一定的顺序进行排列显示(从小到大或从大到小)。
例如:将数组[5,4,3,2,1]中的元素按照从小到大的顺序排序,输出:1,2,3,4,5
var arr = [4, 1, 2, 3, 5];
for (var i = 0; i <= arr.length - 1; i++) { // 外层循环管趟数
for (var j = 0; j <= arr.length - i - 1; j++) { // 里面的循环管 每一趟的交换次数
// 内部交换2个变量的值 前一个和后面一个数组元素相比较
if (arr[j] < arr[j + 1]) { // 从大到小排列
// if (arr[j] > arr[j + 1]) { // 从小到大排列
var temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
console.log(arr);
函数
为什么使用函数?
在JS里面,可能会定义非常多的相同代码或者功能相似的代码,这些代码可能需要大量重复使用。
虽然for循环语句也能实现一些简单的重复操作,但是比较具有局限性,此时我们就可以使用JS中的函数。
函数的使用:
函数就是封装了一段可以被重复执行调用的代码块 目的: 就是让大量代码重复使用
函数在使用时分为两步:声明函数和调用函数。
声明函数:
function函数名( ){
//函数体代码
)
调用函数:
函数名( ); //通过调用函数名来执行函数体代码
注意:调用的时候千万不要忘记添加小括号,且声明函数本身并不会执行代码,只有调用函数时才会执行函数体代码。
函数的封装:
函数的封装是把一个或者多个功能通过函数的方式封装起来,对外只提供一个简单的函数接口
简单理解︰封装类似于将电脑配件整合组装到机箱中(类似快递打包)
函数的参数:形参和实参
在声明函数时,可以在函数名称后面的小括号中添加一些参数,这些参数被称为形参,而在调用该函数时,同样也需要传递相应的参数,这些参数被称为实参。
参数类型 | 描述 |
---|---|
形参 | 形式上的参数函数定义的时候传递的参数当前并不知道是什么 |
实参 | 实际上的参数函数调用的时候传递的参数实参是传递给形参的 |
参数的作用:在函数内部某些值不能固定,我们可以通过参数在调用函数时传递不同的值进去。利用函数的参数实现函数重复不同的代码。
function 函数名(形参1,形参2...) { // 在声明函数的小括号里面是 形参 (形式上的参数:形参是接受实参的)
// 函数体
}
函数名(实参1,实参2…); // 在函数调用的小括号里面是实参(实际的参数)
函数的参数可以有,也可以没有个数不限
形参/实参拓展案例:
利用函数求任意两个数之间的和
function getSums(start, end) {
var sum = 0;
for (var i = start; i <= end; i++) {
sum += i;
}
console.log(sum);
}
getSums(1, 100);
注意:多个参数之间通过逗号隔开,形参可以看做是不用声明的变量
形参实参个数不匹配
参数个数 | 描述 |
---|---|
实参个等于形参个数 | 输出正确实参结果 |
实参个数多于形参个数 | 只取到形参的个数 |
实参个数小于形参个数 | 多的形参定义为undefined,结果为NaN |
-
如果实参的个数和形参的个数一致 则正常输出结果
-
如果实参的个数多于形参的个数 会取到形参的个数
-
如果实参的个数小于形参的个数 多于的形参定义为undefined 最终的结果就是 NaN
建议 我们尽量让实参的个数和形参相匹配
参数总结:
-
函数可以带参数也可以不带参数
-
声明函数的时候,函数名括号里面的是形参,形参的默认值为undefined
-
调用函数的时候,函数名括号里面的是实参
-
多个参数中间用逗号分隔
-
形参的个数可以和实参个数不匹配,但是结果不可预计,我们尽量要匹配
函数的返回值
把函数将值返回给调用者,需要通过使用return语句就可以实现。
function 函数名() {
return 需要返回的结果;
}
函数名( );
(1) 我们函数只是实现某种功能,最终的结果需要返回给函数的调用者函数名() 通过return 实现的
(2) 只要函数遇到return 就把后面的结果 返回给函数的调用者 函数名() = return后面的结果
拓展案例:
利用函数 求两个数的最大值,最小值
function getMax(num1, num2) {
return num1 > num2 ? num1 : num2;
}
function getMin(num1, num2) {
return num1 < num2 ? num1 : num2;
}
console.log(getMax(11, 3));
console.log(getMin(10, 21));
利用函数求数组 [5,2,99,101,67,77] 中的最大数值
function getArrMax(arr) { // arr 接受一个数组 arr = [5,2,99,101,67,77]
var max = arr[0];
for (var i = 1; i <= arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
return max;
}
console.log(getArrMax([3, 77, 44, 99, 143]));
Arguments的使用
当我们不确定有多少个参数传递的时候,可以用arguments来获取。在JavaScript中, arguments实际上它是当前函数的一个内置对象。所有函数都内置了一个arguments对象,arguments对象中存储了传递的所有实参。
arguments展示形式是一个伪数组,因此可以进行遍历。伪数组具有以下特点:
-
具有数组的 length 属性
-
按索引方式储存数据
-
它没有真正数组的一些方法 pop() push() 等等
arguments参数获取拓展案例:
利用arguments和函数求可变数组元素的最大值
function getMax() { // arguments = [1,2,3]
var max = arguments[0];
for (var i = 1; i < arguments.length; i++) {
if (arguments[i] > max) {
max = arguments[i];
}
}
return max;
}
console.log(getMax(1, 2, 3));
console.log(getMax(1, 2, 3, 4, 5));
函数的调用
因为每个函数都是独立的代码块,用于完成特殊任务,因此经常会用到函数相互调用的情况。
function fn1 () {
console.log ("111");
fn2();
console.log ("fn1");
}
function fn2() {
console. log(222) ;
console. log("fn2");
}
fn1();
拓展案例:
用户输入年份,输出当前年份2月份的天数
function isRunYear(year) { // 判断是否为闰年的函数
// 如果是闰年我们返回 true 否则 返回 false
var flag = false;
if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
flag = true;
}
return flag;
}
function backDay() {
var year = prompt('请您输入年份:');
if (isRunYear(year)) { // 调用函数需要加小括号
alert('当前年份是闰年2月份有29天');
} else {
alert('当前年份是平年2月份有28天');
}
}
backDay();
函数的声明方式
- 利用函数关键字自定义函数(命名函数)
function fn() {i
函数体
}
fn();
- 函数表达式(匿名函数)
var变量名= function() {};
var fun = function(name) {
console.log('我是函数表达式');
}
fun1(“路飞”);
注意:
- fun是变量名 不是函数名
- 函数表达式声明方式跟声明变量差不多,只不过变量里面存的是值 而 函数表达式里面存的是函数
- 函数表达式也可以进行传递参数