在Javascript中模仿基于类的OOP构造函数

时间:2011-09-28 22:02:15

标签: javascript oop

快速注意: Javascript中的OOP是一个在Stackoverflow和其他地方被打死的主题,但我无法在任何地方找到这个具体问题。

Javascript对象中的“悬挂代码”一直困扰着我,因为它似乎打破了代码的流程。我所说的“挂码”的含义如下:

function newObject()
{
    var thisObject = this;

    // HANGING CODE DOING VARIOUS THINGS SUCH AS
    // $('#someDiv').click(function(){}); OR
    // var someObjectLiteral = {value:'value'};
}

我想通过执行以下操作来模仿基于类的OOP构造函数:

function newObject()
{
    var thisObject = this;

    function construct()
    {
        //WHAT USED TO BE HANGING CODE
    }

    construct();
}

对于第二种方法,以下任何一项都是正确的或可能是真的:

  1. 明显更慢
  2. 在某些情况下根本不起作用
  3. 打破了正确的编码习惯
  4. 调试起来会更难
  5. 有一种更好的方法可以达到相同的效果
  6. 谢谢。

2 个答案:

答案 0 :(得分:2)

在内部函数中包装代码本身并没有错。您唯一需要注意的是,您不能在其他函数中使用this(您需要使用中间变量,例如thisObject

完成了这项工作之后,我发现“悬挂代码”(至少在您的示例中显示的类型)完全没有问题。像Java这样的语言可能已经训练你将所有放在一个类中,但是在Javascript中,你只需要在你明确想要利用继承或多态的情况下进行oop-things-up。 / p>

你可能需要稍微远离oop心态。例如,在您的情况下,新对象构造函数中的“挂起代码”可能看起来很糟糕,但我只是将该函数重命名为“addClickHandler”或“setLiterals”并将其称为一天。

答案 1 :(得分:1)

您可以使用MooTools Class之类的东西,其中比使用“悬挂”代码的方法慢。这主要是因为MooTools类具有与其“Native”结构相关的开销。很多你可能不会,也可能不会需要的东西。听起来你想要一些直截了当的东西。

您可以执行以下操作:

var Klass = function(attrs) {
    var key, newClass;

    attrs = attrs || {};

    newClass = function() {
        if(this.init) {
            this.init.apply(this, Array.prototype.slice.call(arguments));
        }
    };

    for(key in attrs) {
        newClass.prototype[key] = attrs[key]
    }

    return newClass;
};

然后,您可以执行以下操作:

var Person = new Klass({
    init: function(name, bg) {
        this.name = name;
        document.getElementById('container').styles.background = bg;
    },

    speak: function() {
        'I am ' + this.name;
    }
});

var tim = new Person('tim', 'blue');
// background now blue
tim.speak();
// 'I am tim'

var jane = new Person('jane', 'purple');
// background now purple
jane.speak();
// 'I am jane'

因此,当您创建类的新实例时,此代码将触发init()。传递任何论据。您可以在其中放置“挂起”代码。节点,由于原型的工作方式,这不允许您创建新实例的新实例。而且您需要进一步更改它以允许构建父类等内容。但这是构建类结构的一种非常简单的方法。

这应该适合你想要的。如果你遇到“不能做”的事情,肯定会有办法纠正这个问题。你可能只需要修改代码。正如我在前一段中所说的那样。由于一个类基本上是一个返回的函数,因此会产生一个新的实例。但没有什么太重要的。至于最佳实践,我会说它并不坏。有许多JS库具有相当广泛的类结构供您使用。而且很多人都使用课程。但是由于它们不是真正的原生JS类型,因此存在并且将会使用它们的争论。