sayHi(); //错误:函数还不存在var sayHi = function () {alert("test");};例2:if (true) {function sayHi() {alert("1");}} else {function sayHi() {alert("2");}}sayHi();//打印结果并不是我们想要的例3:var fun1 = function fun2() {alert("test");}fun2();//错误:函数还不存在在例1中,我们不能在使用函数声明式语法定义之前调用函数。解决方案:var sayHi = function () {alert("test");};sayHi()2.使用函数声明式。(这里浏览器引擎会 函数声明提升, 在所有代码执行之前先读取函数声明)sayHi(); function sayHi () {alert("test");};if (true) {function sayHi() { alert("1");}} else {function sayHi() { alert("2");}}sayHi();//打印结果并不是我们想要的为什么会这样?正因为 函数声明提升 ,所以浏览器在预解析的时候不会判断if条件,直接解析第二个函数定义的时候覆盖了第一个。var sayHi;if (true) {sayHi = function () { alert("1");}} else {sayHi = function () { alert("2");}}sayHi();在例3中,发现只能只用fun1()调用,而不能使用fun2()调用。
所以只能只用fun1()调用,而不能使用fun2()调用。
其实这里我还是有疑问的?哪位大神知道,望告知。
既然,fun2在外面不能调用为什么在函数内部能调用?虽然在debugger还是得不到fun1。
好了,通过上面的三道题目热身。我们继续今天的主题“闭包”。
1.什么是闭包?
定义:就是有权访问另一个函数作用域的变量的函数
我们先从一个示例函数开始:
例1:
function fun() {var a = "张三";}fun();//在我们执行完后,变量a就被标记为销毁了例2:function fun() {var a = "张三";return function () {alert("test");}}var f = fun();//同样,在我们执行完后,变量a就被标记为销毁了例3:function fun() {var a = "张三";return function () {alert(a);}}var f = fun();//【现在情况发生变化了,如果a被销毁,显然f被调用的话就不能访问到变量a的值了】f();//【然后变量a的值正常的被访问到了】//这就是闭包,当函数A 返回的函数B 里面使用到了函数A的变量,那么函数B就使用了闭包。示例:function fun() {var a = "张三";return function () { alert(a);}}var f = fun();//【现在情况发生变化了,如果a被销毁,显然f被调用的话就不能访问到变量a的值了】f();//【然后变量a的值正常的被访问到了】显然,滥用闭包会增大内存的使用。所以非特殊情况尽量不要使用闭包。如果用到了,记得手动设置空引用,内存才能被回收 f = null ;
2.什么是匿名函数? (仅仅只是解释这个概念)
如:(即,没有名字的函数)
关于对象中函数的返回值是匿名函数时,this的怪异现象
讲解之前,先清醒下头脑,不要越看越迷糊了。如果迷糊了,那就直接忽略下面的。
var name1 = "张三";var obj = {name1: "李四",fun2: function () {alert(this.name1);},fun3: function () {return function () {alert(this.name1);}}}obj.fun2();//打印结果"李四"意料之中的。var name1 = "张三";var obj = {name1: "李四",fun2: function () {alert(this.name1);},fun3: function () {return function () {alert(this.name1);}}}//obj.fun3()();var obj2 = {};obj2.name1 = "test";obj2.fun = obj.fun3();obj2.fun();//打印结果"test",再次证明了“哪个对象点出来的方法,this就是哪个对象”.var name1 = "张三";var obj = {name1: "李四",fun2: function () { alert(this.name1);},fun3: function () {return function () { alert(this.name1);}}}//obj.fun3()();var obj2 = {};obj2.name1 = "test";obj2.fun = obj.fun3();obj2.fun();//打印结果"test",再次证明了“哪个对象点出来的方法,this就是哪个对象”.我们来分解下 obj.fun3()() 先是 obj.fun3() 返回一个匿名函数到了window作用域,然后接着调用this就指向了window了。( 感觉解释有点勉强,也不知道对不,暂时自己先是这么理解的 )