码迷,mamicode.com
首页 > 其他好文 > 详细

命名函数表达式的名字和函数声明的名字

时间:2016-01-11 21:49:51      阅读:134      评论:0      收藏:0      [点我收藏+]

标签:

 1 var s = 0,
 2     b = 0;
 3 function A(s) {
 4     A = function () {
 5         console.log(s + b++);
 6     };
 7     console.log(A);
 8     console.log(s++);
 9 }
10 A(1);
11 A(2);
12 console.log(delete A);
13 A(2);

A作为全局对象的一个属性,值为一个函数的引用,当执行A函数时,将一个匿名函数传给A,此时会进行作用域链查找,在全局对象中找到了A,然后赋给它。因为A作为一个函数声明,是不能删除的。如果改成下面这样:

 1 var s = 0,
 2     b = 0;
 3 function A(s) {
 4     d = function () {
 5         console.log(s + b++);
 6     };
 7     console.log(d);
 8     console.log(s++);
 9 }
10 A(1);
11 d(2);
12 console.log(delete d);//true
13 d(2);

注意,d不是一个变量,只是被添加到全局对象中作为了一个属性,变量不能被删除,属性可以被删除。

 1 function A() {
 2     function B() {
 3         function C() {
 4             A = function () {
 5                 console.log(1);
 6             };
 7         }
 8         C();
 9     }
10     B();
11 }
12 A();
13 A();//1

函数声明和命名函数表达式的函数”真“名是不同的。上面的例子中,A是一个函数声明,作为一个全局对象的属性而存在,执行赋值语句时就是通过作用域链查找到的全局对象里的A。

 1 (function A() {
 2     function B() {
 3         function C() {
 4             A = function () {
 5                 console.log(1);
 6             };
 7         }
 8         C();
 9     }
10     B();
11 })();
12 A();//ReferenceError: A is not defined

命名函数表达式的名称存在了一个特殊对象里,这个特殊对象位于父级作用域和A函数作用域之间,上面的例子中,相当于在全局对象和A函数的活动对象之间加 了一个特殊对象,这个特殊对象只有一个属性那就是A,值为A函数。这就是为什么在全局对象里访问A属性不存在,只有在A函数内部作用域才能访问A属性的原因。也就是说:

1 function A() {}
1 (function A() {})();

上面第一个的A是存在于全局对象里的一个属性,上面第二个的A是存在于一个全局对象和A的活动对象之间的一个特殊对象中。

1 function A() {
2     var A = 2;
3     console.log(A);
4 }
5 A();//2
6 A();//2

所以说,在函数体内可以声明和函数名相同的变量或者函数。只不过不建议这么做,虽然语法没错。

1 function A() {
2     function A() {
3         console.log(2);
4     }
5     A();
6 }
7 A();//2
8 A();//2

 

命名函数表达式的名字和函数声明的名字

标签:

原文地址:http://www.cnblogs.com/callmegongchenglion/p/5122489.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!