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

 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
时间: 2024-12-28 00:31:45

命名函数表达式的名字和函数声明的名字的相关文章

java8 函数引用 -> 一种利用现有函数简单推理为函数表达式即简化的函数表达式

// ***java8 函数引用 -> 一种利用现有函数简单推理为函数表达式即简化的函数表达式(省去了参数,-> 符号,只有更简化函数表达式体),[从而生成对应接口实现类默认的抽象方法体].*** // 函数表达式可以推理成java的匿名类,那么现有的函数就可以推理成函数表达式.只要现有的函数符合要生成的方法的签名即可(入参,返回值,函数名无关紧要) // 参数和返回值有编译器从上下文获得.从而省去了参数.只提供方法名就可以. // 所以(arg) -> {} 函数表达式,可以简化为利用

函数声明、 函数表达式 与立即调用函数表达式的比较

函数声明 函数声明创建将来代码调用的函数.函数可以在声明之前的位置被调用.代码样例如下: //可以在声明之前的位置被调用 var size=area(3,6); function area(width,height){ return width*height; }; //可以在声明之后的位置被调用 var size2=area(2,4); 函数表达式   将函数放在本该表达式待的位置,这称为函数表达式.在函数表达式中,经常使用匿名函数.代码样例如下 var area=function(width

函数表达式和函数声明~(自己的记录)

在ECMAScript中,创建函数的最常用的两个方法是函数表达式和函数声明,两者期间的区别是有点晕,ECMA的规范明确了一点~函数声明必须带有标示符 (Identifier)就是大家说的(函数名),而函数表达式则可以省略函数名. 那么没有函数名那肯定就是函数表达式了,那么有函数名时,如何区分它是函数表达式还是函数声明呢~~如果是作为赋值表达式的一部分则为函数表达式,如果是包含在一个函数体内,或者位于程序的最顶部的话则作为函数声明~ function foo(){} // 声明,因为它是程序的一部

深入理解JavaScript系列(2):揭秘命名函数表达式

前言 网上还没用发现有人对命名函数表达式进去重复深入的讨论,正因为如此,网上出现了各种各样的误解,本文将从原理和实践两个方面来探讨JavaScript关于命名函数表达式的优缺点. 简单的说,命名函数表达式只有一个用户,那就是在Debug或者Profiler分析的时候来描述函数的名称,也可以使用函数名实现递归,但很快你就会发现其实是不切实际的.当然,如果你不关注调试,那就没什么可担心的了,否则,如果你想了解兼容性方面的东西的话,你还是应该继续往下看看. 我们先开始看看,什么叫函数表达式,然后再说一

深入理解JavaScript系列(2):揭秘命名函数表达式(转)

前言 网上还没用发现有人对命名函数表达式进去重复深入的讨论,正因为如此,网上出现了各种各样的误解,本文将从原理和实践两个方面来探讨JavaScript关于命名函数表达式的优缺点. 简 单的说,命名函数表达式只有一个用户,那就是在Debug或者Profiler分析的时候来描述函数的名称,也可以使用函数名实现递归,但很快你 就会发现其实是不切实际的.当然,如果你不关注调试,那就没什么可担心的了,否则,如果你想了解兼容性方面的东西的话,你还是应该继续往下看看. 我们先开始看看,什么叫函数表达式,然后再

深入理解javascript:揭秘命名函数表达式

这是一篇转自汤姆大叔的文章:http://www.cnblogs.com/TomXu/archive/2011/12/15/2288411.html 前言 网上还没用发现有人对命名函数表达式进去重复深入的讨论,正因为如此,网上出现了各种各样的误解,本文将从原理和实践两个方面来探讨JavaScript关于命名函数表达式的优缺点. 简单的说,命名函数表达式只有一个用户,那就是在Debug或者Profiler分析的时候来描述函数的名称,也可以使用函数名实现递归,但很快你 就会发现其实是不切实际的.当然

命名函数表达式探秘

函数表达式与函数声明 在ECMAScript中,有两个最常用的创建函数对象的方法,即使用函数表达式或者使用函数声明.这两种方法之间的区别可谓 相当地令人困惑:至少我是相当地困惑.对此,ECMA规范只明确了一点,即函数声明 必须始终带有一个标识符(Identifier)——也就是函数名呗,而函数表达式 则可省略这个标识符: 函数声明: function Identifier ( FormalParameterList opt ){ FunctionBody } 函数表达式: function Id

JavaScript 函数声明,函数表达式,匿名函数的区别,深入理解立即执行函数(function(){…})()

function fnName(){xxxx}; // 函数声明:使用function关键字声明一个函数,在指定一个函数名. //例如:(正常,因为 提升 了函数声明,函数调用可以在函数声明之前) fnName(); function fnName(){ alert('Hello World'); } var fnName = function(){xxxx}; //函数表达式:使用function关键字声明一个函数,但是未给函数命名,最后将匿名函数赋予给一个变量. //例如1:(报错,变量fn

javascript中函数声明和函数表达式的区别

1.js中函数表达式的定义 表达式(expression)JavaScript中的一个短语,javascript会将其计算(evaluate)出一个结果.程序中的常量是一个最简单的表达式.变量名也是一种简单的表达式,它的值就是赋值给变量的值.复杂表达式是由简单表达式组成. --摘自<javascript权威指南> 一个经典的函数表达式的定义方法: //函数表达式的声明,表达式的值就是这个新定义的函数 var expressFunc = function(){}; 函数名称是函数声明语句必须得部

JavaScript笔记- 函数声明和函数表达式(001)

function 是 Javascript 中的第一类对象,这就意味着函数可以像其他值一样被传递.一个最常见的用法就是将一个匿名函数作为回调函数传递到另外一个异步函数中. 函数声明 ? 1 function foo() {} 函数 foo 将会在整个程序执行前被 hoist (提升),因此它在定义 foo 函数的整个 scope (作用域)中都是可用的.即使在函数定义之前调用它也没问题. 1 2 foo(); // Works because foo was created before thi