AMD兼容JavaScript-定义然后返回与仅返回之间有什么区别

AMD兼容JavaScript-定义然后返回与仅返回之间有什么区别,javascript,functional-programming,Javascript,Functional Programming,我想知道以下两者之间是否有区别 define( function () { var Dog = { Bark: function () { alert('Woof! Woof! Woof!'); } }; return Dog; }); 及 及 我想我更喜欢第一款的外观,但我担心它与第二款和第三款的不同之处在于它在被退回之前会被评估。。。我意识到这是一种愚蠢的说法,因为显然所有函数声明都需要在某一点上进行求值,但我不知道

我想知道以下两者之间是否有区别

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


我想我更喜欢第一款的外观,但我担心它与第二款和第三款的不同之处在于它在被退回之前会被评估。。。我意识到这是一种愚蠢的说法,因为显然所有函数声明都需要在某一点上进行求值,但我不知道JavaScript在幕后是如何工作的,我希望澄清一下。

第一个和第二个示例实际上是相同的,在第一个示例中,您只需向读者发出“种类”的信号通过使用临时变量对对象进行命名来返回对象的名称。需要注意的一点是,该对象在所有需要该模块作为依赖项的模块中共享,因此是一种单例

第三个完全不同。如果
new Dog()
是此模块的别名,并且需要将此模块作为依赖项,则返回用于创建新对象(或其中多个对象)的函数。此函数是共享的,但不包含
Bark
或其他方法,其实例包含这些方法,但不共享这些方法

第三个也可以写成

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

函数的狗名甚至是可选的(但通常推荐用于可读性/调试)。

第一个和第二个几乎相同。在第三种选择中可以看到真正的区别。在这种情况下,您将返回一个可能使用新运算符调用的函数。尽管如此,第三种方案仍存在一些缺陷,使其成为最差的方案:

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

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

        Dog.prototype.Bark = function () { alert('Woof! Woof! Woof!'); };
    return Dog;
});
通过这样做,您可以确保只有一个树皮函数的实例将由使用Dog函数创建的所有对象共享

我注意到的另一个缺陷是,您没有确保Dog函数将创建一个对象。我的意思是,如果没有新的接线员调用它会发生什么?。它可能会导致像这样的非常讨厌的错误:

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;
});
使用此改进的第三个选项,选择取决于您试图解决的问题。您是否需要该对象的多个实例?如果是这样,那么您应该使用改进的第三个选项,否则您可以使用第一个或第二个选项

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;
});