文章目录
- 递归函数:在函数内部调用自身,一般解决数学问题。菲波那切数列: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); 对于js。只有函数能够关住变量的作用域。
- 局部变量:在一个作用域(定义域)内定义的变量就是这个作用域内的局部变量。只能在作用域内被访问到。全局变量:从广义上来看,全局变量也是一种局部变量。全局变量定义在全局,所以也叫全局变量。可以在任何地方都被访问到。变量申明的原理:全局变量,在全局定义之后,会永久存在,任何时候,任何位置访问,都能够找到它。局部变量定义在函数内部的,函数定义的过程,并没有真正的去定义这个局部变量,只有在执行函数的时候,才会立即定义这个局部变量,执行完之后,变量就被立即销毁了,在其他的地方访问变量的时候,找不到这个变量,所以会有一个引用错误,变量未定义。 // 在全局范围内定义的变量var a = 10;// 函数function fun() { // 函数内部可以使用全局a console.log(a); // b在函数内部声明,只能在函数内部使用,b局部变量 var b = 20; console.log(++ b);}// 在函数内部声明b,在函数外部不能使用// console.log(b);fun();
- 1传递作用。在不同函数间使用全局变量可以作用信号量,这些函数都可以改变信号量,使用新值参与计算。 // a 是全局变量,任何地方都可以使用// a称为信号量,不管任何函数改变a的值,都可以记住并且再次使用都是使用a改变之后的新值参与计算var a = 10;// 函数使用afunction fun() { a ++; console.log(a);}// 函数也可以使用afunction 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引擎会从其所在的作用域依次向外层查找,查找会在找到第一个匹配的标识符的时候停止。在多层嵌套的作用域中可以定义同名的标识符,发生“遮蔽效应”。 // 全局avar 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); 如果变量声明时,不写var关键字,计算机会自动在全局作用域内给它进行一个声明,局部变量就强制性的变成了全局变量。这种情况是不合理,会造成一个全局变量的污染。所以,定义变量必须写var关键字。 // 全局avar a = 10;// 等价于在全局声明var a = 20;function fun1() { // 函数内部的var 省略,强制转为全局变量 a = 20; console.log(a); function fun2() { console.log(a); } fun2();}fun1();console.log(a);
- 在函数内部声明的函数,只能在函数内部声明,在函数外部任何地方都不能访问。 // 声明函数function outer() { // 函数内部声明一个变量 var a = 10; // 函数内部声明一个函数 function inner() { console.log(a); } // 调用函数 inner();}// 调用函数outer();// inner在函数外部不能使用inner();
- 函数本身就是闭包,函数可以记住自己定义时所处的外部环境,和内部语句,这就是闭包。 function outer() { var a = 10; function inner() { console.log(a); } // console.log(inner); // inner没有小括号。表示定义语句 return inner;}// 调用outer返回的是Inner函数的定义// console.log(outer());// 用i变量接收outer(),相当于把inner函数赋值ivar 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(x,y) { function inner(y) { // 作用域链根据就近原则 // console.log(y); console.log(x + y); } // 调用outer(x,y)返回的是inner函数 return inner;}// i赋值的是inner函数// outer(1,2) x = 1, y =2var i = outer(1,2);// i是inner函数名字,调用i函数,i的实际参数是赋值给inner函数y// i(10)调用,能够记住x = 1,还可以内部语句console.log(1 + y)i(10);i(20); 闭包并不是一成不变的,函数的每一次调用都会产生一个全新的闭包。举例: function fun1() { var a = 10; function fun2() { a ++; console.log(a); } // 调用fun1返回的是fun2的定义 return fun2;}// 每一次fun1调用都产生一个全新的闭包,之间互不影响var inn1 = fun1();var inn2 = fun1();// 闭包的外部环境不是一成不变的,能够记住当前的新值,并且参与计算inn1();inn1();inn1();inn1();// 每一次fun1调用都产生一个全新的闭包,inn1和inn2闭包互不影响// 每一个闭包,外部环境是全新的内部语句也是全新的inn2();inn2();inn1();
递归函数:在函数内部调用自身,一般解决数学问题。
菲波那切数列: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);

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

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);

如果变量声明时,不写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);

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

函数本身就是闭包,函数可以记住自己定义时所处的外部环境,和内部语句,这就是闭包。
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(x,y) {
function inner(y) {
// 作用域链根据就近原则
// console.log(y);
console.log(x + y);
}
// 调用outer(x,y)返回的是inner函数
return inner;
}
// i赋值的是inner函数
// outer(1,2) x = 1, y =2
var i = outer(1,2);
// i是inner函数名字,调用i函数,i的实际参数是赋值给inner函数y
// i(10)调用,能够记住x = 1,还可以内部语句console.log(1 + y)
i(10);
i(20);

闭包并不是一成不变的,函数的每一次调用都会产生一个全新的闭包。
举例:
function fun1() {
var a = 10;
function fun2() {
a ++;
console.log(a);
}
// 调用fun1返回的是fun2的定义
return fun2;
}
// 每一次fun1调用都产生一个全新的闭包,之间互不影响
var inn1 = fun1();
var inn2 = fun1();
// 闭包的外部环境不是一成不变的,能够记住当前的新值,并且参与计算
inn1();
inn1();
inn1();
inn1();
// 每一次fun1调用都产生一个全新的闭包,inn1和inn2闭包互不影响
// 每一个闭包,外部环境是全新的内部语句也是全新的
inn2();
inn2();
inn1();
