提及来ECMAScript中什么最有意思,用原书(《JavaScript高级程序设计》)做者的话说——莫过于函数了,有意思的根源在于函数其实是对象。每一个函数都是Function
类型的实例,并且都与其余引用类型同样具备属性和方法。因为函数是对象,所以函数名实际上也就是一个指向函数对象的指针,不会与某个函数绑定。javascript
函数的定义方式有三种:java
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代码,第二次是解析传入构造函数中的字符串),从而影响性能。不过,这种方式对于理解“函数是对象,函数名是指针”来讲却是很是直观的。指针
因为函数名仅仅是指向函数的指针,所以函数名与包含对象指针的其余变量没有什么不一样。换句话说,一个函数可能会有多个名字,以下例所示:code
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
,此时anotherSum
和sum
就指向了同一个函数,所以anotherSum()
也正常返回告终果。即便切断sum
与函数对象的引用关系,也不会影响anotherSum
。对象
函数名做为指针,也能够理解为何ECMAScript中没有函数重载(函数名相同,参数列表不一样)的概念。来看下面的示例:ip
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
就为100
,num2
为undefined
,若是像这样调用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
会更安全一些。
最近在重读唐浩明先生的小说《曾国藩》,里面曾国藩讲到,看书要作到四点:看读写做。看指的就是一般的默默的阅读,能够增长阅读量;读指高声朗诵,他讲一些诗词歌赋等文章,非高声朗诵不能体会其中奥妙;写是抄写,看书时遇到经典的段落文章、好的句子,要抄写下来,既能加深理解,又能以备往后查阅;做是根据本身的理解再创做,这是检测本身是否真的理解以及提升做文能力的重要途径。
本文算是抄写吧,虽然有稍些改动,但基本和原书内容一致,记录下来,一方面加深印象,另外一方面也是分享给读者。