声明函数

在ECMAScript中,创建函数的最常用的两个方法是函数表达式和函数声明,两者期间的区别是有点晕,因为ECMA规范只明确了一点:函数声明必须带有标示符(Identifier)(就是大家常说的函数名称),而函数表达式则可以省略这个标示符:

  函数声明:

  function 函数名称 (参数:可选){ 函数体 }

  函数表达式:

  function 函数名称(可选)(参数:可选){ 函数体 }

所以,可以看出,如果不声明函数名称,它肯定是表达式,可如果声明了函数名称的话,如何判断是函数声明还是函数表达式呢?ECMAScript是通 过上下文来区分的,如果function foo(){}是作为赋值表达式的一部分的话,那它就是一个函数表达式,如果function foo(){}被包含在一个函数体内,或者位于程序的最顶部的话,那它就是一个函数声明。

  function foo(){} // 声明,因为它是程序的一部分  var bar = function foo(){}; // 表达式,因为它是赋值表达式的一部分

  new function bar(){}; // 表达式,因为它是new表达式

  (function(){    function bar(){} // 声明,因为它是函数体的一部分  })();

还有一种函数表达式不太常见,就是被括号括住的(function foo(){}),他是表达式的原因是因为括号 ()是一个分组操作符,它的内部只能包含表达式,我们来看几个例子:

  function foo(){} // 函数声明  (function foo(){}); // 函数表达式:包含在分组操作符内

  try {    (var x = 5); // 分组操作符,只能包含表达式而不能包含语句:这里的var就是语句  } catch(err) {    // SyntaxError  }

你可以会想到,在使用eval对JSON进行执行的时候,JSON字符串通常被包含在一个圆括号里:eval(‘(‘ + json + ‘)‘),这样做的原因就是因为分组操作符,也就是这对括号,会让解析器强制将JSON的花括号解析成表达式而不是代码块。

  try {    { "x": 5 }; // "{" 和 "}" 做解析成代码块  } catch(err) {    // SyntaxError  }

  ({ "x": 5 }); // 分组操作符强制将"{" 和 "}"作为对象字面量来解析

表达式和声明存在着十分微妙的差别,首先,函数声明会在任何表达式被解析和求值之前先被解析和求值,即使你的声明在代码的最后一行,它也会在同作用域内第一个表达式之前被解析/求值,参考如下例子,函数fn是在alert之后声明的,但是在alert执行的时候,fn已经有定义了:

  alert(fn());

  function fn() {    return ‘Hello world!‘;  }

另外,还有一点需要提醒一下,函数声明在条件语句内虽然可以用,但是没有被标准化,也就是说不同的环境可能有不同的执行结果,所以这样情况下,最好使用函数表达式:

  // 千万别这样做!  // 因为有的浏览器会返回first的这个function,而有的浏览器返回的却是第二个

  if (true) {    function foo() {      return ‘first‘;    }  }  else {    function foo() {      return ‘second‘;    }  }  foo();

  // 相反,这样情况,我们要用函数表达式  var foo;  if (true) {    foo = function() {      return ‘first‘;    };  }  else {    foo = function() {      return ‘second‘;    };  }  foo();
时间: 2024-11-05 06:12:51

声明函数的相关文章

[其他] 关于C语言中使用未声明函数的问题

在c语言中,碰到一个.c文件,无.h头文件,在另一.c文件调用函数时,并没有进行声明extern, 此时编译器不会报错,会默认去查找同名的函数,这样会存在一些问题,查了些资料,稍微总结了下: 总结: 1.声明函数可以不加extern,函数默认extern.2.声明变量必须要加extern.3.如果不加extern,编译器会默认去查找同函数名的函数,但会出错. 1).参数中如果出现float,一定会出现读取错误,但编译运行不报错.如果形参float后有int*类型的变量,编译运行会报错,之前有则不

javascript中定义声明函数的四种方法

javascript中定义声明函数的四种方法 :http://blog.163.com/zzf_fly/blog/static/209589158201286104927248/ 方法一:function functionName([parameters]){functionBody}; 方法二:将一个未命名的函数function赋给一个指定变量(var):var add=function(a, b){} 方法三:使用new运算符声明函数varName=new Function([param1N

javascript两种声明函数的方式的一次深入解析

声明函数的方式 javascript有两种声明函数的方式,一个是函数表达式定义函数,也就是我们说的匿名函数方式,一个是函数语句定义函数,下面看代码: /*方式一*/ var FUNCTION_NAME = function() { /* FUNCTION_BODY */}; /*方式二*/ function FUNCTION_NAME () { /* FUNCTION_BODY */}; 区别一 方式一的声明方式是先声明后使用 方式二的声明方式可以先调用,后声明 /*方式一: *先声明后使用 *

js中声明函数的区别

在JS中有两种定义函数的方式, 1是var aaa=function(){...} 2是function aaa(){...} var 方式定义的函数,不能先调用函数,后声明,只能先声明函数,然后调用. function方式定义函数可以先调用,后声明.请看代码: var声明时,只有变量声明提前了,变量的初始化代码仍在原位置.然而,使用函数声明的话,函数名称和函数体都会提前.两种声明得到的函数都不可删除 //aaa();这样调用就会出错                var aaa = funct

块内声明函数

ES5中只有全局作用域和函数作用域,没有块级作用域的概念,而ES6中引入了块级作用域的概念. ES5 规定,函数只能在顶层作用域和函数作用域之中声明,不能在块级作用域声明. 但是,浏览器没有遵守这个规定,为了兼容以前的旧代码,还是支持在块级作用域之中声明函数,因此上面两种情况实际都能运行,不会报错. ES6 引入了块级作用域,明确允许在块级作用域之中声明函数.ES6 规定,块级作用域之中,函数声明语句的行为类似于let,在块级作用域之外不可引用.

声明函数的属性

在GNU C中,你可以声明关于在你程序中调用的函数的某些东西,来帮助编译器优化函数调用和更仔细地检查你的代码. 关键字__attribute__允许你在声明时指定特殊的属性.跟在这个关键字后面的是双重圆括号里面的属性说明.有十四个属性noreturn, pure, const, format, format_arg, no_instrument_function, section, constructor, destructor, unused, weak, malloc, alias and

c++学习笔记之基础---类内声明函数后在类外定义的一种方法

在C++的“类”中经常遇到这样的函数, 返回值类型名 类名::函数成员名(参数表){ 函数体.} 双冒号的作用 ::域名解析符!返回值类型名 类名::函数成员名(参数表) { 函数体. } 这个是在类内声明函数后在类外定义的一种方法!如果不加"类名::"的话,编译系统就不会知道你的函数属于哪个类;另外,这样定义函数一定要在类中声明之后,说明它是类的成员函数才可以!在类内声明的时候就不需要::了,直接 返回值类型 函数名(参数表) 就可以了!

如何声明函数指针类型

函数指针就是指向函数的指针,可以用与函数指针类型对应的函数名赋值,可以用来调用函数.全局函数指针常用于回调(函数). 声明函数指针类型应根据其所指向的函数去声明. 例如声明函数 int fun(int i,float k); 的函数指针类型,只需仿照函数这样写 typedef int (*Pfun)(int i, float k); 如此便可定义该类型的函数指针变量 Pfun pfun = NULL;

声明函数的是方式

声明函数的方式 在JS里面,声明函数的方式有多种 普通声明方式 所谓普通声明方式,就是我们最常见的函数声明方式 通过这种方式所创建的函数,有一个特点,就是会有函数提升.会将函数提升到最上面 在JS里面,函数是一等公民.所以在提升的时候,同样是提升,函数的提升会在变量的提升的上面. 函数表达式 所谓函数表达式,就是指将一个函数(一般指匿名函数)赋值给一个变量.这种形式不存在函数提升 所谓匿名函数,就是指没有函数名的函数 命名式函数表达式 就是将一个有函数名的函数赋值给一个变量 需要注意的是,虽然命