javascript - AMD 兼容的 JavaScript - 定义然后返回与只返回之间的任何区别

标签 javascript functional-programming

我想知道下面的有没有区别

define(
    function () {
        var Dog = {
             Bark: function () { alert('Woof! Woof! Woof!'); }
        };
    return Dog;
});

define(
    function () {
        return {
             Bark: function () { alert('Woof! Woof! Woof!'); }
        };
});

define(
    function () {
        function Dog()  {
             this.Bark = function () { alert('Woof! Woof! Woof!'); };
        };
    return Dog;
});

我认为就外观而言我更喜欢第一个,但我担心它与第二个和第三个不同,因为它会在返回之前进行评估...我意识到这是一种愚蠢的说法由于显然所有函数声明都需要在某个时候进行评估,但不知道 JavaScript 是如何在幕后工作的,因此我希望得到澄清。

最佳答案

第一和第二几乎是一样的。在第三个选项中可以注意到真正的区别。在这种情况下,您将返回一个可能使用 new 运算符调用的函数。尽管如此,第三种选择有一些缺点,使其成为最糟糕的选择:

首先,Dog 函数将创建一个新对象,并在内存中分配一个新的 Bark 函数。因此,就内存效率而言,此选项显然比其他两个选项差,因为其他两个选项仅创建一个分配给单个 Bark 函数的对象。回到第三种情况,您可以通过以下方式改进它:

define(
    function () {
        function Dog()  {
        };

        Dog.prototype.Bark = function () { alert('Woof! Woof! Woof!'); };
    return Dog;
});

通过这样做,您可以确保只有一个 Bark 函数的实例,所有使用 Dog 函数创建的对象都将共享该实例。

我注意到的另一个缺陷是您不能确保Dog 函数会创建一个对象。我的意思是,如果在没有 new 运算符的情况下调用它会发生什么?。它可能是像这样的非常讨厌的错误的原因:

var tommy = Dog();
tommy.Bark(); //Bark is undefined because tommy is equal to Dog's return value

所以要解决这个问题,您可以这样做:

define(
    function () {
        function Dog()  {
            if(!(this instanceof Dog)){
                return new Dog();
            }
        };

        Dog.prototype.Bark = function () { alert('Woof! Woof! Woof!'); };
    return Dog;
});

有了这个改进的第三个选项,选择取决于您要解决的问题。您是否需要该对象的多个实例?如果是这种情况,那么您应该使用改进的第三个​​选项,否则您可以使用第一个或第二个选项。

关于javascript - AMD 兼容的 JavaScript - 定义然后返回与只返回之间的任何区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25821515/

相关文章:

javascript - 显示来自 json 结果类型的图像数据

javascript - Magento 2 设计配置错误

javascript - JQuery:div 滑动以占据整页

haskell - 为什么惰性评估有用?

Java 8 通过签名推断方法引用解析,这是否损坏?

javascript - Raphaeljs : How to get the elements reference back using event. 目标?

正则表达式 : match text after pattern

F# WinRT 的优点

java - 如何以函数式风格多次写入 "if optional is empty, call next method returning optional, if not return this non-empty optional"?

error-handling - 如何访问:cause, :via and :trace keys of an exception in Clojure?