“伪造” JavaScript构造

问题描述:

语境“伪造” JavaScript构造

我的工作在提高我的JavaScript技能,我更多地了解原型。我想更好地理解这个问题中的代码以及它的任何限制或问题。

有一点不明显的是定义了比简单初始化更复杂的构造函数。我想要做的是创建一个类,该类在调用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

一般来说,你做了什么是好的。你不需要暴露一个名为构造函数的属性..你可以只在AsyncOrderLine中运行该函数。然后你可以避免给_instance.constructor赋值undefined。但是,这个问题非常广泛,很难正式回答。有无数的方法来完成你所做的。 – keparo

+1

“*我所做的是创建一个属性并为其指定一个自我调用匿名方法。*” - 为什么要这样做? –

+0

@ŠimeVidas我打算把它叫做构造函数以外的东西,并给它赋值。我将其重命名为该问题。问题是我想创建对象时运行一个函数。 – dmck

没有必要使这样的事情复杂化。你可以在你的构造函数里运行你想要的代码:

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

正如其他人所说的,没有理由构造函数属性。你可以在函数体中运行你想要的任何代码,它会在对象初始化的时候运行。如果你想运行异步代码(比如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"); 
});