大家好,我是阿赵。继续学习JavaScript,这次学习的是函数。
一、 什么是函数
function,可以翻译成函数或者方法。
在程序里面,函数是被设计为执行特定任务的代码块。
使用函数,可以实现代码的复用,提高开发效率。
举个例子,假如我们需要对两个数字之间的所有数字求和,如果不用函数,我们可以这样写:
let sum = 0;
for (let i = 1; i <= 100; i++) {
sum += i;
}
console.log(sum);
sum = 0;
for (let i = 2; i <= 200; i++) {
sum += i;
}
console.log(sum);
sum = 0;
for (let i = 3; i <= 300; i++) {
sum += i;
}
console.log(sum);
每次需求的数字不一样,我们就要重新写一套代码。
如果使用了函数,会变成这样:
function getSum(num1, num2) {
var sum = 0;
for (var i = num1; i <= num2; i++) {
sum += i;
}
return sum;
}
console.log(getSum(1, 100));
console.log(getSum(2, 200));
console.log(getSum(3, 300));
可以看出,使用了函数之后,相同的代码可以复用了,这样会提高开发的效率,而且降低维护的成本。
二、 函数的结构
1、 基础函数结构
语法:
function 函数名()
{
函数体
}
这是最简单的函数,举例:
function printSum() {
var sum = 0;
for (var i = 0; i <= 100; i++) {
sum += i;
}
console.log(sum);
}
printSum();
这里的printSum函数,只要调用了,就会在里面遍历,然后相加,最后打印出结果。
2、 带参数的结构
语法:
function 函数名(参数1,参数2……)
{
函数体
}
添加了参数,可以指定函数里面的计算值。
举例:
function printSum(val1, val2) {
var sum = 0;
for (var i = val1; i <= val2; i++) {
sum += i;
}
console.log(sum);
}
printSum(0, 100);
这次的遍历数值不是写死在代码里面,而是在调用函数的时候传进去,会变得更加灵活。
3、 带返回值的结构
语法:
function 函数名(参数1,参数2,……)
{
函数体
return 返回值
}
举例:
function getSum(val1, val2) {
var sum = 0;
for (var i = val1; i <= val2; i++) {
sum += i;
}
return sum;
}
let result = getSum(0, 100);
console.log(result);
这次的函数不再是直接在函数里面打印结果,而是把结果返回,这样在调用函数的时候可以拿到返回值,再通过返回值做其他的事情。
三、 函数的命名规范
函数和变量的命名规范基本一致,可以参考变量的命名规范。
对于函数,命名建议是用动词开头,比如之前举例的printSum或者getSum,一看就能知道,一个是print打印相加结果的,一个是get获取相加结果的。
类似的常用动词有:
can 可以执行
has 含有某值
is 是否某值
get 获取某值
set 设置某值
load 加载数据
等
四、 形参和实参
关于函数的参数,一般有形式参数(形参)和实际参数(实参)这样的概念区分。
所谓的形参,就是在声明函数时候用的,比如
function getSum(val1, val2)
这里声明函数是,告诉使用者需要传进去2个参数,一个是val1,一个是val2,这两个参数是没有具体的值的,只是声明用的,就叫做形式参数,简称形参。
所谓的实参,就是在调用函数的时候传进去的值,比如
getSum(100,200);
这里调用getSum函数时,传进去了2个参数,第一个是100,第二个是200,这时候的100和200,就是实际参数,简称实参
五、 作用域
1、 什么是作用域
作用域(scope)规定了变量能被访问的范围,作用是:
1.提高程序逻辑的局部性
2.增强程序的可靠性
3.减少名字冲突
例子:
let num = 10;
console.log(num);
function fn() {
let num = 20;
console.log(num);
}
fn();
console.log(num);
结果:

可以看出,在一开始,声明了一个变量叫num,然后赋值为10,打印值
然后声明了一个叫fn的函数,在函数内部也声明了一个变量叫num,然后赋值为20,打印值。
在fn函数结束后,再打印了一次num的值,看看是否有变化。
从结果看,写在fn外面的num,值是一直没有变化,一直都是10,而在fn函数里面的num,这个变量只有在fun函数内部起效,不会影响到外面。
这就是变量的作用域了,在某个函数范围内声明的变量,作用域只到函数本身,出了函数就没作用了。而如果有同样名字的变量,它可能存在多个作用域,那么原则是找最近的一个父级生效。比如fn函数里面的num,就只会找到fn函数本身生效,而写在fn外面的num,原则上是在它以下所有的作用域都能生效,比如fn内部也能生效。但由于fn内部已经声明了同名的num变量,所以不能再在fn内部访问外面的num变量了。
2、 作用域分类
1.局部作用域
(1).函数作用域
- 在函数内部声明的变量,只能在函数内部被访问,外部无法直接访问。
- 函数的参数也是函数内部的局部变量。
- 不同函数内部声明的变量无法互相访问。
- 函数执行完毕之后,内部的变量实际被清空了。
(2).块作用域
在JavaScript里面,使用{}包裹的代码成为代码块。
代码块内部声明的变量,外部将“有可能”无法访问
- let声明的变量会产生块作用域,而var声明的变量不会产生块作用域
- const声明的常量也会产生块作用域
- 不同代码块之间变量无法互相访问
2.全局作用域
在<script>标签和js文件的最外层声明就是所谓的全局作用域,在此声明的变量在函数内部也可以被访问。
注意:
(1).为window对象动态添加的属性默认也是全局的,不推荐这么做。
(2).函数中未使用任何关键字声明的变量,也是全局变量,不推荐这么做。
(3).尽可能少的声明全局变量,防止全局变量被污染。
3、 作用域链
作用域链本质上是底层变量查找机制。
当我们需要查找一个变量时,会按照这个顺序查找:
1.在函数被执行时,会优先查找当前函数作用域中的变量
2.如果当前作用域查找不到,会依次逐级查找父级作用域,直到全局作用域。
作用域链的总结:
1.嵌套关系的作用域串联起来形成作用域链。
2.相同作用域链中按从小到大的规则查找变量。
3.子作用域能访问父作用域,父作用域不能访问子作用域。

774

被折叠的 条评论
为什么被折叠?



