适合零基础、小白的学习笔记,js函数的定义与调用、作用域、匿名函数、嵌套与递归、闭包,复习巩固基础知识,温故而知新。
文章目录
一、函数定义与调用
1.初识函数
函数是事件驱动、可重复使用的代码块,用于封装一段完成特定功能的代码。函数的定义是由function、函数名、参数和函数体组成的。其中,参数可有可无,返回值也可有可无。函数语法格式如下:
2.参数设置
函数在定义时根据参数的不同,可分为两种类型,一种是无参函数,一种是有参函数。在定义有参函数时,设置的参数称为形参,函数调用时传递的参数称为实参。所谓形参指的是形式参数,具有特定的意义;实参指的是实际参数,也就是具体的值。
3.函数的返回值
函数代表一个行为,返回值表示这个行为的结果。
(1)return 的含义
// 理解返回值
function getNum(){
return 2; //return 的作用,将函数的结果返回给当前函数名
}
var result = getNum(); // 如果希望返回值保存,就放在变量中;
console.log(result); //2
(2)return 使用方法
• return只能返回一个数据
• 如果函数中没有 return,则返回 undefined
//return 可以用来结束一个函数
function Fun() {
console.log("helloweb");
return;
console.log("我还会执行吗?");
}
Fun();//helloweb
-----------------------------------------------------------------------
function fn() {
for (var i = 0; i < 10; i++) {
if (i == 3) { // 循环 3 次就 return
break;
}
console.log("谁最帅!"); // 打印 3 次
}
return "看 return会不会执行我"; //return 不执行, break 执行
}
fn();
4.函数的调用
当函数定义完成后,要想在程序中发挥函数的作用,必须得调用这个函数。函数调用的语法格式如下。
函数名称( [参数1,参数2,…] ) 参数可有可无。(变量必须“先声明,后使用”;函数可以“先使用,后声明”)
二、变量的作用域
变量需要在它的作用范围内才可以被使用,这个作用范围称为变量的作用域。Javascript根据作用域使用范围的不同,可以将其划分为全局作用域、函数作用域和块级作用域(ES6提供的)。
1.全局变量
不在任何函数内声明的变量(显示定义)或在函数内省略var声明的变量(隐式定义)都称为全局变量。
var a = 3; // 全局
function info() {
alert(a); //3
var b = 5;
alert(b); //5
}
info();
console.log(b); // 报错,访问不到 输出结果:Uncaught ReferenceError: b is not defined
-----------------------------------------------------------------------
var a = 'one'; //全局变量
function test() {
var a = 'two'; //局部变量
console.log(a);//当局部变量与全局变量重命名时,局部变量的优先级高于全局变量
}
test(); //two
console.log(a); //one
-----------------------------------------------------------------------
//不使用var声明的变量也是全局变量(不建议这样用)
function info() {
age = 18;//全局
}
info();
alert(age);//18
2.局部变量
在函数体内利用var关键字定义的变量称为局部变量,它仅在该函数体内有效。
function info() {
var age = 18;//局部变量
alert(age);
}
info();//18
alert(age);//访问不到 Uncaught ReferenceError: age is not defined
3.块级变量
ES6提供的let关键字声明的变量称为块级变量,仅在“{ }”中间有效,如if、for或while语句等。
for(let a = 0; a < 3; ++a){
console.log(a);//0 1 2
}
多学一招:垃圾回收机制
在JavaScript中,局部变量只有在函数的执行过程中存在,而在这个过程中会为局部变量在(栈或堆)内存上分配相应的空间,以存储它们的值,然后在函数中使用这些变量,直到函数结束。而一旦函数执行结束,局部变量就没有存在必要了,此时JavaScript就会通过垃圾回收机制自动释放它们所占用的内存空间。
三、匿名函数
1.匿名函数、函数表达式
匿名函数指的是没有函数名称的函数,可以有效地避免全局变量的污染以及函数名的冲突问题。所谓函数表达式指的是将声明的函数赋值给一个变量,通过变量完成函数的调用和参数的传递。采用“变量名( )”的方式调用。
var fn = function sum(num1,num2){//定义函数表达式求和
return num1 + num2;
};
console.log(fn(1,2));//3
var say = function () {
console.log("hello");
};
say();//hello
document.body.onclick = function(){
alert('Hi,everybody!');
}
2.自运行函数
不用调用,自己执行,叫自运行函数。
function fn(){
// 这里是代码
}
fn(); // 运行 fn 函数
----------------------
var fn = function(){
// 这里是代码
}
fn(); // 运行 fn 函数
---------------------
//(fn)() 等价于 fn()
(function(){
// 这里是代码
})();
3.回调函数
所谓回调函数指的是一个函数A作为参数传递给一个函数B,然后在B的函数体内调用函数A。此时,我们称函数A为回调函数。其中,匿名函数常用作函数的参数传递,实现回调函数。
//fn回调函数
function cal(num1,num2,fn) {
return fn(num1,num2);
}
console.log(cal(45,55,function (a,b) {
return a + b;//100
}));
console.log(cal(10,20,function (a,b) {
return a * b;//200
}));
4.箭头函数
ES6引入了一种新的语法编写匿名函数,我们称之为箭头函数。箭头函数表达式的语法更短,使代码更加清晰。
四、嵌套与递归
1.函数嵌套与作用域链
var i = 26;
function fn1() { //声明的第1个函数
var i = 24;
function fn2() { //声明的第2个函数
function fn3() { //声明的第3个函数
console.log(i); //24
}
fn3();
}
fn2();
}
fn1();
2.递归调用
function factorial(n){
if(n == 1){
return 1;
}
return n * factorial(n-1);
}
var n = prompt('求n的阶乘\n n是大于等于1的正整数,如2表示求2!。');
n = parseInt(n);
if(isNaN(n)){
console.log('输入的n值不合法');
}else{
console.log(n + '的阶乘为:' + factorial(n));
}
【案例】求斐波那契数列第N项的值
斐波那契数列又称黄金分割数列,指的是这样一个省略“1,1,2,3,5,8,13,21…”,从中可以找出的规律是“这个数列从第3项开始,每一项等于前两项之和”。
五、闭包函数
1.什么是闭包函数
所谓“闭包”指的就是有权访问另一函数作用域内变量(局部变量)的函数。它最主要的用途(特性)是以下两点。
①可以在函数外部读取函数内部的变量。
②可以让变量的值始终保持在内部中。
2.闭包函数的实现(创建)
创建闭包的常见方式有:
• 在一个函数内部创建另外一个函数,并且把这个函数 return出去。
• 用函数为元素绑定事件,当事件发生时,还可以操作该函数中的变量。
// 方式 1---- 函数内部 return 一个函数
function run() {
var a = 15;
return function () {
a++;
console.log(a);
};
};
var b = run();
// alert(b); //b 是一个函数
b(); // 可以访问另外一个作用域中变量的函数
// 方式 2-- 函数内部为绑定事件
function addClick() {
var txt = "abcd";
document.body.onclick = function () {
alert(txt);
}
};
addClick();
// 方式 3-- 函数内部将变量作为回调函数的参数
function play(num, fn) {
if (num > 10) {
return fn && fn(num);
};
};
var ss = play(20, function (n) {
return n + 1;
});
console.log(ss);//21