JavaScript函数闭包以及作用域

花门楼前见秋草,岂能贫贱相看老。这篇文章主要讲述JavaScript函数闭包以及作用域相关的知识,希望能为你提供帮助。


递归函数
递归函数:在函数内部调用自身,一般解决数学问题。
菲波那切数列:1,1,2,3,,5,8,13,21,34……

function feibo(n)
// 用户输入第n项,返回对应的值
// 从第3项开始值等于n-1对应的值+n-2对应的值
if(n === 1 || n == 2)
return 1;
else
return feibo(n-1) + feibo(n-2);



console.log(feibo(1));
console.log(feibo(2));
console.log(feibo(3));
console.log(feibo(4));
console.log(feibo(5));
console.log(feibo(50));

变量的作用域
函数的内部声明的变量,只能在函数内部使用,在函数外部任何地方都不能访问。
// 在函数内部声明的变量只能在函数内部使用
function fun()
// a在函数内部声明的,只能在fun函数内部使用
var a = 10;
console.log(a);


// a在函数外部不能使用
console.log(a);

JavaScript函数闭包以及作用域

文章图片

对于js。只有函数能够关住变量的作用域。
局部变量和全局变量
【JavaScript函数闭包以及作用域】局部变量:在一个作用域(定义域)内定义的变量就是这个作用域内的局部变量。只能在作用域内被访问到。
全局变量:从广义上来看,全局变量也是一种局部变量。全局变量定义在全局,所以也叫全局变量。可以在任何地方都被访问到。
变量申明的原理:全局变量,在全局定义之后,会永久存在,任何时候,任何位置访问,都能够找到它。局部变量定义在函数内部的,函数定义的过程,并没有真正的去定义这个局部变量,只有在执行函数的时候,才会立即定义这个局部变量,执行完之后,变量就被立即销毁了,在其他的地方访问变量的时候,找不到这个变量,所以会有一个引用错误,变量未定义。

// 在全局范围内定义的变量
var a = 10;
// 函数
function fun()
// 函数内部可以使用全局a
console.log(a);
// b在函数内部声明,只能在函数内部使用,b局部变量
var b = 20;
console.log(++ b);


// 在函数内部声明b,在函数外部不能使用
// console.log(b);
fun();

形式参数是局部变量形参也是局部变量,只能在函数内部使用,在外部任何地方都不能访问。
// 形参是局部变量
function fun(a,b,c)
console.log(a);
console.log(b);
console.log(c);


// 调用
fun(10,20,30,40,50);

JavaScript函数闭包以及作用域

文章图片

全局变量作用
1传递作用。在不同函数间使用全局变量可以作用信号量,这些函数都可以改变信号量,使用新值参与计算。
// a 是全局变量,任何地方都可以使用
// a称为信号量,不管任何函数改变a的值,都可以记住并且再次使用都是使用a改变之后的新值参与计算
var a = 10;
// 函数使用a
function fun()
a ++;
console.log(a);


// 函数也可以使用a
function fun2()
a --;
console.log(a);

2 通信作用,在同一个函数使用全局变量,不会每次都清空,也是使用当前的新值参与计算。
// 使用全局变量
var a = 1;
// 声明函数
function fun()
console.log(++ a);


fun();
fun();
fun();
fun();
fun();
fun();
fun();
fun();
// 输出新值
console.log(a);

作用域链
指的是我们变量查找的一个规律:我们可以在不同的作用域内使用相同的标识符去命名变量。我们在使用一个变量的时候,需要找到匹配的标识符,我们有重复的,用哪一个?如果在当前作用域有这个变量,就直接使用,如果当前作用域没有这个变量定义,会一层一层的从本层往外依次查找,遇到第一个就直接使用。类似于就近原则。
当遇见一个变量时,JS引擎会从其所在的作用域依次向外层查找,查找会在找到第一个匹配的标识符的时候停止。在多层嵌套的作用域中可以定义同名的标识符,发生“遮蔽效应”。

// 全局a
var a = 10;
function fun1()
var a = 20;
// 本层作用域有变量直接使用20
console.log(a);
function fun2()
// 本层作用域没有a的定义,从本层出发,向外进行查找20
console.log(a);
function fun3()
// 本层有a定义直接使用
var a = 30;
console.log(a);

fun3();

fun2();


// 调用
fun1();
console.log(a);

JavaScript函数闭包以及作用域

文章图片

如果变量声明时,不写var关键字,计算机会自动在全局作用域内给它进行一个声明,局部变量就强制性的变成了全局变量。这种情况是不合理,会造成一个全局变量的污染。所以,定义变量必须写var关键字。
// 全局a
var a = 10;
// 等价于在全局声明var a = 20;
function fun1()
// 函数内部的var 省略,强制转为全局变量
a = 20;
console.log(a);
function fun2()
console.log(a);

fun2();

fun1();
console.log(a);

JavaScript函数闭包以及作用域

文章图片

函数的作用域
在函数内部声明的函数,只能在函数内部声明,在函数外部任何地方都不能访问。
// 声明函数
function outer()
// 函数内部声明一个变量
var a = 10;
// 函数内部声明一个函数
function inner()
console.log(a);

// 调用函数
inner();


// 调用函数
outer();
// inner在函数外部不能使用
inner();

JavaScript函数闭包以及作用域

文章图片

闭包
函数本身就是闭包,函数可以记住自己定义时所处的外部环境,和内部语句,这就是闭包。
function outer()
var a = 10;
function inner()
console.log(a);

// console.log(inner);
// inner没有小括号。表示定义语句
return inner;


// 调用outer返回的是Inner函数的定义
// console.log(outer());

// 用i变量接收outer(),相当于把inner函数赋值i
var i = outer();
i();

对于inner函数,外部环境var a = 10; 内部语句console.log(a),不管我们把inner函数拿到哪里它都可以记住自己的所处的外部环境(变量的作用域)和自己的内部语句。
闭包是函数天生存在的性质,不需要任何结构,只不过我们需要借助这种形式体会到闭包。

// 形参是局部变量
function outer(x)
function inner(y)
// 当前作用域没有x的定义,使用outer中x
console.log(x + y);

// 返回inner定义
return inner;


// 将outer调用赋值给i,相当于将inner定义赋值的i
//类似于把inner拿到外部使用,能够记住自己定义时所处的外部环境x=10
//类似于把inner拿到外部使用,能够记住自己定义时内部语句console.log(10+ y)
//i = function inner(y) console.log(10 + y)
var i = outer(10);
// 调用i函数
i(20,30,40);
// 声明一次函数i可以多次调用
i(100);

// 闭包:函数能够记住定义时的外部环境和内部语句
function outer(

    推荐阅读