你可以在调用父函数之前将函数应用于参数吗?

时间:2014-02-11 20:53:08

标签: javascript

以下是原始资料的淡化示例:

Snippet 1

function slice(obj) {
    return Array.prototype.slice.call(obj,0);
}

function logEach(a) {
    a = slice(a);

    a.forEach(function(o) {
        console.log(o.nodeType);
    });
}

logEach(document.getElementsByTagName('*'));

我想知道在调用函数之前是否有某种方法将函数应用于参数'a',例如:

Snippet 2

//doesn't work

function logEach(a = slice(a)) {
    a.forEach( //... etc.

我知道以下内容是可行的,但我很想知道是否有办法实现上一个代码段(代码段2 ):

摘录3

//works
function slice(obj) {
    // ... etc.
}

function logEach(a) {
    a.forEach( // ... etc.

// then later on...

logEach(slice(document.getElementsByTagName('*')));

是否可以避免代码段3 ,并执行与代码段2 类似的操作? 此外,代码段2 中的尝试是否会被称为参数映射?

修改

谢谢p.s.w.g.提示我澄清一下:

在我的情况下,我将不止一次使用'a',所以我不想使用slice(a).forEach

2 个答案:

答案 0 :(得分:1)

如果您只在方法正文中使用slice(a)一次的结果(在a.forEach中),那么您可以像这样轻松地编写它:

function logEach(a) {
    slice(a).forEach(function(o) {
        console.log(o.nodeType);
    });
}

但是,如果您必须多次参考它,我可以看到有三个选项。您已经使用的简单方法:

function logEach(a) {
    a = slice(a);
    a.forEach(function(o) {
        console.log(o.nodeType);
    });
}

通过包装函数的内容:

function logEach(a) {
    (function(a) {
        a.forEach(function(o) {
            console.log(o.nodeType);
        });
    })(slice(a));
}

通过这样包裹整个:

function logEach(a) {
    a.forEach(function(o) {
        console.log(o.nodeType);
    });
}
logEach = (function(f) { 
    return function(a) { f(slice(a)); }; 
})(logEach);

这最后两个选项看起来很聪明,但它们只是让你的代码更难阅读,并没有真正提供很多好处。我建议保持简单。

答案 1 :(得分:0)

我不确定,如果这是你正在寻找的东西,但你可以写一些像功能装饰器:

//decorator logic

function sliceDec(func, args) {
    return func(slice(args[0]));
}

function decorate(func, decorator) {
    return function () {
        return decorator(func, arguments);
    }
}

//original code

function slice(obj) {
    return Array.prototype.slice.call(obj,0);
}

function logEach(a) {
    a.forEach(function(o) {
        console.log(o.nodeType);
    });
}

//apply decorator

var logEachSliced = decorate(logEach, sliceDec);

//call function

logEachSliced(document.getElementsByTagName('*'));

但是这只是基本上将你的函数包装在另一个函数中(除了这个之外你还会找到其他的方法),在第一个参数上调用slice,然后再处理原始函数。 / p>