1

可能重复:
Javascript:模块模式与构造函数/原型模式?

我想在 javaScript 中使用类仿真。这是一种偏好。

我一直在使用模块模式,但正在考虑只使用一个简单的函数对象,因为我可以创建公共和私有成员变量和函数。

下面是一个模拟类的函数对象的例子:

var input = document.getElementById('input');
var output = document.getElementById('output');

function test()
{
    var private_var = 'private_var';
    var private_func = function(){ return 'private_func';};
    var my = {};
    my.public_var = 'public_var';
    my.public_func = function(){ return 'public_func';};
    return my;
}

var object_test = new test();

alert( '| ' + object_test.public_var);
alert( '| ' + object_test.private_var);

alert( '| ' + object_test.public_func() );
alert( '| ' + object_test.private_func() );

​

是模拟类的模块模式的示例。

主要区别是什么?除了使隐含的全局显式的能力之外,还有吗?

4

2 回答 2

2

我可能误解了您所说的“函数对象”是什么意思,但据我所知,这些模式并不是真正可以互换的。

“模块模式”用于根据需要定义具有方法和属性的单个对象。一个很好的例子是Math自定义模块的一个简单例子只是一个Object实例:

var Module = { prop: 'prop' };
alert(Module.prop);

但是,通过这种方式,模块不是类。您无需致电new Math即可使用它们。您只需调用它们的方法 ( Math.abs()) 或获取/设置它们的属性 ( Math.PI)。

函数对象”——或者我所理解的构造函数——是最接近 JavaScript 所具有的“类”定义的概念。Object, String, Array. 这些和其他是为创建新实例而定义的构造函数。

您提供的代码段当然可以修改为构造函数:

// common-practice: constructors are named in PascalCase
function Test()
{
    var private_var = 'private_var';
    var private_func = function(){ return 'private_func';};

    this.public_var = 'public_var';
    this.public_func = function(){ return 'public_func';};
}

var object_test = new Test();

此外,这些模式甚至不一定是互斥的。将构造函数视为模块将允许定义类似“静态”的成员:

var Foo = (function () {
    function constructor() {
        var private_var = 'private_var';
        this.public_prop = 'public_prop';
    }

    var private_shared = 'private_shared';
    constructor.public_shared = 'public_shared';

    return constructor;
})();

alert(Foo.public_shared);     // 'public_shared' (module property)
alert(new Foo().public_prop); // 'public_prop'   (instance property)
于 2012-05-14T00:33:37.500 回答
0

我认为主要问题是您的 test() 函数仍然可以在没有 new 关键字的情况下被调用,并且在这种情况下,“this”的值将指向被调用者上下文(很可能是全局的),而不是 test( ) 内部闭包,导致不良影响,例如污染全局命名空间和不同的实例覆盖彼此的值。如果您将构造函数作为常规函数调用,解释器不会警告您。如果您的代码不打算与大量受众共享,并且您对构造函数使用一些命名约定,例如构造函数的 Test() 和常规函数的 test(),那么您仍然是安全的。它还有助于在代码中保持一些纪律,例如强制您在 return 语句中定义任何“公共”成员,所有成员都将相邻,作为一个干净的外观。这在大型代码库中很有趣。

于 2012-05-13T22:15:00.080 回答