一、JavaScript介绍
一、JavaScript书写位置
1、内部:直接写在HTML里script标签写在上面
2、外部:写在js文件里,通过
二、JavaScript注释
1、单行注释:
//
快捷键:ctrl+/
2、多行注释:
/**/
快捷键:shift+alt+A
三、JavaScript输入输出语法
1、输出语法
语法1:document.write(‘要输出的内容’)
作用:向boody内输出内容
注意:如果输出的内容写的是标签会被解析成网页元素。
语法2:alert(‘要输出的内容’)
作用:页面弹出警告对话框
语法1:console.log(‘控制台打印’)
作用:控制台输出语法,程序员调试使用
2、输入语法
语法:prompt(‘请输入姓名:’)
作用:显示一个对话框,对话框包含一条文字信息,用来提示用户输入文字
二、变量
一、变量是什么
变量就是计算机存储数据的盒子
二、变量的基本使用
1、声明变量:
要想使用变量首先要创建变量。
语法:let 变量名
举例:let age (声明了一个变量名为age的变量
2、变量赋值
首先要声明变量
let age
然后给变量赋值
age = 18
符合写法
let age = 18
3、注意:
不允许声明多个相同变量。
可以同时生成多个不同的变量但不提倡:
let age = 18, unanme = ‘张三’
提倡:
let age = 18
let uname = ‘张三’
控制台可以一行写
console.log(age,uname)
4、变量名命名规范
不能用关键字如let,var,if,for等
只能用下划线、字母、数字、$组成,且数字不能开头
严格区分大小写
top,name不能命名
起名要有意义
小驼峰命名法,第一个单词小写,后面每个单词首字母大写
三、数组
一、声明语法
let 数组名 = [数据1,数据2,…,数据n]
例
let names = [‘小明’ , ‘小刚’ , ‘小红’]
数组是按顺序保存的,所以每个数据都有编号
计算机编号从0开始
数组可以储存任意类型的数组
数组中的每一条数据称为元素
二、取值语法
数组名[下标]
三、遍历数组
<script>
for(let i = 0; i < nums.length; i++) {
数组名[下标]
}
</script>
四、数组-改
数组名[下标] = 数据,在指定位置修改数据
<script>
let arr = ['upupa','upupu','upupdada']
for (let i = 0; i < arr.length; i++) {
arr[i] = arr[i] + '老师'
document.write(arr[i])
}
</script>
numArr[1] = 6//将数组中下标为1的数据改为6
五、数组-增
数组名.push(增加的数据)在最后添加,可以多个数据,并且返回新的数组长度
数组名.unshift(增加的数据)在开头添加,可以多个数据,并且返回新的数组长度
数组名[下标] = 数据,在指定位置添加数据
arr.push('pink')//在最后添加一个pink的数据
numArr[5] = 6//在数组后下面再添加一个下标为5的数据:6
六、数组-删
数组名.pop()删除数组中最后一条数据,并返回删除的元素
数组名.shift()删除数组中第一条数据,并返回删除的元素
数组名.splice(要删除数据的索引号,索引号开始往后删除的个数)//后面的参数不写默认从选择的索引号开始删完
arr.splice(1,2)//从第1个索引号开始往后删除 2个数据
numArr.length = 4//删除数组长度为4
<script>
let arr = [12,56,87,0,54,0,0,885]
//删除出最后一个
arr.pop()
//删除第一个
arr.shift()
//从索引号2开始删除3个
arr.splice(2,3)
//从索引号1开始删完
arr.splice(1)
console.log(arr)
</script>
四、常量
一、基本使用
概念:使用const声明的变量称为常量。
使用场景:当某个变量永远不会改变,就可以使用const来声明。
常量使用:
const G = 9.8
console.log(G)
注意:常量不允许重新赋值,声明的时候必须赋值。
五、数据类型
一、基本数据类型
number 数字型
string 字符串型
boolean 布尔型
undefined 未定义型
null 空类型
1.数字类型(Number)
数字可以有很多操作
+:求和
-:求差
*:求积
/:求商
%:取余(经常作为某个数字是否被整除)
运算时有优先级
NaN代表一个计算错误。
2.字符串类型(string)
通过单引号,双引号,反引号包裹的都是字符串。
字符串拼接:+运算符 可以实现字符串的拼接
数字相加,字符相连
模板字符串:
document.write(`大家好,我叫${name},今年${age}岁`)
3.布尔类型(boolean)
true flase
4.未定义类型(undefined)
变量没内容
let num
console.log(num)输出就为undefined
5.空类型(null)
变量有内容,为空
let obj = null
console.log(obj)输出就为null
二、检测数据类型
typeof用来检测数据类型
typeof 数据;
typeof(数据);
<script>
let num = 10
console.log(typeof num)//输出为number
let str = 'pink'
console.log(typeof str)//输出为string
let flag = false
console.log(typeof flag);//输出为boolean
let un
console.log(typeof un);//输出为undefined
let obj = null
console.log(typeof obj);//输出为object
</script>
三、数据类型转换
1.隐式转换
加号两边只要有一个字符串,都会把另一个转换成字符串
除了+以外的算术运算符 比如- * /都会把数据转换成数字类型
<script>
console.log(1+1);//2
console.log('pink'+1);//pink1
console.log('pink'-1);//NaN
console.log(2+'2');//22
console.log(2-'2');//0
console.log(+12);//12
console.log(+'12');//12(number类型)
console.log('' - 2);//-2
console.log(null + 2);//2
console.log(undefined + 2);//2
</script>
2.显示转换
number(数据)
转换成数字类型,转换失败结果为NaN(not a number)
parseInt(数据)
只保留整数
parseFloat(数据)
可以保留小数
String(数据);
变量名.toString()
console.log(num+‘’)
转换成字符串
Boolean(数据)
转换成布尔类型
" "、0、undefined、null、false、NaN转换为布尔类型后都是false,其余都为true
<script>
let str = '123'
console.log(Number(str));//123number类型
console.log(Number('pink'));//NaN
console.log(Number(true));//1
console.log(Number(false));//0
console.log(Number(undefined));//NaN
console.log(Number(null));//0
let num =Number(prompt('输入年薪'))
console.log(num);//输出为number类型
let num1 = prompt('请输入年薪')
console.log(Number(num1));//输出为number类型
console.log(parseInt('12px'));//12
console.log(parseInt('12.34px'));//12
console.log(parseInt('abc12.34px'));//NaN
console.log(parseFloat('12px'));//12
console.log(parseFloat('12.34px'));//12.34
console.log(parseFloat('abc12.34px'));//NaN
//String(数据)
console.log(String(123))
//变量名.toString(),需要借助变量调用 toSting
let num = 123
console.log(num.toString())
//隐式转换
console.log(num+'')
</script>
三、流程控制
一、运算符
1.赋值运算符
可以用:+= , -= , *= , /= ,%=来给数据赋值计算
<script>
//以前
let num = 1
num = num + 1
console.log(num);//2
//现在
let num1 = 1
num1 += 1
console.log(num1);//2
let arr = [10,30,54,21]
arr[3] += 6
console.log(arr) //[10,30,54,27]
</script>
2.自增运算符
一元运算符:
只有一个操作数
++ , –
一般使用后置自增
<script>
// 前置自增
let num = 1
num ++
console.log(num);//2
//后置自增
let num1 = 1
++num
console.log(num1);//2
//前置后置区别
let num2 = 1
console.log(++num + 1);//3(前置是先自增)
console.log(num++ + 1);//2(后置是在第一个算式结束时自增,这行代码结束后num已经是3了)
</script>
3.比较运算符
1.==不比较数据类型
2.===还要比较数据类型
3.!==也要比较数据类型
<script>
console.log(3 > 5);//flase
console.log(3 >= 3);//true
console.log(2 == 2);//true
console.log(2 == '2');//true,不比较数据类型
console.log(2 === '2');//flase,要比较数据类型
console.log(NaN === NaN);//NaN不等于任何数据,包括自己
console.log(2 !== '2');//true
console.log(2 != '2');//flase
</script>
4.逻辑运算符
1.&&:与,一假则假
2.||:或,一真则真
3.!:非,取反
<script>
//逻辑与 一假则假
console.log(true && true)//true
console.log(false && true)//false
console.log(3 < 5 && 3 > 2)//true
console.log(3 < 5 && 3 < 2)//false
//逻辑或 一真则真
console.log(true || true);//true
console.log(false || true);//true
console.log(false || false);//flase
//逻辑非 取反
console.log(!true);//false
console.log(!false);//true
</script>
逻辑运算符优先级:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-upZ2BS0w-1658822076100)(img/yunsuanfuyouxianji.png)]
二、语句
1.顺序结构
从上往下按顺序执行
2.分支结构
1.if分支语句
单分支
<script>
//条件里结果只有true/false,
if(条件) {
满足条件要执行的代码
}
//单分支语句
if(false) {
console.log('执行语句')//没有执行
}
if(3 < 5) {
console.log('执行语句')//输出为执行语句
}
//除了0所有数字都为true
if(1) {
console.log('执行语句')//输出为执行语句
}
//除了空字符串''其它字符串都为真
if('pink') {
console.log('执行语句')//输出为执行语句
}
</script>
双分支
<script>
if(条件) {
满足要执行的代码
}else {
不满足执行的代码
}
</script>
多分支
<script>
if(条件1) {
满足1要执行的代码并结束语句
}else if(条件2) {
不满足条件1,满足条件2执行的代码并结束语句
}else {
不满足执行的代码并结束语句
}
</script>
2.三元运算符
条件 ? 满足条件执行的代码 : 不满足条件执行的代码
<script>
3<5 ? 3 : 5 //输出为3
</script>
3.switch分支语句
<script>
switch (数据) {
case 数值1:
代码1 //如果数据===数值1则输出这行代码并退出
break
case 数值2:
代码2 //如果数据===数值2则输出这行代码并退出
break
case 数值3:
代码3 //如果数据===数值2则输出这行代码并退出
break
defult:
代码n //如果都不满足则输出这行代码并退出
break//可省略
}
</script>
4.if else和switch case的区别
if else判断范围更广,switch case通常处理case值比较确定的情况;
分支少时if else执行效率更高;
分支多时switch case执行效率更高;
要注意的是switch必须是===。
3.循环结构
1.while循环
whille(循环条件) {
要重复执行的代码(循环体)
}
<script>
//1.变量起始值
let i = 1
//2.终止条件
while (i <= 3) {
document.write('我要循环三次')
//3.变量的变化量
i++
}
</script>
2.结束循环
break退出整个循环语句
continue退出当前循环语句,继续执行下一条
<script>
let i = 1
while (i <= 5) {
if (i===3) {
// break //退出循环,直接退出整个循环
i++
continue //退出当前循环语句后面的语句不会再执行 ,直接跳到新的循环,所以要在continue之前添加i++
}
document.write(`我要吃${i}个包子`)
i++
}
</script>
3.for循环
for (变量起始值; 终止条件; 变量变化量;) {
//循环体
}
<script>
for (let i = 0; i <= 3; i++) {
console.log('月薪过万');
}
</script>
4.for while循环的区别
明确循环次数的用for循环;
不明确循环次数的用while。
5.嵌套循环
for(外部声明记录循环次数的变量; 循环条件; 变化值;) {
for(内部声明记录循环次数的变量; 循环条件; 变化值;) {
循环体
}
}
<script>
for (let i = 1; i < 4; i++) {
document.write(`第${i}天<br>`)
for (let j = 1; j < 6; j++) {
document.write(`今天的第${j}个单词<br>`)
}
}
/*输出为第1天
今天的第1个单词
今天的第2个单词
今天的第3个单词
今天的第4个单词
今天的第5个单词
...*/
</script>
三、函数
1.函数的作用:
可以执行特定任务的代码块,可以实现代码复用,有利于精简代码
2.使用函数 :
1.函数的命名规范:
小驼峰命名法
前缀为动词
2.声明函数(封装函数)
function 函数名() {}
fuction sayHi() {
console.log('hi~~~')
}
3.函数的调用方法
函数名(),必须要加小括号
sayHi()
4.函数参数
fuction 函数名(形参列表) {
函数体
}
函数(实参)
形参:声明函数时写在函数名右边括号里
实参:调用函数时写在函数名右边括号里(实参可以是变量)
形参可以理解为在函数内声明的变量,实参理解为给变量赋值
开发中实参个数尽量与形参个数一致
5.函数的默认值
如果用户不输入实参就会出现(undefined,undefiend)
因此我们可以在形参后添加(start = 0, end = 0)//形参后面不一定跟的是0,如数组后跟=[]
<script>
function getSum(x = 0, y = 0) {
document.write(x+y)
}
getSum()//结果时0而不是NaN
getSum(1,2)//结果是3
</script>
6.函数返回值
当调用某个函数,这个函数会返回一个结果,
这就是有返回值的函数
<script>
//声明函数
function fn() {
return 20//返回值
}
//声明变量调用函数
let re = fn()
//输出函数
console.log(re)
</script>
7.函数细节补充
1.两个相同的函数后面的会覆盖前面的函数
2.js中实参和形参的个数可以不一致
如果形参过多,会自动填上undefined
如果实参过多,多余的实参会被忽略(函数内部用一个arguments,里面装着所有实参)
3.函数一旦碰上return就不会再往下执行了,函数的结束用return
8.作用域
限定代码可用性范围的称为作用域
全局作用域
全局有效,作用于整个代码所执行的环境(函数外部)
和.js文件是全局作用域全局变量
全局作用域里的变量称为全局变量,任何区域都可以访问和修改
块级作用域
局部有效,作用于函数内的代码环境。因为跟函数有关系,所以也称为函数作用域。
局部变量
局部作用域里的变量称为局部变量,只能在当前函数内访问和修改
**
如果局部变量未用let也当全局变量
形参可以看作函数的局部变量
变量的访问原则
在能够访问到的情况下先局部,局部没有再找全局(就近原则)
9.匿名函数
没有函数名的函数
fuction() {}
使用方式
1.函数表达式
将匿名函数赋值给一个变量,并且通过变量名称进行调用,我们将其称为函数表达式
语法:
<script>
let fn = function() {
//函数体
}
fn()//变量名()
</script>
函数表达式与具名函数的不同:
函数表达式中调用函数要写在声明变量后,
具名函数调用函数可以写在任意位置
2.立即执行函数
避免全局变量之间污染
无需调用立即执行,用’ ; '隔开
<script>
// 第一种写法
(function () { })();
(function (x, y) {
console.log(x + y)
})(1, 2);
// 第二种写法
(function () {}())
(function (x, y) {
console.log(x + y)
}(1, 2));
</script>
10.逻辑中断
在&&和||中,当满足一定条件会让右边代码不再执行
&& 左边为false时中断
|| 左边为true时中断
因此我们可以利用逻辑中断来给变量的形参赋初始值
语法:
<script>
function fn(x, y) {
x = x || 0
y = y || 0
console.log(x + y)//0而不是NaN
}
fn()
</script>
11.对象
对象是一种数据类型 ,无序的数据的集合,可以详细的描述某个事物。
1.对象的声明方法
let 对象名 = {
属性名: 属性值,
方法名: 函数
}
属性:
属性一般是名词;
属性和属性值之间用’ : '分隔
属性之间用’ , '分隔
属性名可以用’ '包起来,通常可以用在属性名带有特殊符号时//‘goods-name’: HUAWEI,
方法:
方法一般是动词;
方法名和函数之间用’ : '分隔
方法也要用’ , '分隔
方法是依附在对象中的函数
方法名也可以用’ '包起来,情况和属性相同
2.对象-查
语法:
对象名.属性
对象名[‘属性’]一定要带’ ’ 当属性名带’ '时用这个方法可以查到
3.对象-改
语法:
对象名.属性 = 新的属性值
4.对象-增
语法:
对象名.新属性 = 属性值
5.对象-删
语法:
delete 对象名.属性
6.对象中方法的调用
对象名.方法(实参)
<script>
let obj = {
uname: '吴彦祖',
age: '18',
genrel: '男',
fn: function (x, y) {
console.log(x + y)
}
}
obj.uname = '王城'//修改属性uname的属性值
obj.marry = '未婚'//添加新属性
delete obj.genrel//删除genrel属性
obj.fn(1, 2)//调用obj对象的fn方法--function函数
console.log(obj['age'])//查看age属性
console.log(obj.age)//查看age属性
console.log(obj)//输出obj对象
7.遍历对象
----for in----
语法:
<script>
for (let k(可以是任何字习惯用k/key) in 对象名) {
console.log(k)//输出的是对象的各个属性名,*并且是字符串型*
console.log(obj.k)//输出会是undefined,因为k是字符串型
console.log(obj[k])//输出的就是各个属性值,因为obj[' ']也能用来查询属性,并且[ ]内放的是字符串类型
}
</script>
8.内置对象
数学函数Math:
Math.ceil(数字)//向上取整
Math.floor(数字)//向下取整
Math.round(数字)//四舍五入,负数时-1.51===-2但-1.5===-1。
Math.max(数字)//取最大值
Math.min(数字)//取最小值
Math.bas(数字)//取绝对值
Math.pow(4, 2)//4的2次方
Math.sqrt(16)//16的平方根
可以在MDN中查询。。。
内置对象生成随机数
Math.random()//返回0-1之间的随机数,包括0不包括1
生成0-10的随机数:
Math.floor(Math.random() * (10 + 1))//因为 随机数不包括1所以乘11
生成5-10的随机数:
Math.floor(Math.random() * (5 + 1)) + 5//给0+5就是5-10
生成N-M之间的随机数:
Math.floor(Math.random() * (M - N + 1)) + N
输出数组中随机元素:
<script>
let arr = ['aaa', 'bbb', 'ccc']
let random = Math.floor(Math.random() * arr.length)
console.log(arr[random])
</script>
四、栈和堆
内存分为栈和堆,
基本数据类型的值存在栈里,复杂数据类型、引用数据类型的值存在堆里。
但是复杂数据类型和引用数据类型还有一个地址存在栈里,在取他们的值时,是通过栈里的地址来找到堆里的值。
因此就有了:
<script>
let num1 = 10
let num2 = num1//在栈里又储存了一个10
num2 = 20//将nmu2在栈里储存的10改为20,并不会影响到num1的10
console.log(num1)//输出为10
let obj1 = {
age: 18
}//在堆里储存一个18,在栈里储存一个地址用来找到堆里的18
let obj2 = obj1//在栈里储存一个和obj一样的地址
obj2.age = 20//通过栈里的地址找到堆里的18改成20
aonsole.log(obj1.age)//20此时obj1通过地址找到的堆里的值已经改成了20
</script>
)//取最小值
Math.bas(数字)//取绝对值
Math.pow(4, 2)//4的2次方
Math.sqrt(16)//16的平方根
可以在MDN中查询。。。
内置对象生成随机数
```js
Math.random()//返回0-1之间的随机数,包括0不包括1
生成0-10的随机数:
Math.floor(Math.random() * (10 + 1))//因为 随机数不包括1所以乘11
生成5-10的随机数:
Math.floor(Math.random() * (5 + 1)) + 5//给0+5就是5-10
生成N-M之间的随机数:
Math.floor(Math.random() * (M - N + 1)) + N
输出数组中随机元素:
<script>
let arr = ['aaa', 'bbb', 'ccc']
let random = Math.floor(Math.random() * arr.length)
console.log(arr[random])
</script>
四、栈和堆
内存分为栈和堆,
基本数据类型的值存在栈里,复杂数据类型、引用数据类型的值存在堆里。
但是复杂数据类型和引用数据类型还有一个地址存在栈里,在取他们的值时,是通过栈里的地址来找到堆里的值。
因此就有了:
<script>
let num1 = 10
let num2 = num1//在栈里又储存了一个10
num2 = 20//将nmu2在栈里储存的10改为20,并不会影响到num1的10
console.log(num1)//输出为10
let obj1 = {
age: 18
}//在堆里储存一个18,在栈里储存一个地址用来找到堆里的18
let obj2 = obj1//在栈里储存一个和obj一样的地址
obj2.age = 20//通过栈里的地址找到堆里的18改成20
aonsole.log(obj1.age)//20此时obj1通过地址找到的堆里的值已经改成了20
</script>