js-函数(闭包、私有、递归、自调)、变量和作用域
JavaScript 函数
将脚本编写为函数,就可以避免页面载入时执行该脚本。
打印 定义的函数名 就相当于打印这整个函数
函数包含着一些代码,这些代码只能被事件**,或者在函数被调用时才会执行。
你可以在页面中的任何位置调用脚本(如果函数嵌入一个外部的 .js 文件,那么甚至可以从其他的页面中调用)。
创建函数的语法:function 函数名(var1,var2,...,varX){
代码...
}
注意:无参数的函数必须在其函数名后加括号
函数的调用必须是函数名后面跟(),有参给参无参不给
函数名是什么? 函数名 == 整个函数。
函数加载问题? JS加载的时候,只加载函数名,不加载函数体。所以如果想使用内部的成员变量,需要先调用这个函数函数。
第一种:函数声明(最常用)
function 函数名(){
代码...
}
第二种:函数表达式
var text = function (var1,var2,...,varX) {
代码……
}
第三种:面向对象(构造函数)
var fn = new Function(var1,var2,...,varX);
第四种:匿名函数(即没有名字的函数)
function (){
代码……
}
特殊的函数:
第一种:回调函数(一个函数作为另一个函数的参数进行传递)
function fn(a,b,){
return a()+b();
}
var one = function(){
return 1;
}
var two = function(){
return 2:
}
//函数调用
fn(one,two)
第二种:匿名回调函数(将匿名函数作为参数传递的函数)
第三种:自调函数(自己定义自己调用,别人不能调用的函数)
(function () {
alert("a");
}) ();
第四种:内部私有函数(函数里面还有函数)
内部私有函数的表现形式:
function fn() { function fn1() { console.log("fn1"); } } fn(); // fn1();//如果执行fn1()会报错内部私有函数的解决办法:(通过函数表达式的方式将内部的那个函数给放到外部)
var fn2 ; function fun() { fn2=function () { alert("fn2"); } } fun(); fn2();
闭包:闭包就是能够读取其他函数内部变量的函数,闭包包含自由(未绑定到特定对象)变量,这些变量不是在这个代码块内或者任何全局上下文中定义的,而是在定义代码块的环境中定义(局部变量),闭包是将函数内部和函数外部连接起来的桥梁。
//作用域、上下文 function a() { var i=0; function b() { console.log(++i); } return b; } var c = a(); c();
首先函数c是无法访问函数a中的变量的,此时通过在函数a内构造一个内部函数b,b自然是可以读取a中的变量的,此时c便可以通过b来读取a中的变量,这便是闭包了。
如果之后再执行c(),此时会输出1,这是为什么呢?
这和js的垃圾回收机制有很大的关系,由于闭包c的存在,函数b依赖于a中的变量,使得函数a的i始终存在在内存。
递归
注意:别忘记 JavaScript 中大小写字母的重要性。"function" 这个词必须是小写的,否则 JavaScript 就会出错。另外需要注意的是,必须使用大小写完全相同的函数名来调用函数。
return 语句
return 语句用来规定从函数返回的值。
因此,需要返回某个值的函数必须使用这个 return 语句。
function prod(a,b){
}
注意:
1. 如果函数没有显示的使用 return语句 ,那么函数有默认的返回值:undefined
2. 如果函数使用 return语句,那么跟再return后面的值,就成了函数的返回值
3. 如果函数使用 return语句,但是return后面没有任何值,那么函数的返回值 也是:undefined
4. 函数使用return语句后,这个函数会在执行完 return 语句之后停止并立即退出,也就是说return后面的所有其他代码都不会再执行。
变量和作用域(隐式全局变量和变量声明提升)
变量和作用域(函数中的变量需要函数执行后才能执行)
一、全局变量(成员变量)
哪里都可以访问到的变量。
(进入script立即定义的变量或函数外部和函数没有var的变量)
二、局部变量(只有局部能够访问的变量)
函数内部的变量,只有函数内部可以访问到。
(函数内部用var定义的变量和形参)
作用域:全局变量一直存在,手动消失;局部变量函数调用完就被回收。
隐式全局变量
隐式全局变量就是隐藏的全局变量不好被发现。(没有被var声明的变量可看成是全局变量)
function fn(){
var a = b = c = 1; // b和c就是隐式全局变量
}
注意:
function fn(){
var a = b = c = 1; // b和c就是隐式全局变量(等号)
var a = 1; b = 2; c = 3; // b和c就是隐式全局变量(分号)
var a = 1 , b = 2 , c = 3; // b和c就不是隐式全局变量(逗号)
}
变量声明提升(出现原因:预解析)
函数中,定义变量在使用变量之后。
只提升变量名,不提升变量值,容易出现undefined。计算后形成NaN。
function fn(){
// var aaa;
console.log(aaa);
var aaa = 1;
}
//提前看一眼这个习惯叫什么呢? 预解析!
//变量声明提升:在预解析的时候,成员变量和函数,被提升到最高位置,方便其他程序访问。
//变量声明提升特点:成员变量只提升变量名,不提升变量值。但是,函数是所有内容全部提升。(function直接定义的)
//函数范围内照样会出现变量声明提升
//什么情况容易出现变量声明提升:使用变量在定义变量之前。
函数范围内,照样适用。
预解析过程:
语法检查,如果有错误,直接停止后续步骤不再运行。
把变量和函数的声明提升到当前作用域的最前面,只会提升声明,不会提升赋值和调用。
先提升变量后提升函数,如果函数和变量同名,则被替换;
代码执行过程
变量的赋值,函数的调用,循环判断等,根据代码由上往下顺序执行;
小知识:
1.函数不调用不执行
2.函数名等于整个函数
3.加载函数的时候,只加载函数名,不加载函数体(原因:函数里面的值不加载不执行)
4.就近原则使用变量(同名变量)
5.两个平级的函数变量不会相互影响,但可以使用相同的参数。
如有不足请多多指教!希望给您带来帮助!