ECMAScript 函数

一、ECMAScript 函数概述

1、什么是函数?

函数是一组可以随时随地运行的语句。
函数是 ECMAScript 的核心。
函数是由这样的方式进行声明的:关键字 function、函数名、一组参数,以及置于括号中的待执行代码。

函数的基本语法是这样的:

    function functionName(arg0, arg1, ... argN) {
       statements
    }

例如:

function sayHi(sName, sMessage) {
  alert("Hello " + sName + sMessage);
}

2、如何调用函数?

函数可以通过其名字加上括号中的参数进行调用,如果有多个参数。
如果您想调用上例中的那个函数,可以使用如下的代码:

sayHi("David", " Nice to meet you!")

调用上面的函数 sayHi() 会生成一个警告窗口。

3、函数如何返回值?

函数只需要使用return运算符后跟要返回的值即可。

函数在执行过 return 语句后立即停止代码。因此,return 语句后的代码都不会被执行。

注释:如果函数无明确的返回值,或调用了没有参数的 return 语句,那么它真正返回的值是 undefined。


二、ECMAScript arguments 对象

1、arguments 对象

在函数代码中,使用特殊对象 arguments,开发者无需明确指出参数名,就能访问它们。

例如,在函数 sayHi() 中,第一个参数是 message。用 arguments[0] 也可以访问这个值,即第一个参数的值(第一个参数位于位置 0,第二个参数位于位置 1,依此类推)。

因此,无需明确命名参数,就可以重写函数:

function sayHi() {
  if (arguments[0] == "bye") {
    return;
  }

  alert(arguments[0]);
}

2、检测参数个数

还可以用 arguments 对象检测函数的参数个数,引用属性 arguments.length 即可。

function howManyArgs() {
  alert(arguments.length);
}

howManyArgs("string", 45);
howManyArgs();
howManyArgs(12);

上面这段代码将依次显示 "2"、"0" 和 "1"。

注释

  • ECMAScript 不会验证传递给函数的参数个数是否等于函数定义的参数个数
  • 开发者定义的函数都可以接受任意个数的参数(根据 Netscape 的文档,最多可接受 255 个),而不会引发任何错误。
  • 任何遗漏的参数都会以 undefined 传递给函数,多余的函数将忽略。

3、模拟函数重载

用 arguments 对象判断传递给函数的参数个数,即可模拟函数重载:

function doAdd() {
  if(arguments.length == 1) {    //arguments.length用于判断参数的个数
    alert(arguments[0] + 5);
  } else if(arguments.length == 2) {
    alert(arguments[0] + arguments[1]);
  }
}

doAdd(10);  //输出 "15"
doAdd(40, 20);  //输出 "60"

三、ECMAScript Function 对象(类)

ECMAScript 的函数实际上是功能完整的对象。

1、Function 对象(类)

ECMAScript 最令人感兴趣的可能莫过于函数实际上是功能完整的对象。
Function 类可以表示开发者定义的任何函数。

用 Function 类直接创建函数的语法如下:

var function_name = new function(arg1, arg2, ..., argN, function_body)

在上面的形式中,每个 arg 都是一个参数,最后一个参数是函数主体(要执行的代码)。这些参数必须是字符串。

实例:

var sayHi = 
new Function("sName", "sMessage", "alert(\"Hello \" + sName + sMessage);");

2、Function 对象的 length 属性

如前所述,函数属于引用类型,所以它们也有属性和方法。

ECMAScript 定义的属性 length 声明了函数期望的参数个数

ECMAScript 可以接受任意多个参数(最多 25 个)

3、Function 对象的方法

Function 对象也有与所有对象共享的 valueOf() 方法和 toString() 方法。这两个方法返回的都是函数的源代码,在调试时尤其有用。例如:

function doAdd(iNum) {
  alert(iNum + 10);
}

document.write(doAdd.toString());

返回结果:

function doAdd(iNum) { alert(iNum + 10); }

四、ECMAScript 闭包(closure)

ECMAScript 最易让人误解的一点是,它支持闭包(closure)。
闭包,指的是词法表示包括不被计算的变量的函数,也就是说,函数可以使用函数之外定义的变量。

1、简单的闭包实例

在 ECMAScript 中使用全局变量是一个简单的闭包实例。请思考下面这段代码:

var sMessage = "hello world";

function sayHelloWorld() {
  alert(sMessage);
}

sayHelloWorld();

2、复杂的闭包实例

在一个函数中定义另一个会使闭包变得更加复杂。例如:

var iBaseNum = 10;

function addNum(iNum1, iNum2) {
  function doAdd() {
    return iNum1 + iNum2 + iBaseNum;
  }
  return doAdd();
}

这里要掌握的重要概念是,doAdd() 函数根本不接受参数,它使用的值是从执行环境中获取的。


补充


五、变量对象(Variable Object)

1、介绍

大多数ECMAScript程序员应该都知道变量与执行上下文有密切关系:

var a = 10; // 全局上下文中的变量
 
(function () {
  var b = 20; // function上下文中的局部变量
})();
 
alert(a); // 10
alert(b); // 全局变量 "b" 没有声明

并且,很多程序员也都知道,当前ECMAScript规范指出独立作用域只能通过“函数(function)”代码类型的执行上下文创建。也就是说,相对于C/C++来说,ECMAScript里的for循环并不能创建一个局部的上下文。

for (var k in {a: 1, b: 2}) {
  alert(k);
}
 
alert(k); // 尽管循环已经结束但变量k依然在当前作用域

2、数据声明

如果变量与执行上下文相关,那变量自己应该知道它的数据存储在哪里,并且知道如何访问。这种机制称为变量对象(variable object)。

变量对象(缩写为VO)是一个与执行上下文相关的特殊对象,它存储着在上下文中声明的以下内容:

  • 变量 (var, 变量声明);
  • 函数声明 (FunctionDeclaration, 缩写为FD);
  • 函数的形参

参考资料


【1.ECMAScript 函数概述】http://www.w3school.com.cn/js/pro_js_functions.asp
【2.深入理解JavaScript系列(12):变量对象(Variable Object)】http://www.cnblogs.com/TomXu/archive/2012/01/16/2309728.html

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,524评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,869评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,813评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,210评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,085评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,117评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,533评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,219评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,487评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,582评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,362评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,218评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,589评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,899评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,176评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,503评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,707评论 2 335

推荐阅读更多精彩内容