我正在尝试在Lucee上的组件上使用合成访问器(虽然这个问题在ColdFusion上也是如此)。
Repro代码:
// Person.cfc
component accessors=true {
property firstName;
property lastName;
function init(firstName, lastName){
variables.firstName = arguments.firstName;
variables.lastName = arguments.lastName;
}
}
调用代码:
// person.cfm
person = new Person("Abigail", "Bowen");
writeDump(person);
注意我在这里使用合成访问器不,我纯粹是将参数值设置为同名的变量范围变量。
但是,当我运行此代码时,我看到了:
注意如何填充属性。这没有问题,但我显然不明白accessors
标志应该如何工作。我认为它只是为我合成一些存取方法(它有),但就是这样。
另请注意,如果我将CFC定义修改为而不是将访问者设置为true,那么转储显示为:
所以没有合成访问器(如预期的那样),但现在甚至没有显示属性(使用变量范围的值)。
我真的不明白“属性”和访问者设置的这种混淆吗?当然,访问者设置应该只影响是否创建了这些访问器方法?
如果我只是在其中一个平台上看到这个,我可能会把它归结为writeDump()
如何解释属性定义的变幻莫测。但是ColdFusion 11上的行为是一样的,所以看起来我的行为似乎有些不同。
任何人都能解释一下吗?有没有解释它的文档?如果不是......嗯...为什么不呢?
我的基本担忧是,属性值没有“正确”存储,一旦我实现了更多的代码,可能会给我带来问题。
更新:
至少在ColdFusion上,它似乎只是writeDump()
行为的变化,因为如果有属性的getter(无论是否设置了accessors
标志),那么属性值开始显示在转储中。但是Lucee的情况并非如此,所以那里仍有一个问号。
为了充分披露,这个问题是我在博客上提出的问题的摘要(“CFML: trying to understand accessors”)。复制是有意的,因为我的博客与本网站的受众不同。
答案 0 :(得分:10)
如果没有accessors=true
,则property
声明只是元数据。
使用accessors=true
,property
声明会触发getter / setter的生成,因此property
是variables
范围项和一对方法。
在构造函数中,您分配给variables
范围项 - 这与使用生成的setter相同 - 当CFML转储组件时,它会看到property
元数据和生成的getters,因此它显示了这些属性的值(因为它可以轻松安全地调用生成的getter)。
答案 1 :(得分:2)
这提出了ACF9。在此之前,属性文档中的定义是正确的:cfproperty声明是只是元数据。 (请参阅dump(getMetaData())。
在ACF9中,由于以下三个原因,这不完全正确:
使用accessors=true
为每个属性生成一个getter和setter,这些访问器读取和写入变量范围。 Cfproperty不仅仅是元数据,而且直接影响实例的行为。我喜欢将它视为真实OO属性的CF版本(偶然引入)。
cfdump 实现会根据属性声明更改其行为。如果property name;
已定义且方法getName()
存在(生成或实施),则会将其添加到转储的属性部分。
属性属性控制ORM。
由于我了解了这些功能,因此我设计了所有(公共)CFC,以便在转储时看起来正确,例如。当我想让它可见时,我只使用属性声明(+ getters)。此外,您可以实现仅由转储调用的方法,并且在实例化时不需要任何费用:
struct function getDebug(){
var x = doSomethingExpensive();
return { "Foo":f, "Bar":b, "Baz":x };
}
//or for a user iterator
string function getName(){
return qUsers.name[index];
}
我知道一些警告:
getDebug()
和getName()
)不适用于Railo / Lucee。property name="user" getter="false" setter="false";
它仍然在转储中可见 - 它应该被隐藏。