Coldfusion 组件上访问器的意外行为=true
我试图在Lucee上的组件上使用综合访问器(尽管这个问题在ColdFusion上似乎也一样) 复制代码:Coldfusion 组件上访问器的意外行为=true,coldfusion,cfml,lucee,Coldfusion,Cfml,Lucee,我试图在Lucee上的组件上使用综合访问器(尽管这个问题在ColdFusion上似乎也一样) 复制代码: // Person.cfc component accessors=true { property firstName; property lastName; function init(firstName, lastName){ variables.firstName = arguments.firstName; variable
// 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的情况并非如此,因此仍然存在一个问号
为了充分披露,这个问题是我在我的博客(“”)上提出的一个问题的总结。复制是故意的,因为我的博客与本网站的读者不同。如果没有
accessors=true
,那么属性声明就只是元数据
使用accessors=true
,属性
声明触发getter/setter的生成,因此属性
既是变量
范围项又是一对方法
在构造函数中,您将变量
范围项赋值——这与使用生成的setter相同——当CFML转储组件时,它会看到属性
元数据和生成的getter,因此它会显示这些属性的值(因为它可以轻松安全地调用生成的getter)。这是ACF9提出的。在此之前,属性文档中的定义是正确的:cfproperty声明是元数据(请参阅dump(getMetaData())
在ACF9中,这不再完全正确,原因有三:
使用accessors=true
为每个属性生成一个getter和setter,这些访问器从变量范围读取和写入。Cfproperty不再只是元数据,而是直接影响实例的行为。我喜欢将其视为真正OO属性的CF版本(偶然介绍)
cfdump实现根据属性声明更改其行为。如果定义了property name;
,并且方法getName()
存在(生成或实现),则将其添加到转储的属性部分
属性属性控制ORM
因为我了解了这些特性,所以我设计了所有(公共)CFC,使其在转储时看起来正确,例如,我只在希望其可见时使用属性声明(+getter)。此外,您可以实现仅由转储调用的方法,并且在实例化时不花费任何成本:
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];
}
我知道一些警告:
- ACF总是从转储调用getter,而在Railo/Lucee中显示变量范围中的值。因此,上述示例(
getDebug()
和getName()
)在Railo/Lucee上不起作用
- 如果getter不是公共的或导致错误,则转储将显示属性的空字符串(此处不确定,可能是缺少属性)
- 扩展CFC中的属性声明被忽略。在使用继承的ORM实体中,这让我有些头疼,因为不允许您两次声明属性。因此,您不可能显示在基本CFC中定义的属性
- Railo/Lucee似乎忽略了属性类型。所有访问器只接受并返回字符串(请参见getMetaData()
- 次要:在ACF中,当您激活访问器,但停用属性的getter和setter时:
property name=“user”getter=“false”setter=“false”;
它在转储中仍然可见-应该隐藏它
是的,这是def的外观(请参阅我的更新)。Lucee的行为与ColdFusion的行为略有不同。我猜Lucee查找设置和方法;CF只查找方法。区别完全在于转储行为,而不是其他。这只是CF9构造函数行为的一个例子吗?在CF9中,init()成为一个真正的构造函数,如果你有一个,它会在你使用new关键字时被自动调用,就像在Java中一样。如果你将init()重命名为Person(),同样的事情也会发生。如果你是正确的,那么如果你使用了其他函数名,它也会发生,但实际上没有。只有当CF作为构造函数运行时才会发生这种情况。