js(2)
函数
抽取-封装
css中的抽取封装:
.left{
width:30px;
height:30px;
text-align:center;
line-height:30px;
background-color:pink;
}
.right{
width:30px;
height:30px;
text-align:center;
line-height:30px;
background-color:purple;
}
.btn{
width:30px;
height:30px;
text-align:center;
line-height:30px;
}
.left{
background-color:pink;
}
.right{
background-color:purple;
}
函数的抽取封装:
<script>
//声明
function sheet99(){
//外层循环控制行数
for(let i=1;i<=9;i++){
for(let j=1;j<=i;j++){
//里层循环控制列数
document.write(`<span>${j}x${i}=${i*j}</span>`)
}
//换行
document.write(`<br>`)
}
}
//调用
sheet99()
</script>
函数基础
- function,是被设计为执行特定任务的代码块。
- 函数可以把具有相同或相似逻辑的代码“包裹”起来,通过调用这些被“包裹”的代码逻辑,精简代码方便使用。
函数使用
声明
function 函数名(){
函数体
}
函数名命名规范
- 和变量名基本一致
- 尽量使用小驼峰式命名法
- 前缀应该使用动词
- 命名建议:常用动词约定
动词 | 含义 |
---|---|
can | 判断是否可执行某个动作 |
has | 判断是否含义某个值 |
is | 判断是否为某个值 |
get | 获取某个值 |
set | 设置某个值 |
load | 加载某些数据 |
function getName(){}
function addSquares(){}
调用
//函数调用,这些函数体内的代码逻辑会被执行
函数名()
小括号的本质就是函数的调用。
函数传参
声明
function 函数名(参数,参数){
函数体
}
function get(start,end)
//形参,形式上的参数
{}
getSum(1,50)//实参,实际的参数
形参可以理解为是在这个函数内部声明的变量,实参可以理解为给这个变量赋值。
开发中尽量保持形参和实参个数一致。
参数的默认值
形参:可以看作变量,但如果一个变量不给值,默认值
undefined
若出现undefined+undefined等,程序不严谨。
NaN
用户不输入实参,可以给形参默认值,可以默认为0,程序更加严谨。
function getSum(x=0,y=0){
document.write(x+y)
}
getSum()//结果是0
getSum(1,2)//结果是3
注:这个默认值只会在缺少实参参数传递才会被执行,所以有参数会优先执行传递过来的实参,否则默认为undefined。
函数返回值
return 数据
//例
function getSum(x,y){
return x+y
}
let num=getSum(10,30)
/*getSum()是调用者,得到结果,赋值给num*/
document.write(num)
细节:
- 在函数体中使用return关键字能将内部执行结果交给函数外部使用
- return后面的代码不会再被执行,会立即结束当前函数,所以return后面的数据不要换行写
- return函数可以没有return这种情况下函数默认返回值为undefined
断点进入函数
右键–sourcers
细节
- 函数名相同,后面覆盖前面
fn()//2
function fn(){
console.log(1)
}
function fn(){
console.log(2)
}
fn()//2
- 参数不匹配
1、实参多余形参,剩余的参数不参与运算(被忽略,函数内部有一个arguments,里面装着所有的实参)
function fn(a,b){
console.log(a+b)
}
fn(1,2,3)//3
2、实参少于形参,自动填上undefined
function fn(a,b){
console.log(a+b)
}
fn(1)//1+undefined=NaN
- 函数一旦碰见return就不会再往下执行了,函数结束用return.
- break用于结束循环,return用于结束函数
作用域
通常来说,一段程序代码中用到的名字并不总是有效可用的,而限定这个名字可用性的代码范围就是这个名字的作用域。
全局作用域
全局有效,作用于所有代码执行的环境(整个script标签内部)或者一个独立的js文件。
全局变量
函数外部的let变量,
全局变量在任何区域都可以访问和修改。
<script>
let num=10
console.log(num)//10
function fn(){
console.log(num)
}
fn()//10
</script>
局部作用域
作用于函数内的代码环境,就是局部作用域。因为跟函数有关系,所以也成为函数作用域。
局部变量
函数内部的let变量,
局部变量只能在当前函数内部访问和修改。
//局部变量
function fn(){
let strr='pink'
}
console.log(str)
注:
- 如果函数内部,变量没有声明,直接赋值,也当全局变量看,但是不推荐。
- 函数内部的形参可以看作局部变量
function fn(x,y){
//形参可以看作是函数的局部变量
console.log(x)
}
fn(1,3)
console.log(x)//错误的
变量的访问原则
- 只要是代码,就至少有一个作用域
- 写在函数内部的局部作用域
- 如果函数中还有函数,那么在这个作用域中又可以诞生一个作用域
- 访问原则:在能访问到的情况下,先局部,局部没有再找全局
let num=10
function fn(){
let num=20
function fun(){
let num=30
console.log(num)
}
fun()//30
}
fn()
具名函数
声明:function fn(){}
调用:fn()
具名函数的调用可以在任何位置。
匿名函数
function(){}
没有名字的函数,无法直接使用。
使用场景少,后期webAPI会使用。
使用方法:
函数表达式
将匿名函数赋值给一个变量,并且通过变量名进行调用。
let fn=function(形参){
//函数体
}
let fn=function(){
console.log('函数表达式')
}
fn()
函数表达式和具名函数的不同:
- 具名函数的调用可以写在任何位置。
- 函数表达式,必须先声明函数表达式,后调用。
立即执行函数(必须加分号)
避免全局变量之间的污染。
//方式1
(function(){console.log(11)})();//外面加()表示优先执行。
//方式2
(function(){console.log(11)}());
//不需要调用立即执行
- 两个小括号,function放在第一个括号里,第二个小括号的本质是调用函数,可以加参数。
- 必须加分号,也可加在括号function前面。
逻辑中断
function fn(x,y){
x=x||0
y=y||0
console.log(x+y)
}
短路
只存在于&&和||中,当满足一定条件会让右边代码不执行。
符号 | 短路条件 |
---|---|
&& | 左边为false就短路 |
|| | 左边为true就短路 |
转换为布尔型
Boolean()函数
Boolean('true')
代表空,否定的值会被转换为false,如0,NaN,null,undefined;其余值都会被转换为true。
对象
- JavaScript里的一种数据类型
- 可以理解为是一种无序的数据集合,注意数组是有序的集合
let obj={
uname:'pink',
age:18,
gender:'女'
}
对象的使用
声明
let 对象名={
属性名:属性值,
方法名:函数
}
let 对象名=new Object()
{}是对象字面量。
对象由属性和方法组成
属性:信息或特征(名词)
- 属性一般都是成对出现的,包括属性名,他们之间使用英文:分隔
- 多个属性之间使用英文 , 分隔
- 属性就是衣服在对象上的变量(外面是变量,对象内是属性)不需要声明
- 属性名可以使用’'或"",一般情况下省略,除非名称遇到特殊符号,如空格,中横线等
方法:功能或行为(动词)
对象操作
查 (查询对象)
1、对象.属性
let obj={
uname:'pink',
age:18,
gender:'女'
}
console.log(obj.uname)
2、对象名[‘属性名’](可以用双引号)
对于多词属性或 - 等属性,点操作就不能用了,可以采取如下方式。
let obj={
'goods - name':'小米'
}
console.log(obj['goods - name'])
改(重新赋值)
对象.属性=值
let obj={
uname:'pink',
age:18,
gender:'女'
}
obj.gender='男'
增(添加新的数据)
对象.新属性名=新值
let obj={
uname:'pink',
age:18,
gender:'女'
}
obj.hobby='球'
删(删除对象中属性)
delete 对象名.属性名(了解)
let obj={
uname:'pink',
age:18,
gender:'女'
}
delete obj.age
对象的方法
方法
let obj={
//方法
song:function(形参){
console.log(1)
}
}
//方法调用 对象名.方法名
obj.song(实参)
声明对象,并添加若干方法后,可以使用、调用对象中的函数,为方法调用。
也可以添加形参和实参。
遍历对象
let obj={
uname:'pink',
age:18,
gender:'女'
}
for(let k in obj){
console.log(obj['uname'])//另一种打印方法
console.log(k)//打印属性名
console.log(obj[k])//打印属性值
}
数组遍历也可以用这个方法,但是打印出来的数组下标是字符串。(不推荐数组使用)
内置对象
Math
提供了一系列做数学运算的方法
Math对象包括的方法有:
-
random:生成0-1之间的随机数(不包括0,1)
-
ceil:向上取整
-
floor:向下取整
-
max:找最大数
-
min:找最小数
-
pow:幂运算
-
abs:绝对值
-
PI:Π=3.14…
-
Math在线文档查看mdn.
console.log(Math.ceil(1.1))//2
术语解释
术语 | 解释 | 距离 |
---|---|---|
关键字 | js里有特殊意义的词汇 | let,var,function,if,else,switch,case,break |
保留字 | 目前来讲没有意义,但未来可能会有特殊意义的词汇 | int,short,long,char |
标识(符) | 变量名、函数名的另一种叫法 | 无 |
表达式 | 能产生值的代码,一般配合运算符出现 | 10+3,age>=8 |
语句 | 一段可执行的代码 | If() for() |
基本数据类型和引用数据类型
简单类型又叫做基本数据类型或者值类型,复杂类型又叫做引用类型。
- 值类型:简单数据类型/基本数据类型,在存储时变量中存储的是值本身,因此叫做值类型。 string, number, boolean, undefined, null
- 引用类型:复杂数据类型,在存储时变量中存储的仅仅是地址(引用),因此叫做引用数据类型 。通过new关键字创建的对象(系统对象、自定义对象),如Object、Arnay、Date等
堆栈空间分配区别:
1、栈(操作系统):由操作系统自动分配释放存放函数的参数值、局部变量的值等。其操作方式类似于数据结构中的栈;
简单数据类型存放到栈里面
2、堆(操作系统):存储复杂类型(对象),一般由程序员分配释放,若程序员不释放,由垃圾回收机制回收。
引用数据类型存放到堆里面
简单类型数据分配
- 值类型(简单数据类型):string, number, boolean, undefined, null
- 值类型变量的数据直接存放在变量(栈空间)中
复杂类型的内存分配
- 引用类型(复杂数据类型):通过 new 关键字创建的对象(系统对象、自定义对象),如Object、Array、Date等
- 引用类型变量(栈空间)里存放的是地址,真正的对象实例存放在堆空间中