Functions在JavaScript中是作为 ‘first class objects’ 存在的。这意味着JS中的functions是一种特殊类型的object,objects 可以做的事情,functions 都可以做。
实际上functions就像是variables
以下列举了关于objects的一些重要的事情(在JS中你也可以用function做同样的事情)。
一个function就是Object type的一个实例:
“`
function feedCat() {
alert(“Kibble, tinned food and water”);
}
alert(feedCatinstanceofObject);
“`
一个function可以有properties和一个链接(该链接可以指向constuctor方法/函数) :
“`
feedCat.food = “kibble”;
alert(feedCat.food);
alert(feedCat.constructor);
“`
你可以把function存到一个变量中:
“`
function feedCat() {
alert(“Kibble, tinned food and water”);
}
var eveningChore = feedCat;
eveningChore();
“`
你可以把function作为参数传递给另外一个function:
“`
function doEveningChores(chores) {
for(var x=0; x<chores.length; x++)
chores[x]();
}
doEveningChores([feedCat]);
“`
也可以把function作为function的返回值:
“`
function tonightChores(){
return feedCat;
}
var tonight = tonightChores();
tonight();
“`
Functions在JavaScript中是作为 first class objects存在的好处是:可以减少重复性的代码
能够在程序中以function的形式传递逻辑,就意味着可以把重复的代码写为一个库函数。这样就可以把独特的逻辑片段(unique pieces of logic)从通用的逻辑中分离。
举个栗子:假设你有一份巧克力清单,并且你想找出所有制造商是Mars的巧克力。因为你喜爱Mars而且你想尝尝Mars的其它巧克力(我已经节食七个月,想想巧克力可以使我得到满足)。
你可以写个loop去遍历整个清单并可以像下面这样应用你的挑选逻辑:
“`
var chocolateBars = [
{name: “Galaxy”, manufacturer: “Mars”},
…];
var marsChocolate = [];
for (var x=0; x<chocolateBars.length; x++) {
if(chocolateBars[x].manufacturer == “Mars”)
marsChocolate.push(chocolateBars[x]);
}
“`
很好!问题解决了。只不过现在是圣诞节,你的应用程序还要从好孩子中挑出淘气的孩子。但是既然你是在写程序,你就不应该把同样的事情再重复写一次。
这听起来像是库函数的工作!让我们把每次相同的事情(遍历已有清单,建立新清单)从不同的事情(应用不同的过滤器)中分离出来。遍历已有清单并建立新清单的逻辑可以写成一个库函数,过滤逻辑可以作为一个参数传递给库函数:
“`
var array_helper = {
filter: function(list, filter)
{
var matches = [];
for(var x=0; x<list.length; x++)
{
if(filter(list[x]))
matches.push(list[x]);
}
return matches;
}
};
var marsChocolate = array_helper.filter(chocolateBars,
function(item){
return item.manufacturer==”Mars”
});
var naughtyList = array_helper.filter (childrenOfTheWorld,
function(item){
return item.naughtiness>50;
});
var niceList = array_helper.filter(childrenOfTheWorld,
function(item){
return item.naughtiness<=50;
});
“`
现在只需要为每份清单写个过滤器,简化了许多。如果在逻辑上出错的话,相对也好找许多。如果在库函数中的逻辑有问题的话,在代码中只需要在一个地方修改。另外,你还可以得到一份美味甜食的清单并且好孩子在圣诞节也会得到他们的礼物。
区分过滤函数这样的想法是如此有用,以至于它成为了流行的JS库的一部分(比如JQuery和Dojo)。它将作为JS 1.6标准的一部分被加入浏览器。然而同样的想法可以应用于许多不同的地方,来减少重复代码。
方法(methods)只不过是特殊的properties(该properties的值是函数)
Objects methods 在JavaScript中没什么特殊的。Methods也是properties,只不过methods的值是function(而不是string,number值).
“`
var sabby ={
name:”Sabby”,
species:”cat”,
hello :function(){alert(“hissss”);}
};
“`
这也是JavaScript语言设计者的聪明之处。因为这意味着他们不必做任何额外的事情来支持object methods。这也是JavaScript可以在没有类的情况下拥有objects的部分原因。
可以使JavaScript灵活,动态
JavaScript的许多灵活之处在于:可以把functions当做‘first class’对待。在javascript objects articles中的绝大多数例子都利用了‘把function当作regular object’这个特性。
在JavaScript中使用objects时采用的所有技巧都依赖这件事。simple objects,constructor functions和prototype都涉及到了‘把functions作为右值赋值给object的properties’。
它也使得JavaScript灵活,轻量级。其它语言中的一些常用的概念(如,命名空间,定制事件custom events,静态方法,扩展方法)都可以被模拟,因为在任何地方都可以创建function。
更多的阅读
我可以找到的关于‘把function当作regular object’的最好的参考是这篇文章functional javascript。它阐述了许多JavaScript拥有的functional language特性。
Raganwald有一篇有意思的文章,它解释了为什么‘把function看做object’是如此的有用。它和ruby,java做了对比,但是它的逻辑仍然是JavaScript。
接下来是什么?
匿名函数式使用function operator在运行时动态创建的函数。匿名函数和‘functions作为first class object’相互配合/作用,导致了JavaScript灵活和动态。
这篇文章是关于How javascript objects work的一部分。
This article is part of a set of related posts aboutHow javascript objects work.
本文翻译自:http://helephant.com/2008/08/19/functions-are-first-class-objects-in-javascript/
.