JavaScript必知必会(九)function 说起 闭包问题

function getPrototyNames(o,/*optional*/ a) { a = a || []; for(var p in o) { a.push(p); } return a; }

caller

func.caller 返回函数调用者

function callfunc() { if(callfunc.caller) { alert(callfunc.caller.toString()); }else { alert("没有函数调用"); } } function handleCaller() { callfunc(); } handleCaller();//返回 handler callfunc();//没有函数调用,返回null,执行了《没有函数调用》

callee

匿名方法递归调用

alert( (function (x) { if (x <= ) return ; return x * arguments.callee(x - ); }()));//

scope

作用域大家都不陌生,今天就来说说闭包问题,深刻吃透闭包问题。

<script> var global = "global scope";//这个是全局的作用域 function scope() { var scope = "local scope";//这个是局部的作用域 return scope;//返回的scope,是局部的变量 } </script>

  1、:定义的全局变量也能在函数内部访问。当定义的局部变量和全局变量名字相同时,局部变量的就会隐藏全局变量,不会破坏全局变量的值。

var scope = "global scope"; function f() { var scope = "local scope"; return scope; } alert(f());//local scope alert(scope);//global scope;

  上面确实是很容易理解,对吧。

2、 全局变量可以不用var声明,但是局部变量必须使用var声明,如果局部变量不使用var声明,编译器会默认这个是个全局变量。

<span>  </span> scope = "global scope"; function f() { scope = "local scope"; return scope; } alert(f());//local scope alert(scope);//local scope

  但是全局变量不使用var声明,也仅限非严格模式,如果使用严格模式的话,会报错误

<script> "use strict"; scope = "global scope"; function f() { scope = "local scope"; return scope; } alert(f());//local scope alert(scope);//local scope </script>

JavaScript必知必会(九)function 说起 闭包问题

所以建议大家声明变量时,千万不要省略var,可以避免不必要的麻烦。

3、 声明提前,也是可以滴。什么叫什么提前。

JavaScript必知必会(九)function 说起 闭包问题

<script> "use strict"; scope; console.log(scope); var scope = "global scope"; console.log(scope); </script>

这个可能大家看出第一个打印undefined ,是呀还没有给他赋值, 下面赋值可定打印global scope了。

这样理解并没有错,但是为什么会这样的呢,一个变量不是应该先定义才可以使用的吗?

这里给大家说下作用域链,JavaScript是基于词法作用域的语言。

1、作用域链是一个对象或者链表,这组代码中定义了这段代码"作用域中“的变量。当JavaScript需要查找变量scope时,就会从链中的第一个对象开发查找,如果第一个对象为scope,则会直接返回这个对象的值,如果不存在继续第二对象开始查找,直到找到。如果在作用域链上未查到该变量,则会抛出一个错误。

我们可以这个作用链可以这样表示:查找 scope->window(全局对象)很显然后面是有定义scope的。但是并没有做赋值操作,后面才做赋值操作,所以此时值为undefined.

4、这个比较具有迷惑性了,大家猜想下打印的值是什么?

<script> "use strict"; var scope = "global scope"; function f() { console.log(scope); var scope = "local scope"; console.log(scope); } f(); </script>

看到这段代码:如果你粗心大意的话,很有可能会写出错误的答案:

1、gobal scope

2、local scope

分析: 声明了全局变量,在函数体中时,第一个表示全局变量,所以打印global,第二定义了局部的变量,覆盖掉了全局的scope,所以打印local scope。

这样的分析在C# java ,完全正确。但是这里分析确实错误的。

这说明这个问题前,我们先看一个问题。

这句话很重要:全局变量在程序中始终都是有定义的。局部变量在声明它的函数体以及其所嵌套的函数内始终是定义的。

如果你是从事高级语言工作开始接触JavaScript 有点不适应其作用域的定义。我也是这样的。我们来看一个例子:

<script> var g = "global scope"; function f() { for(var i=;i<;i++) { for(var j=;j<;j++) { ; } console.log(j); } console.log(i); } console.log(g); f(); </script>

  打印的结果是什么?

大家看到{} 表示语句块,语句块在一块作用域,所以大家可能猜想,j、i值已经在内存释放掉了,所以结果肯定是undefined.

真实的结果可能令你失望,

JavaScript必知必会(九)function 说起 闭包问题

结果为什么会是这样,我开始的表情和你一样。

JavaScript必知必会(九)function 说起 闭包问题

这时查看我让你记住的那句话。。。全局变量在程序中始终都是有定义的。局部变量在声明它的函数体以及其所嵌套的函数内始终是定义的。

确切的说函数的参数 也是属于局部变量的范畴。这句话也很重要!!!

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wzspgz.html