初始化javascript对象时,我想从函数执行中获取属性值。
到那时,我的对象看起来像这样:
request.resource.data.status == "new" || "viewed";
很明显,每次调用request.resource.data.status == "new" || request.resource.data.status == "viewed";
时,var objectName = function(){}
objectName.prototype.initialize = function() {
this.attribute = functionOne();
functionOne() {
return httpRequest();
}
}
都会被执行,并且因为它是异步函数,结果是instance.attribute
。我知道我需要getter和setter方法来实现这一点,但是这样做的正确方法是保持这个原型结构。
我尝试了以下
functionOne
但是当我拨打undefined
时,我收到了此错误:
objectName.prototype.initialize = function() {
this.attribute = undefined;
Object.defineProperty(this, "attribute", {
get: function() { return this.attribute },
set: functionOne()
});
}
答案 0 :(得分:0)
const objectName = function(){}
const objectName.prototype.initialize = function() {
this.attribute = undefined;
Object.defineProperty(this, "attribute", {
get: function() { return this.attribute },
set: functionOne()
});
}
const instance = new objectOne()
// This is infinitely recursive
instance.attribute
// because instance.attribute invokes attribute getter, which returns instance.attribute
// which invokes attribute getter, which returns instance.attribute, which invokes ......
// which "eventually" (actually within a few microseconds) overflows the stack
var objectName = function(){}
objectName.prototype.initialize = function() {
// Function called immediately when you initialize. Result is
// essentially cached to this.attribute.
this.attribute = functionOne();
// returns whatever httpRequest returns
function functionOne() {
return httpRequest();
}
}
由于httpRequest
显然是异步的,因此基本上有两种类型的回报:
.then
。instance.attribute.then(function(attr) {
doSomethingWithAttribute(attr)
})
// or
(async function() {
const attr = await instance.attribute
doSomethingWithAttribute(attr)
})()
var objectName = function(){}
objectName.prototype.initialize = function() {
// Notice I removed the parens here, this is no longer just about
// immediate invocation. We need a callback to give to httpRequest.
// so now attribute is basically an alias for functionOne. You could
// instead accept a callback to attribute and pass it on to functionOne.
this.attribute = functionOne;
functionOne(callback) {
return httpRequest(callback);
}
}
// Just for reference, but not relevant to the question, this is a more concise
// version of the function above assigned to objectName.prototype.initialize.
const equivalentInitialize = {
this.attribute = function(callback) {
return httpRequest(callback);
};
}
const instance = new objectOne()
instance.attribute(doSomethingWithAttribute)
为了使其更具可组合性,您可以将回调API包装在promise中。
var objectName = function(){}
objectName.prototype.initialize = function() {
this.attribute = new Promise(resolve => {
httpRequest(resolve)
})
}
const instance = new objectName()
instance.atttribute
.then(doSomethingWithAttribute)
更好的是,你可以忘记所有这些getter和setter废话,这在Javascript中甚至没有提供你认为它的安全性。
// Making some wild guesses about api here, since I don't what you are using
// here to make a request
httpRequest({ url, method, apiKey })
.then(doSomethingWithResponse)