我很难从“Javascript Ninja的秘密”一书中把握这个例子。
这个概念是你有一个addMethod函数,它允许你将同一个方法的多个版本传递给一个对象,区别在于这些方法接受的参数数量,它们处理这些参数的内容。
我没有得到这背后的“机制”。在检查器中,我只看到第一种方法,但是当我使用不同的参数运行find
方法时,它仍然设法使用它的正确变体。但是怎么样?在使用三个版本运行addMethod
后,这些方法如何仍然可用?
你能帮我理解一下吗?
将方法绑定到对象的函数:
addMethod = function(object, name, fn) {
var old;
old = object[name];
return object[name] = function() {
if (fn.length === arguments.length) {
return fn.apply(this, arguments);
} else if (typeof old === 'function') {
return old.apply(this, arguments);
}
};
};
然后你可以分配相同的函数名作为对象的属性,如下所示:
addMethod(ninjas, 'find', function() {
return this.values;
});
addMethod(ninjas, 'find', function(name) {
var ninja, _i, _len, _ref, _results;
_ref = this.values;
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
ninja = _ref[_i];
if (ninja.indexOf(name) !== -1) {
_results.push(ninja);
}
}
return _results;
});
addMethod(ninjas, 'find', function(first, last) {
var ninja, _i, _len, _ref, _results;
_ref = this.values;
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
ninja = _ref[_i];
if (ninja === ("" + first + " " + last)) {
_results.push(ninja);
}
}
return _results;
});
答案 0 :(得分:3)
每次重载函数时,都会使用旧函数并将其替换为检查要使用哪个重载的函数。
添加第一个函数后,您的代码(粗略地)与:
相同ninjas.find = function(){
if (arguments.length === 1) {
// code for first overload
}
}
添加第二个函数后,您的代码与:
相同ninjas.find = function(){
if (arguments.length === 2) {
// code for second overload
} else {
if (arguments.lenght === 1) {
// code for first overload
}
}
}
每次添加另一个重载时,都会在前一个代码周围添加另一级别的检查。
答案 1 :(得分:1)
addMethod = function(object, name, fn) {
var old;
old = object[name];
return object[name] = function() {
if (fn.length === arguments.length) {
return fn.apply(this, arguments);
} else if (typeof old === 'function') {
return old.apply(this, arguments);
}
};
};
让我们开始吧:
object[name] = function ()
为对象分配一个函数。
例如:
ninjas["find"] = function()
然后它使用第一个匹配将命名的参数数量(fn.length)与传入的参数数量(arguments.length)进行比较。这样它就可以确定需要调用哪个函数。
如果第一个条件不满足,则检查旧函数的类型。如果它是一个函数,那么它只是将参数应用于旧函数。
fn.length
指的是传递的最外层函数。
&安培;
arguments.length
指的是最内部函数长度的参数。
那么压倒一切有效吗?
正如您所看到的,我们每次调用addMethod
时都会将函数引用到名为old
的变量。然后根据if
条件结果,它将覆盖上一个函数与较新的函数。
如果我们没有匹配变量的旧函数,它将返回undefined。
例如:
-----------------------------------------------------------------------
function - fn.length == arguments.length
------------------------------------------------------------------------
ninjas.find() - (0 == 0), uses `function ()`
ninjas.find("Rias") - (1 == 1), uses `function (name)`
ninjas.find("Mohamed", "Rias") - (2 == 2), uses `function (first, last)`
ninjas.find("Mohamed", "Rias", "A") - (? == 3), no match, returns `undefined`