变量、数据类型
JavaScript介绍
JavaScript是什么
-
JavaScript(是什么?)
是一种运行在客户端(浏览器)的编程语言,实现人机交互效果。 -
作用(做什么?)
一 网页特效(监听用户的一些行为让网页作出对应的反馈)
一表单验证(针对表单数据的合法性进行判断)
一 数据交互(获取后台的数据,渲染到前端)
一 服务端编程(node.js) -
JavaScript的组成(有什么?)
—ECMAScript:
规定了js基础语法核心知识。
比如:变量、分支语句、循环语句、对象等等
—Web APIs:
DOM 操作文档,比如对页面元素进行移动、大小、添加删除等操作
BOM 操作浏览器,比如页面弹窗,检测窗口宽度、存储数据到浏览器等等
权威网站: MDN
JavaScript权威网站:
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript
JavaScript书写位置
内部JavaScrip
直接写在html文件里,用script标签包住
规范:script标签写在上面
拓展:alert(‘你好,js’)页面弹出警告对话框
<script>
alert('嗨')
</script>
</body>
注意事项:
我们将<script>放在HTML文件的底部附近的原因是浏览器会按照代码在文件中的顺序加载HTML。如果先加载的JavaScript期望修改其下方的HTML,那么它可能由于HTML尚未被加载而失效。因此,将JavaScript代码放在HTML页面的底部附近通常是最好的策略。
外部JavaScript
代码写在以.js结尾的文件里
语法:通过script标签引入到html页面中
<body>
<!--通过scr引入外部js文件-->
<script scr="my.js"></script>
</body>
注意事项:
1.script标签中间无需写代码,否则会被忽略!
2.外部JavaScript会使代码更加有序,更易于复用,且没有了脚本的混合,HTML也会更加易读,因此这是个好的习惯。
内联JavaScript
代码写在标签内部,了解即可
<body>
<button onclick="alert('哈哈哈')">点我</button>
</body>
JavaScript的注释
- 单行注释
符号://
作用://右边这一行的代码会被忽略
快捷键:ctrl+/ - 块注释
符号:/* */
作用:在/和/之间的所有内容都会被忽略
快捷键:shift +alt + a
<script>
//这种是单行注释的语法
//一次只能注释一行
//可以重复注释
</script>
<script>
/*这种的是多行注释的语法*/
/*
更常见的多行注释是这种写法
在些可以任意换行
多少行都可以
*/
</script>
JavaScript的结束符
作用:使用英文的 ;代表语句结束
实际情况:实际开发中,可写可不写,浏览器(JavaScript引擎)可以自动推断语句的结束位置
现状:在实际开发中,越来越多的人主张书写JavaScript代码时省略结束符
约定:为了风格统一,结束符要么每句都写,要么每句都不写(按照团队要求.)
输入和输出语法
输出语法
- 作用:向body内输出内容
注意:如果输出的内容写的是标签,也会被解析成网页元素
document.write('输出的内容')
- 作用:页面弹出警告对话框
alert('输出的内容')
- 作用:控制台输出语法,程序员调试使用
console.log('控制台打印')
输入语法
语法:
prompt('请输入您的姓名:')
作用:显示一个对话框,其中只包含一条文字信息,用来提示用户输入文字
JavaScript代码执行顺序
按HTML文档流顺序执行JavaScript代码
alert()和prompt()他们会跳过页面渲染先被执行
字面量
字面量就是在计算机中描述事/物
比如:
我们工资是:1000 此时1000 就是 数字字面量
'黑马程序员’字符串字面量
还有接下来我们学的[ ]数组字面量 { }对象字面量 等等
变量
变量是什么
变量是计算机中用来存储数据的“容器”
变量基本使用
声明变量
使用变量之前得先创建/声明/定义变量
语法:
let 变量名
let age
-声明变量有两部分构成:声明关键字、变量名(标识)
-let即关键词,所谓关键词是系统提供的专门用来声明(定义)变量的词语
变量赋值
定义了变量后就能够变量赋值
// 1.声明一个age变量
let age
// 2.age变量赋值为18
age=18
// 3.输出age变量
alert(age)
变量初始化:声明变量的时候直接完成赋值操作
<script>
// 1.声明一个age变量,同时里面存放了18这个数据
let age=18
</script>
更新变量
<script>
// 声明一个age变量,同时里面存放了18这个数据
let age=18
//变量里面的数据发生变化更改为19
age=19
//页面输出的结果为19
document.write(age)
</script>
注意:let不允许多次声明一个变量
声明多个变量
不推荐
<script>
let age=18,uname='pink'
</script>
推荐
<script>
//多行变量声明有点长,但更容易阅读
let age=18
let uname='pink'
</script>
案例
- 输入用户名
<script>
//输出用户名案例
//1.用户输入
//prompt('请输入姓名')
//2.内部处理保存数据
let uname=prompt('请输入姓名')
//3.打印输出
document.write(uname)
</script>
- 交互两个变量
<script>
let num1='pink老师'
let num2='hh'
let temp
//都是把右边给左边
temp=num1
num1=num2
num2=temp
console.log(num1,num2)
</script>
变量的本质
变量本质:是程序在内存中申请的一块用来存放数据的小空间
变量命名规则与规范
- 规则:
-不能用关键字(有特殊含义的字符,JavaScript内置的一些英语词汇。例如:let、var、if、for等;
-只能用下划线、字母、数字、$组成,且数字不能开头
-字母严格区分大小写,如Age和age是不同的变量 - 规范:
-起名要有意义
-遵守小驼峰命名法(第一个单词首字母小写,后面每个单词首字母大写,例如:userName
案例
<script>
//1.姓名
let uname=prompt('请输入姓名')
let age=prompt('请输入年龄')
let gender=prompt('请输入性别')
document.write(uname,age,gender)
</script>
变量拓展-let和var的区别
var声明:可以先使用再声明(不合理)
var声明过的变量可以重复声明(不合理)
比如变量提升、全局变量、没有块级作用域等等
常量
概念:使用const声明的变量称为“常量”
使用场景:当某个变量永远不会改变的时候,就可以使用const来声明,而不是let
命名规范:和变量一致
常量使用:
<script>
//声明一个常量
const G=9.8
//输出这个常量
console.log(G)
</script>
注意:常量不允许重新赋值,声明的时候必须赋值
小技巧:不需要重新赋值的数据使用const
数据类型
js数据类型整体分为两大类:
- 基本数据类型(number数字型、string字符串型、boolean布尔型、undefined未定义型、null空类型)
- 引用数据类型(object对象)
数字类型number
Javascript中的正数、负数、小数等统一称为数字类型。
注意事项:js是弱数据类型,变量到底属于哪种类型只有赋值后才能确认。
例子-计算圆的面积:
//1.页面弹出输入框
let r=prompt('请输入圆的半径')
//2.计算圆的面积(内部处理)
let re=3.14*r*r
//3.页面输出
document.write(re)
NaN代表一个计算错误,它是一个不正确的或者一个未定义的数学操作所得到的结果。
console.log('老师'-2) //NaN
NaN是粘性的,任何对NaN的操作都会返回NaN。
console.log(NaN+2) //NaN
字符串类型string
通过单引号(‘’)、双引号(“”)或反引号(``)包裹的数据都叫字符串,单引号和双引号没有本质上的区别,推荐使用单引号。
let uname='小明' //使用单引号
let gender="男" //使用双引号
let goods=`小米` //使用反引号
let tel='11111111' //看上去是数字,但是引号包裹了就是字符串
let str='' //这种情况叫空字符串
注意事项:
1.无论单引号还是双引号必须成对使用
2.单/双引号可以互相嵌套,但是不以自己嵌套自己(口诀:外双内单/外单内双)
3.必要时可以使用转义符\,输出单引号或双引号
模板字符串
- 使用场景:拼接字符串和变量,没有它之前拼接变量比较麻烦
document.write('大家好,我叫'+name+',今年'+age+'岁了')
- 语法:内容拼接变量时,用${}包住变量
document.write(`大家好,我叫${name},今年${age}岁了`)
布尔类型boolean
表示肯定会或否定时在计算机中对应的是布尔类型数据
let isCool=true
console.log(isCool)
未定义类型undefined
只声明变量不赋值的情况下,变量的默认值为undefined,一般很少直接为某个变量赋值为undefined。
let age //声明变量但是未赋值
document.write(age) //输出undefined
工作使用场景:判断用户是否有数据传递过来。
空类型null
Javascript中的null仅仅是一个代表"无"、"空"或"值未知"的特殊值
let obj=null
console.log(obj) //null
null和undefined的区别:undefined表示没有赋值;nul表示赋值了,但是内容为空。
工作场景:有个变量里面存放的是一个对象,但是对象还未创建好,可以先给个null。
通过typeof关键字检测数据类型
typeof运算符可以返回被检测的数据类型,支持两种语法形式:
1.作为运算符:typeof x(常用的写法)
2.函数形式:typeof(x)
let age=18
let uname='刘德华'
let flag=false
let buy
console.log(typeof age) //number
console.log(typeof uname) //string
console.log(typeof flag) //boolean
console.log(typeof buy) //undefined
类型转换
隐式转换
某些运算符被执行时,系统内部自自动将数据类型进行转换,这种转换称为隐式转换。
规则:
1.+号两边只要有一个是字符串,都会把另一个转成字符串
2.除了+以为的算术运算符如-*/等都会把数据转成数字类型
缺点:
转换类型不明确,靠经验才能总结
console.log(11+11) //22
console.log('11'+11) //1111
console.log(11-11) //0
console.log('11'-11) //0
console.log(1*1) //1
console.log('1'*1) //1
console.log(typeof '123') //string
console.log(typeof +'123') //number
console.log(+'11'+11) //22
显示转换
转换为数字型
- Number(数据)
转成数字类型;如果字符串内容里有非数字,转换失败时结果为NaN(Not a Number)即不是一个数字;NaN也是number类型的数据,代表非数字 - parseInt(数据)
只保留整数 - parseFloat(数据)
可以保留小数
let str ='123'
console.log(Number(str)) //123
console.log(Number('pink')) //NaN
// Let num = Number(prompt('输入年薪'))
// Let num = +prompt('输入年薪')
// console.log(Number(num))
// console.Log(num)
console.log(parseInt('12px')) //12
console.log(parseInt('12.34px')) //12
console.log(parseInt('12.94px')) //12
console.log(parseInt('abc12.94px')) //NaN
//---------------------
console.log(parseFloat('12px')) // 12
console.log(parseFloat('12.34px')) // 12.34
console.log(parseFloat('12.94px')) // 12.94
console.log(parseFloat('abc12.94px')) //NaN
求和案例:
// 1. 用户输入 prompt 得到是字符串类型 要转换为 数字型
let num1 = +prompt('请输入第一个数字:')
let num2 = +prompt('请输入第二个数字:')
// 2. 输出
alert(`两个数相加的和是:${num1 + num2}`)
转换为Boolean型
显示转换:
1.Boolean(内容)
‘’、0、undifined、null、false、NaN转换为布尔值后都是false,其余为true
隐式转换:
- 有字符串的加法"“+1,结果是"1”
- 减法-只能用于数字,它会使空字符串""转换为0
- null经过数字转换之后会变为0
- undefined经过数字转换之后会变成NaN
console.log(''-1)//-1
console.log('pink'-1)//NaN
console.log(null+1)//1
console.log(undifined+1)//NaN
console.log(NaN+1)//NaN
实战案例
// 1. 用户输入
let price = +prompt('请输入商品价格:')
let num = +prompt('请输入商品数量:')
let address = prompt('请输入收货地址:')
// 2. 计算总额
let total = price*num
//3.页面打印渲染
document.write('
<table>
<tr>
<th>商品名称</th>
<th>商品价格</th>
<th>商品数量</th>
<th>总价</th>
<th>收货地址</th>
</tr>
<tr>
<td>小米青春版</td>
<td>${price}元</td>
<td>${num}</td>
<td>${total}元</td>
<td>${address}</td>
</tr>
</table>')
运算符、分支、循环
运算符
赋值运算符
num=num+1简化成num+=1
一元运算符
自增运算符的用法:
- 前置自增和后置自增单独使用没有区别
- 前置自增
let num=1
++num //让num的值加1变2
- 后置自增
let num=1
num++ //让num的值加1变2
- 前置自增和后置自增参与运算有区别
- 前置自增:先自加再使用
let i=1
console.log(++i + 2)//结果是4
- 后置自增:先使用再自加
let i=1
console.log(i++ + 2)//结果是3
比较运算符
>:左边是否大于右边
<: 左边是否小于右边
>=: 左边是否大于或等于右边
<=: 左边是否小于或等于右边
==: 左右两边值是否相等
===:左右两边是否类型和值都相等
!==:左右两边是否不全等
比较结果为boolean类型,即只会得到true或false
对比:
=单等是赋值
==是判断
===是全等
开发中判断是否相等,强烈推荐使用===
console.log(3>5)
console.log(3>=5)
console.log(2==2)
//比较运算符有隐式转换把'2'转换为2
console.log(2=='2') //true
console.log(2==='2') //false
console.log(NaN===NaN) //NaN不等于任何人,包括自己
console.log(2!=='2') //true
console.log(2!='2') //false
console.log('a'<'b') //true
console.log('aa'<'ab') //true
console.log('aa'<'aac') //true
逻辑运算符
逻辑运算符里的短路:
短路:只存在于&&和||中,当满足一定条件会让右边代码不执行
&&:左边为false就短路
||:左边为true就短路
原因:通过左边能得到整个式子的结果
运算结果:都是最后被执行的表达式值,一般用在变量赋值
运算符优先级
语句
表达式和语句
区别:
表达式:因为表达式可被求值,所以它可以写在赋值语句的右侧。 num=3+4
语句:而语句不一定有值,所以比如alert()、for和break等语句就不能被用于赋值。 alert()弹出对话框 ;console.log()控制台打印输出
- 程序三大流程控制语句
- 代码从上往下执行几句,这种叫顺序结构
- 根据条件选择执行代码,这种叫分支结构
- 某段代码被重复执行,这种叫循环结构
分支语句
if分支语句
if语句有三种使用:单分支、双分支、多分支
单分支使用语法:
if(条件) {
满足条件要执行的代码
}
双分支使用语法:
if(条件) {
满足条件要执行的代码
} else {
不满足条件执行的代码
}
多分支使用语法:
if(条件1) {
代码1
} else if(条件2) {
代码2
} else if(条件3) {
代码3
} else {
代码n
}
三元运算符
使用场景:其实是比if双分支更简单的写法,可以使用三元表达式
符号:?与:配合使用
语法:
条件?满足条件执行的代码:不满足条件执行的代码
一般用来取值
//条件?满足条件执行的代码:不满足条件执行的代码
//console.log(3 > 5 ? 3 : 5)
//if(3 < 5){
// alert('真的')
//else {
// alert('假的')
//}
// 3 < 5 ? alert('真的') : alert('假的')
let sum=3 < 5 ? 3 : 5
console.log(sum) // 3
求最大值案例:
//1.用户输入
let num1=+prompt('请您输入第一个数:')
let num2=+prompt('请您输入第二个数:')
//2.判断输出-三元运算符
//if(num1>num2){
// alert(num1)
//else {
// alert(num2)
//}
num1>num2?alert('最大值是:${num1}'):alert('最大值是:${num2}')
数字补0案例:
//let age=18
//age=age+1
//age++
//1.用户输入
let num=prompt('请您输入一个数字:')
//2.判断输出-小于10才补0
num=num<10?0+num:num
alert(num)
switch语句
switch(数据) {
case 值1:
代码1
break
case 值2:
代码2
break
default:
代码n
break
}
释义:
找到跟小括号里数据全等的case值,并执行里面对应的代码;若没有全都===的则执行default里的代码;
switch case语句一般用于等值判断,不适合于区间判断;
switch case一般需要配合break关键字使用 ,没有break会造成case穿透。
简单计算器案例:
//1.用户输入
let num1=+prompt('请您输入第一个数字:')
let num2=+prompt('请您输入第二个数字:')
let sp=prompt('请您输入+-*/其中一个:')
//2.判断输出
switch(sp) {
case '+':
alert('两个数的加法操作是${num1+num2}')
break
case '-':
alert('两个数的减法操作是${num1-num2}')
break
case '*':
alert('两个数的乘法操作是${num1*num2}')
break
case '/':
alert('两个数的除法操作是${num1/num2}')
break
default:
alert('请输入+-*/')
break
}
循环语句
断点调试
作用:学习时可以帮助更好的理解代码运行,工作时可以更快找到bug
浏览器打开调试界面:
- 按F12打开开发者工具
- 点到sources一栏
- 选择代码文件
for循环
for(变量起始值;终止条件;变量变化值){
循环体
}
99乘法表案例:
//1.外层循环控制行数
for(let i=1;i<=9;i++){
//2.里层循环控制列数
for(let j=1;j<=i;j++){
document.write('<span>${j}X${i}=${i*j}</span>')
}
//换行
document.write('<br>')
}
while循环
while(循环条件){
循环体
}
let i=1 //变量起始值
while(i<=3) { //终止条件
document.write('我会循环三次<br>')
i++ //变量变化量
}
案例:
while(true) {
let str=prompt('你爱我吗')
if(str==='爱') {
break
}
}
综合案例
ATM取款机:
// 1. 开始循环 输入框写到 循坏里面
// 3.准备一个总的金额
let money = 100
while (true) {
let re = +prompt('
请您选择操作:
1.存钱
2.取钱
3.查看余额
4.退出
')
// 2、 如果用户输入的 4 则退出循环, break
if (re === 4) {
break
}
// 4.根据输入做操作
switch (re) {
case 1:
// 存钱
let cun = +prompt('请输入存款金额')
money = money + cun
break
case 2:
//取钱
let qu = +prompt('请输入取款金额')
money = money - qu
break
case 3:
//查询金额
alert('您的银行卡余额是${money}')
break
}
}
数组
数组是什么
数组是一种将数据存储在单个变量名下的方式
数组的基本使用
声明语法
let 数组名=[数据1,数据2,... ,数据n]
let arr=new Array(数据1,数据2,... ,数据n)
例
names=['小明','小刚','小红','小力']
- 数组是按顺序保存,每个数据都有自己的编号
- 编号从0开始
- 在数组中,数据的编号也叫索引或下标
- 数组可以存储任意类型的数据
取值语法
数组名[下标]
例
let names=['小明','小刚','小红','小力']
names[0] //小明
names[1] //小刚
一些术语
- 元素:数组中保存的每个数据都叫数组元素
- 下标:数组中数据的编号
- 长度:数组中数据的个数,通过数组的length属性获得
let names=['小明','小刚','小红','小力']
console.log(names[0]) //小明
console.log(names[1]) //小刚
console.log(names.length) //5
遍历数组
用循环把数组中每个元素都访问到,一般用for循环遍历
语法:
for(let i=0;i<数组名.length;i++) {
数组名[i]
}
例
let nums=[1,2,3,4,5]
for(let i=0;i<nums.length;i++) {
document.write(nums[i])
}
数组求和及平均值案例:
let arr=[2,6,1,7,4]
//1.求和的变量
let sum=0
//2.遍历求和
for(let i=0;i<arr.length;i++) {
sum+=arr[i]
}
console.log(`数组的和的结果是:${sum}`)
console.log(`数组的平均值结果是:${sum/arr.length}`)
数组最大值案例:
let arr=[2,6,1,7,400,55,88,100]
let max=arr[0]
let min=arr[0]
// 遍历数组
for(let i=1;i<arr.length;i++) {
//if(max<arr[i])max=arr[i]
max<arr[i]?max=arr[i]:max
//if(min>arr[i])min=arr[i]
min>arr[i]?min=arr[i]:min
}
console.log(`最大值是:${max}`)
console.log(`最小值是:${min}`)
操作数组
数组本质是数据集合,操作无非是增删改查语法
改
let arr=['pink','red','green']
for(let i=0;i<arr.length;i++) {
arr[i]=arr[i]+'老师'
}
console.log(arr) //['pink老师','red老师','green老师']
增
数组.unshift(新增的内容)方法将一个或多个元素添加到数组的开头,并返回该数组的新长度
语法:
arr.unshift(元素1,... ,元素n)
例
let arr=['red','green']
arr.unshift('pink')
console.log(arr) //['pink','red','green']
let arr=['red','green']
arr.unshift('pink','hotpink')
console.log(arr) //['pink','hotpink','red','green']
数组.push(新增的内容)方法将一个或多个元素添加到数组的最后,并返回该数组的新长度
语法:
arr.push(元素1,... ,元素n)
例
let arr=['red','green']
console.log(arr.push('pink')) //3
console.log(arr) //['red','green','pink']
删
- 数组.pop()方法从数组中删除最后一个元素,并返回该元素的值
语法:
arr.pop()
例
let arr=['red','green']
arr.pop()
console.log(arr) //['red']
- 数组.shift()方法从数组中删除第一个元素,并返回该元素的值
语法:
arr.shift()
例
let arr=['red','green']
arr.shift()
console.log(arr) //['green']
- 数组.splice()方法删除指定元素
语法:
arr.splice(start,deleteCount)
//起始位置,从0计数
//删除几个元素,省略则默认从指定的起始位置删到最后
例
let arr=['red','green','pink']
arr.splice(1,1)
arr.splice(1) //['red']
console.log(arr) //['red','pink']
数组排序
冒泡排序:
let arr=[5,4,3,2,1]
for(let i=0;i<arr.length-1;i++){
for(let j=0;j<arr.length-i-1;j++){
if(arr[j]>arr[j+1]){
let temp=arr[j]
arr[j]=arr[j+1]
arr[j+1]=temp
}
}
}
console.log(arr) //[1,2,3,4,5]
数组.sort()方法可以排序
语法:
let arr=[4,2,5,1,3]
//1.升序排列写法
arr.sort(function(a,b){
return a-b
})
console.log(arr) //[1,2,3,4,5]
//2.降序排列写法
arr.sort(function(a,b){
return b-a
})
console.log(arr) //[5,4,3,2,1]
数组案例
数组筛选案例:
let arr=[2,0,6,1,77,9,54,3,78,7]
//1.声明新的空的数组
let newArr=[]
//2.遍历旧数组
for(let i=0;i<arr.length;i++) {
if(arr[i]>=10){
newArr.push(arr[i])
}
console.log(newArr) //[77,54,78]
根据数据生成柱形图案例:
//声明新的数组
let arr=[]
for(let i=0;i<4;i++) {
//let num=prompt(`请输入第${i}季度的数据:`)
//arr.push(num)
arr.push(prompt(`请输入第${i}季度的数据:`))
}
document.write(`<div class="box">`)
for(let i=0;i<arr.length;i++){
document.write(`
<div style="height:${arr[i]}px;">
<span>${arr[i]}</span>
<h4>第${i+1}季度</h4>
</div>
`)
}
//盒子结尾
document.write(`</div>`)
函数
为什么需要函数
function,是被设计为执行特定任务的代码块
函数使用
函数声明语法
function 函数名() {
函数体
}
例:
function sayHi() {
document.write('hai~~')
}
函数名命名规范:
- 和变量命名基本一致
- 尽量小驼峰式命名法
- 前缀应该为动词
- 常用动词约定
函数调用语法
函数名()
例:
//函数一次声明可以多次调用,每一次函数调用函数体里面的代码会重新执行一次
sayHi()
函数封装案例:
// 1. 求2个数的和
//function getSum() {
//Let numl = +prompt('请输入第一个数')
//Let num2 = +prompt('请输入第二个数')
//console.Log(num1 + num2)
// }
// getSum()
// 2、 求 1~100 累加和
function getSum() {
let sum = 0
for (let i = 1; i <= 100; i++) {
sum+=i
}
console.log(sum)
}
getSum()
函数传参
声明语法
/*参数列表中的数据用逗号隔开*/
function 函数名(参数列表) {
函数体
}
例:
单个参数
function getSquare(num1) {
document.write(num1*num1)
}
多个参数
function getSum(num1,num2) {
document.write(num1+num2)
}
例
function getSum(start,end) {
//形参
let sum=0
for(let i=start;i<=end;i++) {
sum+=i
}
console.log(sum)
}
getSum(1,50)//实参 1275
getSum(100,200) //15150
调用语法
函数名(传递的参数列表)
例:
getSquare(8)
getSum(10,20)
参数默认值
形参可以看做变量,但是如果一个变量不给值,默认是undefined
如果用户不输入实参,则出现undefined+undefined结果是NaN
改进:
function getSum(x=0,y=0) {
document.write(x+y)
}
getSum()//结果是0
getSum(1,2)//结果是3
函数封装数组求和案例:
function getArrSum(arr=[]) {
let sum = 0
for (let i = 1; i <arr.length; i++) {
sum+=arr[i]
}
console.log(sum)
}
getArrSum([1,2,3,4,5])//15
getArrSum([11,22,33])//66
getArrSum()//0
实参可以是变量
function getSum(n=0,m=0) {
let sum = 0
for (let i = n; i <=m; i++) {
sum+=i
}
console.log(sum)
}
let num1=+prompt('请输入起始值')
let num2=+prompt('请输入结束值')
getSum(num1,num2)
函数返回值
其实我们前面已经接触了函数具备返回值:
let result=prompt('请输入你的年龄')
let result2=parseInt('111')
这些函数是js底层内置的,直接就可以使用
有些函数没有返回值
alert('我是弹框,不需要返回值')
所以根据需求来设定需不需要返回值
当函数需要返回数据出去时,用return关键字
语法:
return 数据
//return 20
使用:
function getSum(x,y){
return x+y
}
let num=getSum(10,30)
document.write(num)
细节:
- 在函数中使用return关键字能将内部的执行结果交给函数外部使用
- return后面代码不会在被执行,会立即结束当前函数,所以return后面的数据不要换行写
- return函数可以没有return,这种情况函数默认返回值为undefined
- 两个相同的函数后面的会覆盖前面的函数
- 在js中实参的个数和形参的个数可以不一致;
如果形参过多会自动填上undefined(了解)
如果实参过多那么多余的实参会被忽略 - 函数一旦碰到return就不会再往下执行了,函数的结束用return
作用域
通常来说,一段程序代码中所用到的名字并不总是有效和可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域
全局作用域:(全局有效)作用于所有代码执行的环境(整个script标签内部)或者一个独立的js文件
局部作用域:(局部有效)作用于函数内的代码环境,就是局部作用域,因为跟函数有关系,所有也称为函数作用域
如果函数内部变量没有声明直接赋值,也当全局变量看,但是强烈不推荐
有一种情况,函数内部的形参可以看做是局部变量
let num=20
function fn() {
num=10 // 全局变量来看 强烈不允许
}
fn()
console.log(num) //10
function fun(x,y) {
//形参可以看做是函数的局部变量
console.log(x)
}
fun(1,2) //1
console.log(x) //错误的
只要是代码就至少有一个作用域
如果函数中还有函数,那么在这个作用域中就又可以诞生一个作用域
访问原则:在能够访问到的情况下先局部再全局
匿名函数
函数可以分为具名函数和匿名函数
函数表达式:
将匿名函数赋值给一个变量,并且通过变量名称进行调用,我们称这个为函数表达式
语法:
let fn=function() {
//函数体
}
调用:
fn() //函数名()
函数表达式和具名函数的不同:
- 具名函数的调用可以写到任何地方
- 函数表达式必须先声明函数表达式后调用
立即执行函数
场景介绍:避免全局变量之间的污染
语法:
//不需要调用直接执行
//方式1
(function(){ console.log(11) })();
//方式2
(function(){ console.log(11) }());
注意:多个立即执行函数要用;隔开,要不然会报错
(function(){
let num=10
})();//10
(function(){
let num=20
})();//20
(function(x,y){
console.log(x+y)
})(1,2);//3
(function(x,y){
console.log(x+y)
}(1,3));//4
综合案例
//1.用户输入
let second=+prompt('请输入秒数:')
//2.封装函数
function getTime(t){
//console.log(t)//总的秒数
//3.转换
//小时:h=parseInt(总秒数/60/60%24)
//分钟:m=parseInt(总秒数/60%60)
//秒数:s=parseInt(总秒数%60)
h=parseInt(t/60/60%24)
m=parseInt(t/60%60)
s=parseInt(t%60)
h=h<10?'0'+h:h
m=m<10?'0'+m:m
s=s<10?'0'+s:s
//console.log(h,m,s)
return `转换完毕后是${h}小时${m}分${s}秒`
}
let str=getTime(second)
document.write(str)
console.log(h)
对象
什么是对象
对象:js里的一种数据类型
可以理解为是一种无序的数据集合(数组是有序的数据集合)
用来描述某个事物:
- 静态特征:可以用数字、字符串、数组、布尔类型等表示
- 动态行为:使用函数表示
对象使用
对象声明语法:
let 对象名={}
let 对象名=new Object()
例
//声明了一个person的对象
let person={}//{}是对象字面量
对象由属性和方法组成
属性:信息或叫特征(名词)
方法:功能或叫行为(动词)
let 对象名={
属性名:属性值,
方法名:函数
}
属性
数据描述性的信息称为属性,如人的姓名,一般是名词性的
let person={
uname:'pink',
age:'18',
gender:'女'
}
- 属性都是成对出现的,包括属性名和值,它们之间使用英文:分隔
- 多个英文之间使用,分隔
- 属性就是依附在对象上的变量
- 属性名可以使用""或’',一般情况下省略,除非名称遇到特殊符号如空格、中横线等
操作数据就是增删改查语法:
查
属性访问:声明对象,并添加了若干属性后,可以使用.获得对象中属性对应的值
语法:对象名.属性/ 对象名[‘属性名’]
简单理解就是获得对象里面的属性值
let person={
uname:'pink',
age:'18',
gender:'女'
}
console.log(person.uname)
console.log(person['age'])
console.log(person.gender)
改
语法:对象名.属性=新值
let person={
uname:'pink',
age:'18',
gender:'女'
}
person.gender='男'
console.log(person.gender)
console.log(person)
增
语法:对象名.新属性=新值
let person={
uname:'pink',
age:'18',
gender:'女'
}
person.address='cs'
console.log(person) //{uname:'pink', age:'18', gender:'女', address:'cs'}
删(了解)
语法:delete 对象名.属性
let person={
uname:'pink',
age:'18',
gender:'女'
}
delete person.gender
console.log(person) //{uname:'pink', age:'18'}
方法
数据行为性的信息称为方法,如跑步,一般是动词性的,其本质是函数
let person={
uname:'pink',
sayHi:function(){
document.write('hi')
}
}
- 方法是由方法名和函数两部分构成,它们之间用:分隔
- 多个属性之间使用英文,分隔
- 方法是依附在对象中的函数
- 方法可以使用""或’',一般情况下省略,除非名称遇到特殊符号如空格、中横线等
方法调用:声明对象,并添加了若干方法后,可以使用.调用对象中函数
可以添加形参和实参
let person={
uname:'pink',
sayHi:function(){
document.write('hi')
}
}
//对象名.方法名()
person.sayHi()
遍历对象
let obj={
uname:'pink',
age:'18',
gender:'女'
}
for(let k in obj){
console.log(k)// 打印属性名
console.log(obj[k])// 打印属性值
//k==='uname'
一般不用这种方法遍历数组,主要用来遍历对象
for in语法中的k是一个变量,在循环的过程中依次代表对象的属性名
由于k是变量,所有必须使用[]语法解析
一定记住:k是获得对象的属性名,对象名[k]是获得属性值
<body>
<table>
<caption>学生列表</caption>
<tr>
<th>序号</th>
<th>姓名</th>
<th>年龄</th>
<th>性别</th>
<th>家乡</th>
</tr>
<script>
//1.数据准备
let students=[
{name:'小明',age:'11',gender:'男',hometown:'河北省'},
{name:'小红',age:'12',gender:'女',hometown:'河南省'},
{name:'小刚',age:'13',gender:'男',hometown:'山西省'},
{name:'小丽',age:'14',gender:'女',hometown:'山东省'},
{name:'小强',age:'15',gender:'男',hometown:'四川省'},
]
//2.渲染页面
for(let i=0;i<students.length;i++){
document.write(`
<tr>
<td>${i+1}</td>
<td>${students[i].name}</td>
<td>${students[i].age}</td>
<td>${students[i].gender}</td>
<td>${students[i].hometown}</td>
</tr>
`)
}
</script>
内置对象
内置对象:js内部提供的对象,包含各种属性和方法给开发者调用
内置对象-Math
介绍:Math对象是js提供的一个"数字"对象
作用:提供了一系列做数学运算的方法
Math对象包含的方法有:
- random:生成0-1之间的随机数(包含0不包括1)
- ceil:向上取整
- floor:向下取整
- max:找最大值
- min:找最小值
- pow:幂运算
- abs:绝对值
console.log(Math.PI)
//方法
//ceil
console.log(Math.ceil(1.1))//2
console.log(Math.ceil(1.5))//2
console.log(Math.ceil(1.9))//2
//floor
console.log(Math.floor(1.1))//1
console.log(Math.floor(1.5))//1
console.log(Math.floor(1.9))//1
//round四舍五入
console.log(Math.round(1.1))//1
console.log(Math.round(1.49))//1
console.log(Math.round(1.5))//2
console.log(Math.round(1.9))//2
console.log(Math.round(-1.1))//-1
console.log(Math.round(-1.5))//-1
console.log(Math.round(-1.51))//-2
随机数函数案例:
//左闭右开
//console.log(Math.random())
//0~10之间的整数
//console.log(Math.floor(Math.random()*11))
//let arr=['red','green','blue']
//let random=Math.floor(Math.random()*arr.length)
//console.log(arr[random])
//取到N~M之间的随机整数
function getRandom(N,M){
return Math.floor(Math.random()*(M-N+1))+N
}
console.log(getRandom(4,8))
随机点名案例:
let arr=['赵云','黄忠','关羽','张飞','马超','刘备','曹操']
//1.得到一个随机数,作为数组的索引号0~6
let random=Math.floor(Math.random()*arr.length)
//2.页面输出数组里面的元素
document.write(arr[random])
//3.splice(起始位置(下标),删除几个元素)
arr.splice(random,1)//删除刚抽到的
console.log(arr)
猜数字游戏案例:
//1.随机生成一个数字1~10
//取到N~M之间的随机整数
function getRandom(N,M){
return Math.floor(Math.random()*(M-N+1))+N
}
console.log(grtRandom(1,10))
console.log(random)
//需要不断地循环
while(true){
//2.用户输入一个值
let num=+prompt('请输入你猜的数字:')
//3.判断输出
if(num>random){
alert('您猜大了')
}else if(num<random){
alert('您猜小了')
}else{
alert('猜对了,真厉害')
break //退出循环
}
}
//写到for的外面来
if(flag){
alert('次数已经用完')
}
随机颜色案例:
//1.自定义一个随机颜色函数
function getRandomColor(flag = true) {
if(flag) {
// 3. 如果是true 则返回 #ffffff
let str ='#'
let arr =['0', '1', '2', '3', '4', '5', '6', '7','8', '9', 'a', 'b', 'c', 'd', 'e', 'f']
// 利用for循环随机抽6次 累加到 str里面
for (let i = 1; i <= 6; i++){
// 每次要随机从数组里面抽取一个
// random 是数组的索引号 是随机的
let random = Math.floor(Math.random() * arr.length)
// str = str + arr[random]
str += arr[random]
}
return str
} else {
// 4. 否则是 false 则返回 rgb(255,255,255)
let r = Math.floor(Math.random() * 256) // 55
let g = Math.floor(Math.random()* 256) // 89
let b = Math.floor(Math.random() * 256) // 255
return `rgb(${r},${g},${b})`
}
// 2. 调用函数 getRandomCoLor(布尔值)
console.log(getRandomColor(false))
console.log(getRandomColor(true))
console.log(getRandomColor())
// Let str ='#'
//str = str +'f'
拓展
术语解释
基本数据类型和引用数据类型
简单类型又叫做基本数据类型或者值类型,复杂类型又叫做引用类型
- 值类型:简单数据类型/基本数据类型,在存储中变量存储的是值本身,因此叫做值类型string,number,boolean,undifined,null
- 引用类型:复杂数据类型,在存储时变量中存储的不仅仅是地址(引用),因此叫做引用数据类型,通过new关键字创建的对象(系统对象、自定义对象),如Object、Array、Date等
堆栈空间分配区别:
- 栈(操作系统):由操作系统自动分配释放存放函数的参数值、局部变量的值等。其操作方式类似于数据结构中的栈;简单数据类型存放到栈里面
- 堆(操作系统):存储复杂类型(对象),一般由程序员分配释放,若程序员不释放,由垃圾回收机制回收。引用数据类型存放到堆里面
引用类型变量(栈空间)里存放的是地址,真正的对象实例存放在堆空间中