简析JavaScript中的Function类型(一)——函数名是指针

说起来ECMAScript中什么最有意思,用原书(《JavaScript高级程序设计》)作者的话说——莫过于函数了,有意思的根源在于函数实际上是对象。每个函数都是Function类型的实例,而且都与其他引用类型一样具有属性和方法。由于函数是对象,因此函数名实际上也就是一个指向函数对象的指针,不会与某个函数绑定。

函数的定义方式有三种:

  1. 函数声明
  2. 函数表达式
  3. 使用Function构造函数

函数声明的方式是比较常见的一种,如下面例子所示:

function sum(num1, num2){
  return num1 + num2;
}

这与下面使用函数表达式定义函数的方式几乎相差无几:

var sum = function(num1, num2){
  return num1 + num2;
};

上面的函数表达式语法定义了变量sum,并将其初始化为一个函数。有读者可能会注意到,function关键字后面没有函数名,这是因为在使用函数表达式定义函数的时候,没有必要使用函数名,通过变量sum即可以引用函数。另外,还要注意函数未尾有个分号,就像声明其它变量一样。

使用Function构造函数定义函数时,Function构造函数可以接收任意数量的参数,但最后一个参数始终都被看作是函数体,而前面的参数则枚举出了新函数的参数。来看下面的例子:

var sum = new Function('num1', 'num2', 'return num1 + num2');

从技术上讲,这也是一个函数表达式。但是,我们不推荐使用这种方式定义函数,因为这种函数定义方式会导致解析两次代码(第一次是解析常规ECMAScript代码,第二次是解析传入构造函数中的字符串),从而影响性能。不过,这种方式对于理解“函数是对象,函数名是指针”来说倒是非常直观的。

由于函数名仅仅是指向函数的指针,因此函数名与包含对象指针的其他变量没有什么不同。换句话说,一个函数可能会有多个名字,如下例所示:

function sum(num1, num2){
  return num1 + num2;
}
console.log(sum(10, 10));// 20

var anotherSum = sum;
console.log(anotherSum(10, 10));// 20

sum = null;
console.log(anotherSum(10, 10));// 20

上面的代码首先定义了一个名为sum的函数,用于求两个数的和。然后,又声明了变量anotherSum,赋值为sum,此时anotherSumsum就指向了同一个函数,因此anotherSum()也正常返回了结果。即使切断sum与函数对象的引用关系,也不会影响anotherSum

函数名作为指针,也可以理解为什么ECMAScript中没有函数重载(函数名相同,参数列表不同)的概念。来看下面的示例:

function add(num){
  return 100 + num;
}
function add(num, num2){
  return 200 + num;
}
console.log(add(100));// 300

按照函数重载的概念,两个add函数的参数列表不同,当传入一个参数时应该调用第一个add,当传入两个参数时应该调用第二个add。但如上例所示,即使传入一个参数依然是调用第二个add,结果为300,这是为什么呢?

答案在函数名是指针,所以第二个add覆盖了第一个add,也许用函数表达式的写法更容易理解:

var add = function(num){
  return 100 + num;
};
var add = function(num, num2){
  return 200 + num;
};

如上例所示,重新声明add会覆盖第一个add。而JavaScript中的函数调用会根据实际传入的参数个数按顺序匹配参数列表,比如这里传入了一个100,那么add中的num就为100num2undefined,如果像这样调用add(100, 20),那么num2则为20

ECMAScript 2015引入了let关键字可以避免变量覆盖的问题,如下所示:

var add = function(num){
  return 100 + num;
};
//Uncaught SyntaxError: Identifier 'add' has already been declared
let add = function(num, num2){
  return 200 + num;
};

解析的时候已经报错,提示add已经声明,所以使用let会更安全一些。

最近在重读唐浩明先生的小说《曾国藩》,里面曾国藩讲到,看书要做到四点:看读写作。看指的就是通常的默默的阅读,可以增加阅读量;读指高声朗诵,他讲一些诗词歌赋等文章,非高声朗诵不能体会其中奥妙;写是抄写,看书时遇到经典的段落文章、好的句子,要抄写下来,既能加深理解,又能以备日后查阅;作是根据自己的理解再创作,这是检测自己是否真的理解以及提高作文能力的重要途径。

本文算是抄写吧,虽然有稍些改动,但基本和原书内容一致,记录下来,一方面加深印象,另一方面也是分享给读者。

转载于:https://my.oschina.net/bob1900/blog/3017022

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值