复习
2、addHandler (),他的职责是分情况使用DOM0级方法、DOM2级方法或IE方法来添加事件。这个方法属于一个名字叫EventUtil的对象,可以使用这个对象来处理浏览器间的差异。addHandler() 方法接受3个参数:要操作的元素、时间名称和事件处理程序函数
。
3、removeHandler(),它也接受相同参数。这个方法的指责是移除之前添加的事件处理程序,无论该事件处理程序是采取什么方式添加到元素中的。如果其他方法无效,默认采用DOM0级方法
。
一个简单的引例:
// 普通的add函数
function add(x, y) {
return x + y
}
// 柯里化以后
function curryingAdd(x) {
return function (y) {
return x + y
}
}
add(1, 2) // 3
curryingAdd(1)(2) // 3
2个参数先用一个函数接收了第一个参数,再返回一个函数去处理第二个参数
,意思差不多就是封装了一层函数柯里化就被作为函数绑定的一部分去构造更复杂的bind()函数
function bind(fn, context){
var args = Array.prototype.slice.call(arguments, 2);
return function(){
var innerArgs = Array.prototype.slice.call(arguments);
var finalArgs = args.concat(innerArgs);
return fn.apply(context, finalArgs);
};
}
// 初步封装
var currying = function(fn) {
// args 获取第一个方法内的全部参数
var args = Array.prototype.slice.call(arguments, 1)
return function() {
// 将后面方法里的全部参数和args进行合并
var newArgs = args.concat(Array.prototype.slice.call(arguments))
// 把合并后的参数通过apply作为fn的参数并执行
return fn.apply(this, newArgs)
}
}
例子的解析:
第一个参数
是要进行柯里化的函数,其他参数
是要传入的值传入参数 1 表
示被返回的数组包含从第二个参数开始的所有参数newArgs数组将所有内部函数和外部函数的参数数组组合起来
apply
函数,此处考虑到了执行环境,用的this
函数柯里化的好处:
参数复用(正则表达式验证举例:
构造bind函数
// arguments 是一个对应于传递给函数的参数的类数组对象
function a(){
console.log(arguments);
}
a(); // Arguments [callee: ƒ, Symbol(Symbol.iterator): ƒ]
a(1,2,3); // Arguments(3) [1, 2, 3, callee: ƒ, Symbol(Symbol.iterator): ƒ]
2、 ==bind()==方法主要就是将函数绑定到某个对象,bind()会创建一个函数,函数体内的this对象的值会被绑定到传入bind()中的第一个参数的值
参数复用举例:
// 正常正则验证字符串 reg.test(txt)
// 函数封装后
function check(reg, txt) {
return reg.test(txt)
}
check(/\d+/g, 'test') //false
check(/[a-z]+/g, 'test') //true
// Currying后
function curryingCheck(reg) {
return function(txt) {
return reg.test(txt)
}
}
var hasNumber = curryingCheck(/\d+/g)
var hasLetter = curryingCheck(/[a-z]+/g)
hasNumber('test1') // true
hasNumber('testtest') // false
hasLetter('21212') // false
解析:这个正则校验只要用check函数就行了,但是如果要校验较多的话,需要将第一个参数进行复用,这样别的地方就能够直接调用hasNumber,hasLetter等函数,让参数能够复用
性能:
存取arguments对象
通常要比存取命名参数要慢一点arguments.length
的实现上是相当慢的通常比直接调用fn( … ) 稍微慢点
无论是在内存还是速度上
(一直有提到过这个点)——参考于https://www.jianshu.com/p/2975c25e4d71
摘录:JavaScript 中的
柯里化函数和绑定函数
提供了强大的动态函数创建功能
。使用 ==bind() 还是 curry()==要根据是否需要 object 对象响应来决定。它们都能用于创建复杂的算法和功能,当然两者都不应滥用,因为每个函数都会带来额外的开销
——《JavaScript高级程序设计》
// 实现一个add方法,使计算结果能够满足如下预期:
add(1)(2)(3) = 6;
add(1, 2, 3)(4) = 10;
add(1)(2)(3)(4)(5) = 15;
function add() {
// 第一次执行时,定义一个数组专门用来存储所有的参数
var _args = Array.prototype.slice.call(arguments);
// 在内部声明一个函数,利用闭包的特性保存_args并收集所有的参数值
var _adder = function() {
_args.push(...arguments);
return _adder;
};
// 利用toString隐式转换的特性,当最后执行时隐式转换,并计算最终的值返回
_adder.toString = function () {
return _args.reduce(function (a, b) {
return a + b;
});
}
return _adder;
}
add(1)(2)(3) // 6
add(1, 2, 3)(4) // 10
add(1)(2)(3)(4)(5) // 15
add(2, 6)(1) // 9