abbshr.github.io
abbshr.github.io copied to clipboard
盘点ES5核心内容——函数篇
对于函数来说,ES5并没有多大改动,主要是因为JavaScript里的函数本身就足够强大。不过这里增加了一些简单却又十分实用的内容。
arguments实参对象
arguments标示符作为函数的实参列表,在ES5版本下有了改动。
arguments[i]
往往和实参互为别名,修改了二者中任意一个都会影响到另一个。而ES5移除了这一特性。
并且如果使用了"use stricts"
语句(严格模式),arguments会变成保留字,也就是说不能将arguments当做变量名使用,不能给其赋值。
bind
bind方法是一个我认为最棒的新特性之一,因为它大大增强了函数的功能。其用法很简单:
var newfunc = func.bind(obj, arg1, arg2, ...);
意思是将函数func
作为obj对象的方法(func的this
绑定至obj),并传入预设参数arg1,arg2...,最后返回一个经过配置后的新函数newfunc
。
这在函数式编程领域里被称作“Currying”(“柯里化”),也叫“惰性求值”或“部分求值”,是一种应用极广的概念。
该方法的用处很大,在实际应用中我们可用它来做函数的“预配置”、优化层层嵌套的代码结构:
function foo(s) {
var c, a;
// 这里使用了bind方法,
// 将c和a预填充到handler函数的前两个参数中
s.on('event', handler.bind(s, c, a));
}
function handler(c, a, err, arg) {
// handle arguments
arg.on('e', cb.bind(null, c, a, err, arg));
}
function cb(c, a, err, arg, arg1) {
// ...
}
如果不用绑定,代码就会变成这种模样:
function foo(s) {
var c, a;
s.on('event', function handler( err, arg) {
// handle c, a, err, arg
arg.on('e', function (arg1) {
// handle arg1, err, arg
});
});
}
这里看起来还算好,不过一旦嵌套和函数数量一多,代码结构就变混乱了
定义嵌套函数的原因往往是因为要使用外部作用域的变量,bind方法的这种技术允许函数不必嵌套定义,在闭包上调用bind,绑定需要的参数即可。
当然,bind并非ES5的专利。在ES3中就可以通过函数的apply方法和返回闭包来模拟这种技术。
不过经过bind返回的函数与模拟出来的bind返回值有本质上的不同:bind方法返回的函数,形参长度是原长度 - 预填充实参个数
,就像预填充的参数原本不存在一样。除此之外,返回的这个函数并** 不像其它函数一样包含prototype
属性 **,但如果将其作为构造函数调用,则实例化的对象将使用原始函数的prototype
属性作为自己的原型__proto__
。