【问题标题】:how to do overloading in javascript? [duplicate]如何在javascript中进行重载? [复制]
【发布时间】:2015-07-12 14:03:18
【问题描述】:

我正在尝试学习 javascript 中的重载。我用谷歌搜索了它,有一种方法可以使用arguments 长度,然后添加开关条件。但我对那样做不感兴趣。其实我看到了一个很好的答案 Function overloading in Javascript - Best practices 但他没有根据他的观点给出任何重载的例子。那么,如何在 javascript 中进行重载。

这是我的代码。我需要使用上述解决方案重载一个方法。他说这样做:http://jsfiddle.net/m84fg8ac/

function foo(a, b, opts) {

}


foo(1, 2, {"method":"add"});
foo(3, 4, {"test":"equals", "bar":"tree"});

我将如何在我的代码中实现这一点?

function foo(a, b, opts) {

}

function foo(a) {
    console.log("one argument pass");
}

function foo(a, b) {
    console.log("two argument pass");
}

function foo(a, b, c) {
    console.log("three argument pass");
}


foo(1);
foo(1,2);
foo(1,2,3);

这里写着 使用参数进行函数重载的最好方法是不检查参数长度或类型;检查类型只会让你的代码变慢,你会享受到数组、空值、对象等的乐趣。 大多数开发人员所做的是将对象作为其方法的最后一个参数。这个对象可以容纳任何东西。

【问题讨论】:

  • JS 不支持重载,所以我不确定你希望你的第二个 sn-p 如何工作。每次您重新声明 foo 时,之前的声明都会丢失。
  • 你能解释一下为什么你不想检查arguments的长度吗?问如何做某事,却任意限制做某事的一种方式,似乎有点奇怪。换句话说,是什么让您的问题与您所链接的问题不同?
  • @user944513 我没有提出任何答案。我提议将这个问题作为一个副本来结束,因为它不会问任何上一个问题中没有问的问题。感觉该问题的答案没有提供足够的信息并不是提出新问题的充分理由。
  • 这绝对是重复的,因为 user944513 一直引用之前发布的问题,要求“那个解决方案”。
  • @user944513 如果您的方法根据参数的数量做完全不同的事情,那么创建 3 个不同的函数会更好吗?如果您的方法对每个方法都几乎相同,为什么不将其参数长度抽象化呢?如果您只想设置默认值,只需一种方法并设置默认值!

标签: javascript overloading


【解决方案1】:

JavaScript 在调用函数时不需要传递所有参数,因此可以像这样实现重载:

function foo(a, b, c) {
    if (c === undefined) {
        if (b === undefined) {
            if (a === undefined) console.log("zero argument pass");
            else console.log("one argument pass");
        }
        else console.log('two argument pass');
    }
    else console.log('three argument pass');
}

【讨论】:

【解决方案2】:

来自http://ejohn.org/blog/javascript-method-overloading/

var namespace = {};

function addMethod(object, name, fn) {
    var old = object[name];
    object[name] = function() {
        if (fn.length === arguments.length) {
            return fn.apply(this, arguments);
        } else if (typeof old === 'function') {
            return old.apply(this, arguments);
        }
    };
}

addMethod(namespace, "foo", function (a) {
    console.log("one argument pass");
});

addMethod(namespace, "foo", function (a, b) {
    console.log("two arguments pass");
});

addMethod(namespace, "foo", function (a, b, c) {
    console.log("three argument pass");
});

namespace.foo(1);
namespace.foo(1, 2);
namespace.foo(1, 2, 3);

var namespace = {};

function addMethod(object, name, fn) {
    var old = object[name];
    object[name] = function() {
        if (fn.length === arguments.length) {
            return fn.apply(this, arguments);
        } else if (typeof old === 'function') {
            return old.apply(this, arguments);
        }
    };
}

addMethod(namespace, "foo", function (a) {
    document.write("one argument pass<br/>");
});

addMethod(namespace, "foo", function (a, b) {
    document.write("two arguments pass<br/>");
});

addMethod(namespace, "foo", function (a, b, c) {
    document.write("three argument pass<br/>");
});

namespace.foo(1);
namespace.foo(1, 2);
namespace.foo(1, 2, 3);

【讨论】:

    【解决方案3】:

    检查元数

    function foo(a, b, opts) {
        if (arguments.length === 1) {
            console.log("one argument pass")
        } else if (arguments.length === 2) {
            console.log("two argument pass")
        } else if (arguments.length === 3) {
            console.log("three argument pass")
        }
    }
    
    foo(1); // "one argument pass"
    foo(1,2); // "two argument pass"
    foo(1,2,3); // "three argument pass"
    

    http://jsfiddle.net/m84fg8ac/2/

    【讨论】:

    • 我需要使用这个解决方案stackoverflow.com/questions/456177/…
    • 为什么要克隆arguments 对象?还要检查github.com/petkaantonov/bluebird/wiki/…
    • @user944513 您一直链接到一个问题并说您需要使用该“解决方案”。你在说什么解决方案?
    • @user944513 这是一个问题的链接,有 20 多个不同的答案,而不是单一的“解决方案”。
    • @user944513 这是一种避免任何函数重载的方法。您将任何可选参数替换为应该传递给{} 的单个参数。您在 {} 中查找所有可选参数。
    猜你喜欢
    • 1970-01-01
    • 2012-08-06
    • 2016-11-09
    • 2010-09-25
    • 2018-07-26
    • 2011-01-13
    • 1970-01-01
    • 1970-01-01
    • 2011-02-07
    相关资源
    最近更新 更多