`
yiminghe
  • 浏览: 1453073 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

函数申明与函数表达式注意

阅读更多

发现一个好博客:Exploring Javascript by example , 其中一篇文章讨论了 function declaration 以及 named function expression ,讲得很通俗,但是最后那个问题文章没有细讲.

 

起源:

 

在 jquery 源码中看到,原先的类似

 

var b=function(){
  if(..)  arguments.callee();
};

 由于ecmascript-5th不推荐使用callee (strict mode 访问arguments.callee/caller发生异常),变为:

 

var b=function a(){
  if(..)  a();
};

 

 

 

问题:


但是由于代码的不规范以及过于复杂,有时会出现:

 

var b=function a(i){
	if(i!=0) {
		alert(i);
		//递归一下
		a(i-1);
	}
};

//....

//...

alert(a);


//不小心重名了
var a='x';

alert(a);
b(2);
alert(a);

 

可以分别在 ie 和 其他标准浏览器中运行看看,其中 ie 出错了

 

规范:

 

13 function definition 中提到的:


1.  Let  funcEnv be the result of calling NewDeclarativeEnvironment passing the running execution context’s Lexical
Environment as the argument
2.  Let envRec be funcEnv’s environment record.
3.  Call the CreateImmutableBinding(N) concrete method of  envRec  passing the String value of  Identifier as the
argument.
4.  Let  closure  be the result of creating a new Function object as  specified in 13.2 with parameters specified by
FormalParameterListopt and body specified by  FunctionBody. Pass in  funcEnv  as the  Scope. Pass in  true as the
Strict flag if the FunctionExpression is contained in strict code or if its FunctionBody is strict code.
5.  Call the InitializeImmutableBinding(N,V) concrete method of  envRec  passing the String value of  Identifier  and
closure as the arguments.
6.  Return closure.


NOTE The Identifier in a FunctionExpression can be referenced from inside the FunctionExpression's FunctionBody to
allow the function to call itself recursively. However, unlike in a FunctionDeclaration, the  Identifier in a FunctionExpression
cannot be referenced from and does not affect the scope enclosing the FunctionExpression.

 

 

我的解释:

 

可见:在标准中

 

var b=function a(i){
	
	if(i!=0) {
		alert(i);
		//递归一下
		a(i-1);
	}
};

//相当于添加closure

var b=function(){

var a;
return a=function (i){
	
	if(i!=0) {
		alert(i);
		//递归一下
		a(i-1);
	}
}

}();
 

而在ie中相当于:

 

var b=function (i){
if(i!=0){
alert(i);
a(i-1);
}
};
function a(i){
	
	if(i!=0) {
		alert(i);
		//递归一下
		a(i-1);
	}
};



alert(b === a); //false

 

则出错就不意外了!

 

 

分享到:
评论

相关推荐

    JavaScript中的函数申明、函数表达式、箭头函数

    与函数声明不同,函数表达式不会被提升,而是按照代码的顺序执行。这意味着在函数表达式赋值之前尝试调用它会导致错误,因为此时函数尚未定义。上面的例子展示了这种差异,通过比较函数声明和表达式的执行顺序,我们...

    Kotlin 中文文档.pdf

    多重申明 Ranges 类型检查和自动转换 This表达式 等式 运算符重载 空安全 异常 注解 反射 动态类型 参考 API 语法 互用性 Introduction 6 与 java 交互 工具 Kotlin代码文档 使用Maven 使用Ant 使用Griffon 使用...

    python实现的控制台的数学表达式计算器-《智能系统设计与应用》

    (2)表达式中若出现未申明变量,则给该变量初始化一个随机 值,如:a = random(0,10); (3)支持常用数学函数,包括(不限于)如下函数:sin, cos, tan, floor, random, abs, sqrt, ^.... (4)可以修改变量的值,...

    按键精灵VBS脚本教程

    CCur函数可把表达式转换为货币(Currency)类型CSng函数可把表达式转换为单精度(Single)类型。Cdate函数将变量转换为日期值。Cint函数和Clng函数将变量转换为整数,后者的范围比前者要大的多。Cstr函数将变量转换...

    深入浅析python 中的匿名函数

    Python用lambda语法定义匿名函数,只需用表达式而无需申明。 lambda语法的定义如下: lambda [arg1 [,arg2, ... argN]] : expression 匿名函数就是没有实际名称的函数。其主体仅仅是一个表达式,而不需要使用代码块...

    Javascript中 带名 匿名 箭头函数的重要区别(推荐)

    在JavaScript编程语言中,函数是其核心特性之一,有多种函数定义方式,包括带名函数、匿名函数以及ES6引入的箭头函数。这三种函数形式各有特点,下面将详细介绍它们之间的关键区别。 1. 带名函数: 带名函数,即在...

    基于分治思想的表达式运算系统C#源码+项目说明+sln解决方案.zip

    (2)表达式中若出现未申明变量,则给该变量初始化一个随机值,如:a = random(0,10); (3)支持常用数学函数,包括(不限于)如下函数:sin, cos, tan, floor, random, abs, sqrt, ^… (4)可以设置变量动画,...

    本人转载 在此申明 语法树 c 实现 四则运算语法树

    这个函数可能使用栈来存储中间结果,遇到运算符时,将当前的操作数与栈顶的操作数结合,形成一个新的运算节点,并压入栈中。 以下是一个简单的C++代码示例,展示了如何构建一个基本的四则运算语法树节点: ```cpp ...

    VC++支持中文的正则表达式函数库

    这可能是第一个大陆程序员写的开源正则表达式库,原始作者 : lanzhengpeng(兰征鹏),作者放弃除著作署名权之外的任何权益,你可以在保留此申明的前提下,自由的,无限制的分发、修改和使用本函数库。  如有任何建议...

    2015年电大面向对象的程序设计试题库参考资料汇总.doc

    递归函数是函数调用自己的函数,嵌套函数是函数定义在函数内部的函数,Lambda 表达式是匿名函数。 9. 软件工程中的质量因素 软件工程中的质量因素包括正确性、健壮性、可扩展性、可重用性、有效性等。这些因素是...

    Algorithms A Functional Programming Approach

    本书的副标题强调了函数式编程范式在算法设计和实现中的应用,将传统算法与函数式编程思想结合,向读者展示了如何使用函数式编程语言来实现和理解算法。函数式编程(Functional Programming,简称FP)是一种编程范式...

    1、scala面试题(25问).pdf

    Scala语言中的隐式转换函数是指那种以implicit关键字申明的带有单个参数的函数,这样的函数会被自动应用,将值从一种类型转换为另一种类型。 7. 伴生类和伴生对象 在Scala语言中,单例对象与类同名时,该对象被...

    c#智能系统设计与应用,设计一个智能代数运算系统(计算器),实现简单的运算

    (2)表达式中若出现未申明变量,则给该变量初始化一个随机值,如:a = random(0,10); (3)支持常用数学函数,包括(不限于)如下函数:sin, cos, tan, floor, random, abs, sqrt, ^.... (4)可以修改变量的值,表达式...

    C++程序设计 谭浩强 PPT

    第2章 数据类型与表达式 第2篇 面向过程的程序设计 第3章 程序设计初步 第4章 函数与预处理 第5章 数组 第6章 指针 第7章 自定义数据类型 第3篇 基于对象的程序设计 第8章 类和对象 第9章 关于类和对象的进一步讨论 ...

    C语言理论判断题&选择题.docx

    6.C语言中,若省略函数返回类型的申明,则函数类型默认为int。 7.C语言程序中可以有多个函数或多个主函数。 8.一个函数被调用时,函数体内部又调用另一个函数的调用方式称为嵌套调用。 9.函数参数之间的传递方式有两...

    JavaScript下申明对象的几种方法小结

    - 函数表达式(Function Expressions): 也可以使用函数表达式来声明对象,例如 `var myObject = function() {};`。函数表达式的好处是可以包含参数,类似于带有参数的构造函数。 2. 构造函数和函数表达式的参数化 ...

    Kotlin中文版文档

    Kotlin支持多重申明,允许在一个文件或代码块中多次定义同名的变量或函数。Ranges是一个表示数值或字符序列的类型,可以用于范围检查或迭代。 Kotlin还支持类型检查和自动转换,以及多种函数式编程特性,如内联函数...

Global site tag (gtag.js) - Google Analytics