“伪造”JavaScript构造函数

时间:2011-09-23 01:18:48

标签: javascript function-prototypes

上下文

我正致力于提高我的JavaScript技能,而且我正在学习更多有关原型设计的知识。我想更好地理解这个问题中的代码以及它的任何限制或问题。

一件不明显的事情是定义更复杂的构造函数,它不仅仅是简单的初始化。我想要做的是拥有一个在创建Web服务时调用Web服务的类,而无需在初始化后立即调用方法。

我所做的是创建一个属性并为其分配一个自调用匿名方法。它似乎像我想要的那样工作,但我不知道是否有更好的方法。

守则

function AsyncOrderLine(productID) {

    var context = this;

    this.autoValue;
    this._productID = productID;
    this._asyncRequestComplete = false;


    this.hello = function () {
        alert("hello world");
    }

    this.constructor = (function () {
        context.hello();
        context.autoValue = "testing: " + productID + "(" +        context._asyncRequestComplete + ")";
    })()

}

结果

 var _asyncOrderLine = new AsyncOrderLine(1001);

警告显示:“Hello World”

 _asyncOrderLine.autoValue = testing: 1001(false)
 _asyncOrderLine.constructor = 'undefined'

在这种情况下,我希望一旦创建对象,构造函数就保持未定义。

问题

有更好的方法吗?使用这种方法可能会产生任何不可预见的副作用吗?

2 个答案:

答案 0 :(得分:3)

没有必要让这样的事情复杂化。您可以在构造函数中运行所需的任何代码:

function AsyncOrderLine(productID) {

    this.autoValue;
    this._productID = productID;
    this._asyncRequestComplete = false;

    this.hello = function () {
        alert("hello world");
    }

    // Run whatever arbitrary code you want...    
    this.hello();
    this.autoValue = "testing: " + productID + "(" + context._asyncRequestComplete + ")";
}

答案 1 :(得分:2)

正如其他人所说,构造函数属性没有理由。您可以在函数体中运行所需的任何代码,它将在对象初始化时运行。如果你想运行异步代码(比如ajax调用),那么你可能希望将一个完成函数传递给构造函数,这样对象的创建者就可以知道对象初始化的异步部分何时实际完成,因为它不会当对象从初始化返回时完成。这看起来像这样:

function function AsyncOrderLine(productID, fn) {
    // initialization code for the object here
    this._asyncRequestComplete = false;
    ...

    // kick of asychronous networking call here
    var context = this;
    $.getJSON(url, function(data) {
        // process the data response into our object here
        context.whatever = data;

        context._asyncRequestComplete = true;
        // call the completion function with `this` set to point to our object here 
        // so the creator of this object can know when the async part of
        // initialization is actually done
        fn.call(context);
    });
}

然后,调用者会做这样的事情:

var x = new AsyncOrderLine(id, function() {
    // can reference new object and it's methods and properties via "this"
    alert("orderLine object is now completely initialized");
});