什么是Javascript
简介
- JavaScript 是互联网上最流行的脚本语言,这门语言可用于 HTML 和 web,更可广泛用于服务器、PC、笔记本电脑、平板电脑和智能手机等设备 。
- 轻量级,但功能强大的编程语言 。
组成部分
ECMAScript
- js代码语法的标准 是一种规范。
- 规定js有哪些内容。
Web ApI
- dom 页面标签
- bom 浏览器刷新
引入方式
内部式
内联式
外链式 (工作中常用)
注释方式
单行 //
多行 /**/
语法
区分大小写
ECMAScript一切都区分大小写,无论是变量、函数名还是操作符。
括号表示代码块。
标识符
就是变量、函数、属性或者函数参数的名称。
输出方式
- 控制台输出 console.log()
- 弹出警告框 alert()
- 将内容写到 HTML文档中 document.write()
输入方式
- prompt(“ “) ; 输入的内容 数据类型都是字符串
字面量(常量)
在编程语言中,一般固定值称为字面量
待完善。。。
数字(Number)字面量
可以是整数或者是小数,或者是科学计数(e)
字符串(String)字面量
可以使用单引号或双引号
表达式 字面量
用于计算 + - * /
数组(Array)字面量
定义一个数组
对象(Object)字面量
定义一个对象
函数(Function)字面量
定义一个函数
变量(标识符)
什么是变量
- 一个变量,就是一个用于存放数值的容器 。
- 变量的独特之处在于它存放的数值是可以改变的
声明一个变量的语法是
- 使用 let 或 var 关键字之后加上这个变量的名字
var 声明一个变量,可选初始化一个值 .
let 声明一个块作用域的局部变量,可选初始化一个值
let userName ; - 变量的命名:
驼峰命名法
- 不能以数字开头
- 可以使用 英文开头 和 _ $等
- 最好有具体的含义
反引号包裹可以输出html的内容 ${}表示变量,用反引号包裹就不用引号和加号隔开了小案例 document.write ${}
let userName = '熊二';
let userAge = '12';
// 反引号包裹
// 模板字符串
document.write(`大家好,我叫${userName},今年${userAge}岁了`)
document.write(`<h1>一级标题</h1>`)
效果图:
数据类型
检测数据类型
typeof
基本数据类型
Number
整数
或浮点数
NaN
- NaN自己和自己不相等
- NaN参加任何数学运算结果都是NaN
String
用单引号
或双引号
包裹的文本
Boolean
true
false
undefined
- 用 var 或 let 语句声明的变量,如果没有赋初始值,则其值为 undefined 。
- 可以使用 undefined 来判断一个变量是否已赋值 。
null
对一个 null
变量求值时,空值 null
在数值类型环境中会被当作0来对待,而布尔类型环境中会被当作 false
。
数据类型总结
举例 | 当let a = b变量传值时 | 当用==比较时 | |
---|---|---|---|
基本类型值 | 数字型、字符串型、布尔型、undefined型 | 内存中产生新的副本 | 比较值是否相等 |
引用类型值 | 对象、数组 | 内存中不产生新的副本,而是让新变量指向同一个对象 | 比较内存地址是否相同,即比较是否是同一个对象 |
引用数据类型
- array
- object
- function
- regexp
- ….
数据类型转换
隐式转换
本质就是调用Number()函数
系统**自动做转换**
(用的更多、简单)
参加数学运算的操作数不是数字型,会隐式转换
1.转为Number类型
//第一种
1. let num1 = "123";
let num2 = +num1;
//最好简写成下面:
let num1 = "123";
let num2 = +num1;
//第二种
2.//将输入的字符串转为Number类型
let num1 = +prompt('请输入数字');
//第三种
3. let num2 = "123" - 0; //乘 减 除 都可以转为Number类型,加法不行
2.转为String类型
加号两边只要有一个是字符串,都会把另一个转成字符串
let str = 123;
let str2 = str + "";
显式转换
自己写代码告诉系统转成什么类型
1.转为Number类型
转换不成功结果为 NaN (not a number) 不成功应该是字符串里有非数字
parseInt()
和parseFloat()
Number()
//第一种
1.let num = Number("123");
//第二种
2.let num2 = '12';
let num3 = Number(num2);
3.//将输入的字符串转为Number类型
let num1 = prompt('请输入数字');
console.log(parseInt(num1));
//parseInt 方法只能返回整数,所以使用它会丢失小数部分。另外,调用 parseInt 时最好总是带上进制(radix) 参数,这个参数用于指定使用哪一种进制。
2.转为String类型
string()
toString()
常用
//第一种
let str = String(123);
//第二种
let num1 = '12345';
num1.toString(); //常用
运算符
表达式:由操作数、运算符、变量等组成的式子
10 + 8
⬇ ⬇ ⬇
操作数 运算符 操作数
小括号
小括号 | |
---|---|
() | 优先级最高 |
一元运算符
一元运算符 | |
---|---|
++ | 前置自减(i),后置自减(i)。 |
— | 前置自减(—i),后置自减(i—)。 |
- 后置自增:先用再加。先返回原值,再自己+1。
- 前置自增:先加再用
- 前置自增和后置自增单独使用没有区别。
- 面试题型:
let a = 3;
let b = 4;
3 + 4 + 5 + 6
alert(a++ + b++ + ++a + ++b)
//因为先进行了a++ ,当执行到++a时,a的值已经变成了4,而==a先自增再进行运算,所以a变成了5
算术运算符
算数运算符 | 作用 |
---|---|
+ | 求和(也有连字符的作用) |
- | 求差 |
* | 求积 |
/ | 求商 |
% | 取模(取余数)(开发中经常用来验证某个数字是否被整除) |
关系运算符(比较运算符)
关系运算符(比较运算符) | 含义 |
---|---|
> | 大于 |
>= | 大于或等于 |
< | 小于 |
<= | 小于或等于 |
== | 等于(只比较结果不比较类型),1==”1” 结果为true |
!= | 不等于 |
===(全等) | 既要判断类型 也要判断值 |
!== | 不全等于 |
- 得到的都是
布尔值
- 一般是都是对
数字作比较
- 对
字符串做比较 更多是判断两者是否相等
- 两个等号 == 运算符,会进行隐式转换后比较值是否相等
- 1.undefined等于null // true
2.字符串和数字比较时,字符串转数字
3.数字为布尔比较时,布尔转数字
4.字符串和布尔比较时,两者转数字 - js中没有连比
2 <= 4 <= 7 //错误的写法
NaN === NaN
// false 不自等- isNaN函数可以判读某个变量是否为NaN
isNaN(NaN) //true
isNaN(9) //false
- isNaN函数可以判读某个变量是否为NaN
- 但只要变量传入Number()的执行结果为NaN,则NAN函数都会得到true
isNaN(undefined) //true
isNaN('快乐') //true
isNaN(null) //false
- js处理小数可能会丢失精度问题 最好不要比较小数
解决办法:进行小数运算时调用数字的toFixed()方法,保留指定的小数位数alert(0.2 + 0.4===0.6); // false
alert(0.2 === 0.2); //true
//解决办法
Number((0.2 + 0.4).toFixed(2)) //0.6
向上取整和向下取整
- Math.ceil() 向上取整
- Math.floor() 向下取整
Math.ceil(2.4) //3
Math.floor(2.4) //2
Math.ceil(-2.4) //-2
Math.floor(-2.4) //-3
Math.ceil(3) //3
Math.floor(3) //3
相等和全等
1 == true //true
1 === true //false
0 == undefined //false
0 === undefined //false
undefined == null //true
undefined === null //false,因为类型不同
//null → object
//undefined → undefined
- 字符串比较
(不要face)
console.log("2" > "19");
//"2" 和 "1"做比较,如果"2" > "1"得出结果,不会再往下去判断"2" 和 "9"
- "2" 和 "19" 看成是数字 ,**本质是字符串** , "2" 和 "1"字符串做比较
- 运算符两侧如果有一个是字符串和一个是数字,把字符串转成数字再去比较
12. 类型转换再比较
```javascript
console.log(4 > '3'); //true 隐式转换了
console.log(4 > Number('3')); //类型转换再比较 true
逻辑运算符
逻辑运算符 | 含义 |
---|---|
&& | 逻辑与 一假则假 |
|| | 逻辑或 一真则真 |
! | 逻辑非 (单目运算符,只需要一个操作数) |
!true //false
!false //true
!0 //true
!undefined //true
!'' //true
!'haha' //false
!!true //求true的相反的相反 true
//两个!!的值可以看出值本身是真值还是假值
//!!真正工作中常进行布尔值的转换
赋值运算符
对变量进行赋值的运算符
赋值运算符 | 将等号右边的值赋予给左边, 要求左边必须是一个变量 | 示例 |
---|---|---|
= | 把等号右侧操作数的值直接复制给左侧的操作数 | a = b |
+= | 加法运算或连接操作并赋值 | a += b |
-= | 减法运算并赋值 | a -= b |
*= | 乘法运算并赋值 | a *= b |
/= | 除法运算并赋值 | a /= b |
%= | 取模运算并赋值 | a %= b |
let num = 10;
num -= 2; // num = num - 2 8
num += 2; // num = num + 2 12
num *= 2; // num = num * 2 20
num /= 2; // num = num / 2 5
console.log(num);
补充知识点:赋值运算也产生值,等号后面的值将作为”赋值运算的值”
let a;
console.log(a = 5); //5
//这就意味着,可以连续使用赋值运算符
let a, b, c;
a = b = c = 10;
console.log(a); //10
console.log(b); //10
console.log(c); //10
逗号运算符
逗号运算符 | |
---|---|
, | 运算符优先级最低 |
运算符优先级
优先级 | 运算符 | 顺序 |
---|---|---|
1 | 小括号 | () |
2 | 一元运算符 | ++ — |
3 | 算数运算符 | 先 * / % 后 + - |
4 | 关系运算符 | > >= < < <= |
5 | 相等运算符 | == != === !== |
6 | 逻辑运算符 | ! 先 && 后 || 逻辑非优先级最高 |
7 | 赋值运算符 | = |
8 | 逗号运算符 | , |
逻辑非优先级最高
- 同时使用多个运算符编写程序时,会按着顺序先后执行,我们称为优先级。
- JavaScript中 优先级越高越先被执行,优先级相同时以书从左向右执行。
- 乘、除、取余优先级相同
- 加、减优先级相同
- 乘、除、取余优先级大于加、减
- 使用 () 可以提升优先级
- 总结: 先乘除后加减,有括号先算括号里面的~~~
短路
- 利用逻辑运算符的规则 ,判断代码如何执行
- 短路运算结果 通常是用来运算结果(最终谁被运算,表达式就等于谁)
- 空的 否定的都是假的,其余都是真的
0 “”空字符串 null undefined NaN
逻辑中断逻辑与
- 如果表达式1为真,则返回表达式2
- 如果表达式1结果为假,则返回表达式1,因为表达式二被‘短路了’
- 后面的值决定了总结果
都真才真
| 与运算 | 结果 | | —- | —- | | true && true | true | | true && false | false | | false && true | false | | false && false | false |
a && b //都真才真
//b真结果就真
//b假结果就假
逻辑或短路运算
- 如果表达式1结果为真,则返回表达式1,因为表达式二被‘短路了’
- 如果表达式1结果为假,则返回表达式2
有真就真
| 或运算 | 结果 | | —- | —- | | true || true | true | | true || false | true | | false || true | true | | false || false | false |
let num = 0;
console.log(123 || num++); //表达式1为真,后面不执行 结果为123
//从上面可知:逻辑运算的优先级是 非 → 与 → 或
!true || true //true
3 && 4 || 5 && 6 //4
条件语句
最简单基本的流程控制,没有特定的语法结构,程序会按照代码的先后来执行,依次执行。
If语句
无论多少个选择语句,最终只会有一个语句被执行
If 单分支
if (条件表达式) {
语句
}
If 双分支
if (条件表达式) {
语句1
} else {
语句2
}
// 每个 个位上的数字的 n 次幂之和等于它本身
// 拆位 百位 十位 个位 除法 取余
// 同时满足 与 弹出是水仙花数
1. let num = +prompt("请输入数");
//对用户输入的数值,进行合法性的验证
// 数字 100 - 999之间的数字
if (!isNaN(num) && num >= 100 && num <= 999) {
// 数学方法
// 百位
let a = Math.floor(num / 100);
// 十位
let b = Math.floor(num / 10) % 10;
// 个位
let c = num % 10;
if (Math.pow(a, 3) + Math.pow(b, 3) + Math.pow(c, 3) == num) {
alert('是水仙花数')
} else {
alert('不是水仙花数')
}
} else {
// 输入不合法
alert('请输入三位纯数字')
}
2.let num = +prompt("请输入数");
//对用户输入的数值,进行合法性的验证
// 数字 100 - 999之间的数字
if (!isNaN(num) && num >= 100 && num <= 999) {
// 把数字num变为字符串
let num_str = num.toString();
// 百位
let a = Number(num_str.charAt(0));
// 十位
let b = Number(num_str.charAt(1));
// 个位
let c = Number(num_str.charAt(2));
if (Math.pow(a, 3) + Math.pow(b, 3) + Math.pow(c, 3) == num) {
alert('是水仙花数')
} else {
alert('不是水仙花数')
}
} else {
// 输入不合法
alert('请输入三位纯数字')
}
If 多分支
if (条件表达式1) {
语句1
} else if (条件表达式2) {
语句2
} else if (条件表达式3) {
语句3
} else if (条件表达式4) {
语句4
} else {
语句5
}
三元运算符
表达式 ? 表达式1 : 表达式2
如果表达式为真则返回表达式1,如果表达式为假则返回表达式2
let num1 = 10;
let num2 = 20;
console.log(num1 > num2 ? num1 : num2); //20
//个位数的数字补0
let num = +prompt("请输入数字");
alert(num < 10 ? '0' + num : num)
let num1 = 10;
let num2 = 20;
console.log(num1 > num2 ? num1 : num2);
Switch语句
用途:
根据某个条件是否成立,在两个不同值中选择变量的值
- 开发里表达式常写成变量
- num的值必须和case的值全等(===)才能匹配
- 没有break不退出,会继续执行当前case的下一个case
- 多条case可以共用一个语句体
// 判断一个月有多少天
let year = +prompt("请输入年份");
let month = +prompt("请输入月份")
// 根据月份来分类讨论
switch (month) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
alert("这个月有31天");
break; //记得退出
case 4:
case 6:
case 9:
case 10:
alert("这个月有30天");
break; //记得退出
case 2:
// 根据输入的年份判断今年是否是闰年
if (year % 4 == 0 && year % 100 != 0 || year % 100 == 0 && year % 400 == 0) {
// 满足闰年条件
alert("这个月有29天");
} else {
alert("这个月有28天");
}
break; //记得退出
}
循环语句
for循环
使用for循环可以简化程序
for (声明记录循环次数的变量; 循环条件; 变化值) {
循环体
}
for (循环变量; 条件表达式; 操作表达式) {
循环体
}
- 如果满足循环条件则一直循环,不满足则退出
- for循环执行机理
小例子: for (let i = 15; i > 2; i -= 3) {
console.log(i)
}
//15 12 9 6 3
for (let i = 2; i < 12; i += 3) {
i += 4; //也会影响i
console.log(i);
}//6 13
- 死循环
// 死循环
for (let i = 1; i < 100; i--) {
console.log(i);
}
// 如果输出i就是100
双重for循环
for(外层的初始化变量; 外层的条件表达式; 外层的操作表达式) {
for(里层的初始化变量; 里层的条件表达式; 里层的操作表达式) {
执行语句
}
}
//外层循环循环一次,里层循环执行完所有
// 九九乘法表
let str = '';
for (let i = 1; i <= 9; i++) {
for (let j = 1; j <= i; j++) {
str += j + '*' + i + '=' + j * i + '\t'
}
// 外层循环每循环结束一行就换行
str += '\n'
}
console.log(str);
while循环
- 事先不指定循环开始、结束的范围,只要测试条件满足,就一直执行循环体
while (测试条件) {
}
- while循环没有显示定义循环变量,必须自己在while循环外定义好循环变量,有时可以没有循环变量
- 循环体内的语句,必须使循环条件趋向不成立,否则会死循环
// 页面输出1-100
let i = 0;
while (i <= 100) {
document.write(`${i}<br>`);
i++
}
// 计算1加到100的总和并输出
let i = 0;
let sum = 0;
while (i <= 100) {
// sum += i;
// i++;
sum += i++; //等于sum += i 和 i++
}
document.write(sum);
// 计算1-100之间的所有偶数和
1. let i = 0;
let sum = 0;
while (i <= 100) {
//这一行不能直接执行,需要满足下面的条件才执行
if (i % 2 == 0) {
sum += i;
}
//无论当前的i时偶数还是奇数 i++都要执行 因为必须要进行下一轮的循环
i++;
}
document.write(sum)
2. let i = 0;
let sum = 0;
while (i <= 100) {
//利用短路
//只有左边满足条件了等于true 才会执行右边的代码
(i % 2 == 0) && (sum += i);
i++;
}
document.write(sum)
//小兔子拔萝卜,第1天拔1个,第2天拔2个,第3天拔3个.。。
//问第几天能拔到500个
//天的序号
let day = 1;
//累加器
let sum = 0;
while (sum < 500) {
sum += day;
day++;
}
//注意:这里有个"出一错误"
console.log(day - 1);
// 没办法避免"出一错误",只能人为减一了
//穷举法,从1开始试验
//需求:满足n的平方大于456789的最小的整数
let n = 1;
while (n * n <= 456789) {
n++;
}
console.log(n)
do while循环
- 循环体一定会至少执行一次,然后再检测条件是否为true,决定是否继续执行循环体。先执行在判断
do {
循环体
} while (循环执行条件)
- 输出1、2、3到100.
let n = 1;
do {
// 先执行一次,输出1
console.log(n);
n++;
} while (n < 101);
do while更擅长获取随机数
提前拓展: 随机数函数(得到0-1之间的小数)
`Math.random()`
取得介于 1 到 10 之间的一个随机数
Math.floor((Math.random() * 10 ) + 1 );
得到[a,b]区间的整数,包含a和b。公式:
(Math.random() * (max - min + 1) ) + min
//小案例
//随机生成两个变量,a和b,它们都在[-4,4]之间随机取值,但是都不能为0
do {
var a = parseInt(Math.random() * 9) - 4
var b = parseInt(Math.random() * 9) - 4
} while (a == 0 && b == 0)
console.log(a, b);
// 保证了只要退出循环,a和b都不是0
循环退出
continue
结束本次循环,跳过后面的代码,继续下次循环
for (let i = 0; i < 5; i++) {
if (i === 3) {
// 如果i=3的时候,跳出这个循环,不再执行后面的代码
continue;
}
console.log(i); // 0 1 2 4
}
break
- 立即终止循环,只能用在循环语句中
-
跳出整个所在的循环
在for循环中 ```javascript for (let i = 0; i < 10; i++) { console.log(i); // 0 1 2 3 4 if (i == 4) { // 当i=4终止整个循环
break;
} }
for (let i = 0; i < 10; i++) { if (i == 4) { // 当i=4终止整个循环 break; } console.log(i); // 0 1 2 3 }
4. 在while中,通常和while(true){}搭配使用
```javascript
//例子
let n = 1;
while (true) {
if (n * n > 456789) {
console.log(n);
break;
}
n++;
}
for循环和while循环的区别
- 当如果明确循环的次数的时候推荐使用for循环
- 当不明确循环的次数的时候推荐使用while循环
流程控制语句综合
//猜数字
let answer = parseInt(Math.random() * 98) + 2;
let min = 1;
let max = 100;
// 为了不断地循环,使用死循环
while (true) {
let num = +prompt(`请猜测数字,在${min}~${max}之间`);
if (num <= min || num >= max) {
alert("输入的数字不在范围内");
// 跳过本次循环,开启下一次迭代
continue;
}
// 范围的最小值和最大值,为了方便提示用户区间
if (num > answer) {
alert("您输入的数字太大了");
// 因为用户输入的数字太大,所以可以将最大范围设置为用户输入的数字
max = num
} else if (num < answer) {
alert("您输入的数字太小了");
// 因为用户输入的数字太小,所以可以将最小范围设置为用户输入的数字
min = num;
} else {
alert("您答对了");
// 结束循环
break;
}
}
注意
- 在JavaScript中,所有代码指令都会以分号结尾 (
;
) — 如果忘记加分号,你的单行代码可能执行正常,但是在多行代码在一起的时候就可能出错。所以,最好是养成主动以分号作为代码结尾的习惯。 (以后有工具统一格式化)