《部分案例代码下载》
学习目标(全天模式)
- 能够说出函数的形参和实参的区别
- 能够使用函数封装一段代码重复使用
- 能够说出函数中return的作用
- 能够封装一个函数返回两个数的最大值
- 能够说出全局作用域和局部作用域的区别
- 能够说出预解析的过程
- 能够书写定义函数的两种不同方式
- 能够自定义创建对象
。。。。。。
理解上课的知识点……
函数的参数
上面写的计算两个数的和存在问题,如果第一次求10+20的和,第二次求100+200的和,此时怎么办?
需求:计算两个数的和,封装成一个函数
可以把需要求和的两个数作为参数传到函数里面,函数体中计算参数的和即可。
- 形参(形式参数)
- 在函数声明时,设置的参数
- 作用:占位置。
- 实参(实际参数)
- 在函数调用时,传入的参数。
- 作用:函数调用时,会把实参的值赋值给形参,这样形参就有了值。
例子:
1 | var getSum(a,b) { |
形参:
- 在函数声明时,()中的参数
- 形式参数:默认没有具体的值或者类型,只有当调用时,形参才有具体的值或者类型
- 作用:占位置
实参:
- 在函数调用时,给函数传递的参数
- 实际参数:默认有具体的值或者类型
- 作用:函数调用时,会将实参的值,传递给形参
函数声明与调用的进阶写法:
1 | // 函数声明 |
ヾ(๑╹◡╹)ノ” 函数参数的练习
发生变化的值,都能提取成函数的参数(形参)
1 | // 1. 计算1-n之间所有数的和 |
初学者关键在于熟悉语法,对于复杂的情况之后的课程会不断拓展。
函数的返回值
当函数执行完的时候,我们希望函数可以返回执行的结果(返回值)。也就是返回值。
此时可以通过在函数中设置一个return返回一个返回值
买一瓶爽歪歪~
返回值语法:
1 | // 函数的声明 |
注意点: 函数的返回值可以通过一个变量接收,然后对返回值进行之后的操作
ヾ(๑╹◡╹)ノ” 函数返回值的练习
1 | // 1. 计算1-n之间所有数的和,并且返回结果 |
————————
函数三要素
- 函数名:函数可以一次声明,通过函数名()多次调用:比较重要
- 函数的参数:可以没有,但是如果函数体内有需要变化的值,此时就需要把变化的量提取出形参
- 函数的返回值: 可以没有,但是如果需要拿到函数的执行结果,就需要return返回值!!!
开发中:参数和返回值看实际需求决定!
ヾ(๑╹◡╹)ノ” 函数三要素的练习1
1 | // 1. 求任意半径的圆的面积 |
ヾ(๑╹◡╹)ノ” 函数三要素的练习2
1 | // 1. 求任意数组中的最大值 |
函数参数与返回值的说明
需求:封装成函数,求两个任意数的和并且返回结果
要求形参与实参需要一一对应!!但是如果在调用是,传实参写少了,或者写多了,是什么情况呢??
函数参数的注意点:
规范形参与实参的个数需要一一对应!
- 如果参数传少了,没有接收到的值就是undefined(避免这种情况,代码有问题)
- 如果参数传多了,前面的会一一对应,对于多出的会被忽略(不会影响结果)
函数返回值的注意点:
一个函数的返回值,指的是函数调用的结果
- return表示函数返回结果,函数已经结束,return之后的代码就不执行了!!
函数的高级知识
函数内部可以调用函数
在函数内部是可以继续调用别的函数的。
1 | function study() { |
函数的调试
如果需要看上面函数的执行过程,可以通过调试工具调试一下
从左往右看:
第一个:瞬间执行到下一个断点处
第二个:让代码往下执行一步(如果遇到函数的调用,瞬间执行完得出结果,不显示过程)
第三个:让代码往下执行一步(如果遇到函数的调用,会进入函数体中显示过程)
想进入函数看里面的代码使用
第四个:瞬间执行完当前函数(不显示过程)
不想看函数里面的代码了,可以使用跳出
————————
作用域
变量起作用的区域
局部作用域:
- 在函数内部,就是局部作用域
- 在函数内部声明的变量,就叫做局部变量
注意点: 局部变量,只能在当前函数内部,使用!!
1
2
3
4
5
6function fn () {
var num = 22;// num是fn函数内部的变量,是局部变量,只能在fn中使用
console.log(num);
}
fn();
console.log(num);// 报错全局作用域:
- 在script标签内,函数外,就是全局作用域
- 在全局作用域中,声明的变量,就叫做全局变量
注意点: 全局变量,在任何地方,都可以使用!!
1
2
3
4
5
6var num = 11;
function fn () {
console.log(num);// 可以访问全局变量num
}
fn();
console.log(num);// 可以访问全局变量num
全局变量与局部变量的访问规则
下列打印的结果是什么:
先明确是什么变量,再判断值
模拟浏览器的执行
(◕ᴗ◕✿)画图演示
1 | var num = 11; |
- 如果自己作用域中有声明这个变量,就用自己的!
(◕ᴗ◕✿)画图演示
1 | var num = 11; |
- 如果自己作用域中没有声明这个变量,就用外面的(全局作用域)
归纳:自己有就用自己的,自己没有就用外面的!
ヾ(๑╹◡╹)ノ” 作用域访问规则练习 (◕ᴗ◕✿)画图演示
1 | var num = 22; |
隐式全局变量
开发中避免出现(一般只会在面试题中提问)
问题:
1 | num = 10; |
- 一个变量如果从头到尾没有使用var声明,直接赋值,浏览器会默认变成全局变量——》隐式全局变量
(◕ᴗ◕✿)画图演示
1 | function fn (){ |
ヾ(๑╹◡╹)ノ” 隐式全局变量的小练习
1 | var num = 20; |
隐式全局变量开发中避免!!!
————————
预解析
预解析:预先解析代码
在代码开始执行之前,都会把变量和函数的声明进行提升!!——》预解析
可以看做浏览器预先想要知道,有哪些变量和函数~
js代码的执行步骤(两步)
预解析(把变量和函数的声明提升到最前面)
预先解析代码,把所有变量和函数的声明都会提升(浏览器想要预先知道有哪些变量和函数)
再一行一行执行代码
问题:
1 | console.log(num);// 讲道理此时还没有声明变量,应该会报错 |
注意点:
- 所有的变量的声明,都会提升到最顶部,但是不会提升赋值!!!
(◕ᴗ◕✿)画图演示
1 | // 第一步不是执行代码,而是预解析 |
所有的函数的声明,都会提升到最顶部,但是不会提升函数的调用
1
2
3
4
5
6// 第一步不是执行代码,而是预解析
console.log("我是第一行代码");
fn();
function fn() {
console.log('嘻嘻');
}
以下都是错误的写法
如果同时声明了多个同名的变量,只会提升第一个声明,后面的声明会忽略
1
2
3
4var num = 11;
var num = 22;
var num = 33;
var num = 44如果同时声明了多个同名的函数,后面的函数声明会覆盖前面的!!(最后只剩一个函数声明)
开发时避免同名!!
1
2
3
4
5
6
7
8
9
10
11
12
13fn();
function fn() {
console.log('呵呵');
}
fn();
function fn() {
console.log('哈哈');
}
fn();
function fn() {
console.log('嘻嘻');
}
fn();如果同时声明了同名的变量和函数,函数声明优先!!
开发中必须避免!!
1
2
3
4
5
6console.log(a);
function a() {
console.log('我是函数');
}
var a;
console.log(a)
(◕ᴗ◕✿)画图演示
一定要避免这种情况,否则会有bug
1 | var a = 11; |
ヾ(๑╹◡╹)ノ” 小练习
1 | //1、getCool() 比比谁最帅!! |
代码规范:
- 一般先声明,后使用
- 不要让函数名与变量名同名!!
ヾ(๑╹◡╹)ノ” 面试题
一般预解析的题目只在面试中会遇到,实际开发中避免
注意点:每个作用域中都有预解析(局部作用域中也有!)
(◕ᴗ◕✿)画图演示
1 | //1、 每个作用域中都有预解析——》函数内部也会预解析 |
1 | //2. |
————————
(◕ᴗ◕✿)画图演示
1 | //3. |
定义函数的两种方式
两种方法各有千秋,都有使用的场景
函数声明
1 | function 函数名(){ |
函数表达式
1 | var 函数名 = function(){ |
区别:
- 函数声明可以先调用,再声明(因为预解析)
- 函数表达式必须先声明赋值,再调用(相当于变量赋值,只会提升变量声明,不会提升赋值)
匿名函数
匿名函数:没有名字的函数——》不能直接使用,有两个使用场景
场景一:函数表达式
1 | var fn = function (){ |
场景二:匿名函数自调用——》自执行——》自己调用自己
函数可以自调用(声明后立马使用),但是直接调用会报错,此时需要用()把整个函数体包裹起来才行
1 | (function fn(){ |
- 注意点:一般规范匿名函数自调用之后需要加上分号
匿名函数自调用的应用(沙箱模式)
在多人同时写代码时,如果都使用的是全局变量,很容易与其他人的全局变量互相影响,这叫做全局变量污染
一般使用沙箱模式(匿名函数自调用):每个人的代码在单独的作用域中,不会互相影响
例子:
1 | // 小张写的代码,单独运行没毛病 |
解决方法:
只需要让每个人的代码中的变量变成局部变量即可
js中只有函数里面才有局部作用域,只需要那函数包裹起来调用即可
简写就是函数的自调用,但是有名字的函数还是会全局变量污染,所以使用匿名函数自调用
————————
对象
为什么学习对象?
为什么要学习数组:数组可以存储大量的数据,并且数组规范一般储存的是同类型的数据!!
对象:万物皆对象,在现实生活中,只要能被描述出来的就是对象
思考:如果需要在js中描述出一个人这个对象,怎么做?
描述人这个对象:
- 特征:姓名、年龄、性别、身高、体重……
- 行为:吃饭、睡觉、敲代码……
解决方案:
单独使用变量一个个存——》代码麻烦,需要多个变量
1
2
3
4
5
6
7
8
9
10
11
12
13
14// -------------------特征
var name = "张三";
var age = 18;
var sex = "男";
var height = 180;
var weight = 150;
// -------------------行为
var eat = function () {
console.log('吃饭');
}
var sleep = function () {
console.log('睡觉');
}
//-------------------变量太多麻烦使用数组存——》数组规范一般储存同类型的数据,并且数组中的数据用户不明白分别表示什么意思
1
2var arr = ['张三',18,'男',180,150];
//-----------------------数组一般只存储同类型的数据,并且这样写每一项不明确表示什么含义如果需要描述现实中的对象,此时就需要通过js中的对象完成!
对象的基本概念
数组: 一组有序的值的集合——》下标有序
对象: 一组无序的键值对的集合——》可以用于描述生活中对象的特征与行为
键值对就是类似于之前css中的样式
格式:键:值——》key:value
创建对象的方法
字面量(用的最多)
123、’abc’、true、undefined、null、[]、{}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19var obj = {};// 创建一个空对象
console.log(obj);
//----------------------------
var obj = {
// ------------特征——》对象的属性
name:"张三",
age:18,
sex:"男",
height:180,
weight:150,
// ------------行为——》对象的方法(对象中的函数)
eat:function (){
console.log('吃饭');
},
sleep:function (){
console.log('睡觉');
}
};
console.log(obj);注意点:
- 键值对之间以逗号隔开!!!
- 对象中的特征叫做对象的属性
- 对象中的行为(函数)叫做对象的方法
构造函数(用的较少)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15var person = new Object();//创建一个空的对象
//------------------------------
var person = new Object({
name:"张三",
age:18,
sex:"男",
height:180,
weight:150,
eat:function (){
console.log('吃饭');
},
sleep:function (){
console.log('睡觉');
}
})