前端乱弹99日

前端乱弹99日之函数是一等公民

2018-05-20  本文已影响3人  业余马拉松选手

拖延症晚期癌,每次都是周日最后一个小时才开始动笔,先鄙视下自己

今天要“弹”的是一个有点被说“烂”了的话题,在JavaScript里,函数是一等公民(哇,听起来很高大上吧),而同时在这个函数式编程异常火爆的年代,你到底该怎么理解“函数是一等公民”这句话呢?

其实,我们也可以换个角度来看,在JavaScript里,任何东西都是对象(嗯,还是要刨掉原始类型),作为一个后端狗,在读《Java编程思想》这部“巨著”的时候,记得有那么一句“万事万物皆是对象”,那么在JavaScript里离这句话就更近了一些,下面就先看一个例子吧

var log = function(a){
  console.log("invoke:"+a);
}
log.name = "日志";
console.log(log.name);

这里,我们不仅可以将一个函数赋值给一个变量,甚至还可以给这个变量再增加一个属性。那么上面这个log这个到底是个函数呢还是个对象呢?

其实,在JavaScript里,函数只是一个更特殊的对象,他首先拥有对象的一切能力,接着,他还有额外的一个特殊的部分,可以成为执行部分,或是代码部分,那么接着一个更酷的事情就是,我们可以这样使用log这个变量。

var log = function(a){
  console.log("invoke:"+a);
}
log.name = "日志";
log("Just A Test");

这段代码,将会输出

invoke:Just A Test

嗯,如果将一个函数赋值给一个变量之后,我们只需要在这个变量后面增加()即,代表这是一个函数式的对象,可以执行,这里()更适合一种“运算符”,嗯,就叫执行运算符。

而如果一个变量本身不是指向的了一个函数的话,强行调用()会报错,我们可以试试这样一段代码

var a = {
  "name" : "value"
}
a();

这里,我们定义了一个变量a,而变量a实际“指向”的是一个对象,并不是函数,这时我们强行调用()的话,会报这样的错误:

Uncaught TypeError: a is not a function

报错信息很明确,a并不是一个函数。

另外,有关前面曾经聊过的“变量提升”的问题,这里也是需要再说一说的。

我们之前明确过,一个函数定义是会在运行时环境构建的适合就处理完成,因此一个函数的定义和调用的顺序是无关的。

比如这段代码

log("just a test");
function log(a){
  console.log(a);
}

这里我们已经很清楚,是可以正确执行的,那么如果我们换一种方法呢:

log();
var log = function(a){
  console.log(a);
}

这时是会报错的:

Uncaught TypeError: log is not a function

因为这里,log只是一个普通的变量,JavaScript的运行时环境并不会把他作为一个函数,对他提前的初始化,这样的报错就更好理解了。

那么对于函数式编程在JavaScript里的运用,那就更是一个有意思的话题了,今天我们只是框清了一个概念“在JavaScript里,函数只是一个特殊的对象而已”

上一篇 下一篇

猜你喜欢

热点阅读