| 最近整理ASP/VBScript代码,发现过去的一个ASP实现的MVC框架,可惜是个半成品,效率也成问题,不过发现里面有些我写的代码,感觉还稍稍可以拿出来见人,于是今天作此文以记之。 说是ASP,其实和VBScript也脱不了干系,VBScript语言传承于Visual Basic,VB的语法灵活度已经不尽如人意了,VBS作为其子集可想而知。神马反射、自省等先进的技术,微软在.NET中才引入。作为被抛弃的技术,也不奢望微软能够提供支持,于是顽固守旧的程序员只有绞尽脑汁的去模仿实现一些类似的功能。 好吧,我承认很长一段时间我就是顽固守旧派中的一员,今天介绍的就是其中的一项功能,动态创建一个属性对象,属性对象姑且这么称呼,也就是说动态创建的对象只包含属性(Properties)。 下面贴出实现代码供大家参考:
 复制代码 代码如下:'
 ' ASP/VBScript Dynamic Object Generator
 ' Author: WangYe
 ' For more information please visit
 'nbsp;nbsp;nbsp;nbsp;
 ' This code is distributed under the BSD license
 '
 Const PROPERTY_ACCESS_READONLY = 1
 Const PROPERTY_ACCESS_WRITEONLY = -1
 Const PROPERTY_ACCESS_ALL = 0
 
 Class DynamicObject
 nbsp;nbsp;nbsp; Private m_objProperties
 nbsp;nbsp;nbsp; Private m_strName
 
 nbsp;nbsp;nbsp; Private Sub Class_Initialize()
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; Set m_objProperties = CreateObject("Scripting.Dictionary")
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; m_strName = "AnonymousObject"
 nbsp;nbsp;nbsp; End Sub
 
 nbsp;nbsp;nbsp; Private Sub Class_Terminate()
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; If Not IsObject(m_objProperties) Then
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; m_objProperties.RemoveAll
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; End If
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; Set m_objProperties = Nothing
 nbsp;nbsp;nbsp; End Sub
 
 nbsp;nbsp;nbsp; Public Sub setClassName(strName)
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; m_strName = strName
 nbsp;nbsp;nbsp; End Sub
 
 nbsp;nbsp;nbsp; Public Sub add(key, value, access)
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; m_objProperties.Add key, Array(value, access)
 nbsp;nbsp;nbsp; End Sub
 
 nbsp;nbsp;nbsp; Public Sub setValue(key, value, access)
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; If m_objProperties.Exists(key) Then
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; m_objProperties.Item(key)(0) = value
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; m_objProperties.Item(key)(1) = access
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; Else
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; add key,value,access
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; End If
 nbsp;nbsp;nbsp; End Sub
 
 nbsp;nbsp;nbsp; Private Function getReadOnlyCode(strKey)
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; Dim strPrivateName, strPublicGetName
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; strPrivateName = "m_var"  strKey
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; strPublicGetName = "get"  strKey
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; getReadOnlyCode = _
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; "Public Function "  strPublicGetName  "() :"  _
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; strPublicGetName  "="  strPrivateName  " : "  _
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; "End Function : Public Property Get "  strKey  _
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; " : "  strKey  "="  strPrivateName  " : End Property : "
 nbsp;nbsp;nbsp; End Function
 
 nbsp;nbsp;nbsp; Private Function getWriteOnlyCode(strKey)
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; Dim pstr
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; Dim strPrivateName, strPublicSetName, strParamName
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; strPrivateName = "m_var"  strKey
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; strPublicSetName = "set"  strKey
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; strParamName = "param"  strKey
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; getWriteOnlyCode = _
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; "Public Sub "  strPublicSetName  "("  strParamName  ") :"  _
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; strPrivateName  "="  strParamName  " : "  _
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; "End Sub : Public Property Let "  strKey  "("  strParamName  ")"  _
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; " : "  strPrivateName  "="  strParamName  " : End Property : "
 nbsp;nbsp;nbsp; End Function
 
 nbsp;nbsp;nbsp; Private Function parse()
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; Dim i, Keys, Items
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; Keys = m_objProperties.Keys
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; Items = m_objProperties.Items
 
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; Dim init, pstr
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; init = ""
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; pstr = ""
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; parse = "Class "  m_strName  " :"  _
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; "Private Sub Class_Initialize() : "
 
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; Dim strPrivateName
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; For i = 0 To m_objProperties.Count - 1
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; strPrivateName = "m_var"  Keys(i)
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; init = init  strPrivateName  "="""  _
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; Replace(CStr(Items(i)(0)), """", """""")  """:"
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; pstr = pstr  "Private "  strPrivateName  " : "
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; If CInt(Items(i)(1)) gt; 0 Then ' ReadOnly
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; pstr = pstr  getReadOnlyCode(Keys(i))
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; ElseIf CInt(Items(i)(1)) lt; 0 Then ' WriteOnly
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; pstr = pstr  getWriteOnlyCode(Keys(i))
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; Else ' AccessAll
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; pstr = pstr  getReadOnlyCode(Keys(i))  _
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; getWriteOnlyCode(Keys(i))
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; End If
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; Next
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; parse = parse  init  "End Sub : " nbsp; pstr  "End Class"
 nbsp;nbsp;nbsp; End Function
 
 nbsp;nbsp;nbsp; Public Function getObject()
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; Call Execute(parse)
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; Set getObject = Eval("New "  m_strName)
 nbsp;nbsp;nbsp; End Function
 
 nbsp;nbsp;nbsp; Public Sub invokeObject(ByRef obj)
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; Call Execute(parse)
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; Set obj = Eval("New "  m_strName)
 nbsp;nbsp;nbsp; End Sub
 End Class
 
 对于属性对象分别提供了Property直接访问模式和set或者get函数访问模式,当然我还提供了三种权限控制,在add方法中使用,分别是PROPERTY_ACCESS_READONLY(属性只读)、PROPERTY_ACCESS_WRITEONLY(属性只写)和PROPERTY_ACCESS_ALL(属性读写),你可以像下面这样使用(一个例子):复制代码 代码如下:
 Dim DynObj
 Set DynObj = New DynamicObject
 nbsp;nbsp;nbsp; DynObj.add "Name", "WangYe", PROPERTY_ACCESS_READONLY
 nbsp;nbsp;nbsp; DynObj.add "HomePage", "http://jb51.net", PROPERTY_ACCESS_READONLY
 nbsp;nbsp;nbsp; DynObj.add "Job", "Programmer", PROPERTY_ACCESS_ALL
 nbsp;nbsp;nbsp; '
 nbsp;nbsp;nbsp; ' 如果没有setClassName,
 nbsp;nbsp;nbsp; ' 新创建的对象将会自动命名为AnonymousObject
 nbsp;nbsp;nbsp; ' 但是如果创建多个对象,就必须指定名称
 nbsp;nbsp;nbsp; ' 否则就可能引起对象名重复的异常
 nbsp;nbsp;nbsp; DynObj.setClassName "User"
 
 nbsp;nbsp;nbsp; Dim User
 nbsp;nbsp;nbsp; Set User = DynObj.GetObject()
 nbsp;nbsp;nbsp; ' 或者 DynObj.invokeObject User
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; Response.Write User.Name
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; ' Response.Write User.getName()
 nbsp;Response.Write User.HomePage
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; ' Response.Write User.getHomePage()
 nbsp;Response.Write User.Job
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; ' Response.Write User.getJob()
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; ' 改变属性值nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; User.Job = "Engineer"
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; ' User.setJob "Engineer"
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; Response.Write User.getJob()nbsp;nbsp;nbsp; Set User = Nothing
 
 Set DynObj = Nothing
 其原理很简单,就是通过给定的Key-Value动态生成VBS Class脚本代码,然后调用Execute执行以便于将这段代码加入到代码上下文流中,最后再通过Eval新建这个对象。
 好了,就介绍到这里,今后我可能还会陆续公开一些Classic ASP的相关技巧代码。 2012年11月7日更新 修复从旧项目移植过来导致的BUG。 修复了一些Bug增加了一些特性,我先把最新的代码贴出来供大家参考: 复制代码 代码如下:'' ASP/VBScript Dynamic Object Generator
 ' Author: WangYe
 ' For more information please visit
 'nbsp;nbsp;nbsp;nbsp;
 ' This code is distributed under the BSD license
 '
 ' UPDATE:
 'nbsp;nbsp; 2012/11/7
 'nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; 1. Add variable key validator.
 'nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; 2. Add hasattr_ property for determine
 'nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; if the property exists.
 'nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; 3. Add getattr_ property for get property
 'nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; value safety.
 'nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; 4. Class name can be accessed by ClassName_ property.
 'nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; 5. Fixed some issues.
 '
 Const PROPERTY_ACCESS_READONLY = 1
 Const PROPERTY_ACCESS_WRITEONLY = -1
 Const PROPERTY_ACCESS_ALL = 0
 
 Class DynamicObject
 nbsp;nbsp;nbsp; Private m_objProperties
 nbsp;nbsp;nbsp; Private m_strName
 nbsp;nbsp;nbsp; Private m_objRegExp
 
 nbsp;nbsp;nbsp; Private Sub Class_Initialize()
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; Set m_objProperties = CreateObject("Scripting.Dictionary")
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; Set m_objRegExp = New RegExp
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; m_objRegExp.IgnoreCase = True
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; m_objRegExp.Global = False
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; m_objRegExp.Pattern = "^[a-z][a-z0-9]*$"
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; m_strName = "AnonymousObject"
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; m_objProperties.Add "ClassName_", _
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; Array(m_strName, PROPERTY_ACCESS_READONLY)
 nbsp;nbsp;nbsp; End Sub
 
 nbsp;nbsp;nbsp; Private Sub Class_Terminate()
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; Set m_objRegExp = Nothing
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; If IsObject(m_objProperties) Then
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; m_objProperties.RemoveAll
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; End If
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; Set m_objProperties = Nothing
 nbsp;nbsp;nbsp; End Sub
 
 nbsp;nbsp;nbsp; Public Sub setClassName(strName)
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; If Not m_objRegExp.Test(strName) Then
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; ' Skipped Invalid Class Name
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; ' Raise
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; Exit Sub
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; End If
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; m_strName = strName
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; m_objProperties("ClassName_") = _
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; Array(m_strName, PROPERTY_ACCESS_READONLY)
 nbsp;nbsp;nbsp; End Sub
 
 nbsp;nbsp;nbsp; Public Sub add(key, value, access)
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; If Not m_objRegExp.Test(key) Then
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; ' Skipped Invalid key
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; ' Raise
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; Exit Sub
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; End If
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; If key = "hasattr_" Then key = "hasattr__"
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; If key = "ClassName_" Then key = "ClassName__"
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; 'Response.Write key
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; m_objProperties.Add key, Array(value, access)
 nbsp;nbsp;nbsp; End Sub
 
 nbsp;nbsp;nbsp; Public Sub setValue(key, value, access)
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; If m_objProperties.Exists(key) Then
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; m_objProperties.Item(key)(0) = value
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; m_objProperties.Item(key)(1) = access
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; Else
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; add key,value,access
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; End If
 nbsp;nbsp;nbsp; End Sub
 
 nbsp;nbsp;nbsp; Private Function getReadOnlyCode(strKey)
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; Dim strPrivateName, strPublicGetName
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; strPrivateName = "m_var"  strKey
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; strPublicGetName = "get"  strKey
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; getReadOnlyCode = _
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; "Public Function "  strPublicGetName  "() :"  _
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; strPublicGetName  "="  strPrivateName  " : "  _
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; "End Function : Public Property Get "  strKey  _
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; " : "  strKey  "="  strPrivateName  _
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; " : End Property : "
 nbsp;nbsp;nbsp; End Function
 
 nbsp;nbsp;nbsp; Private Function getWriteOnlyCode(strKey)
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; Dim pstr
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; Dim strPrivateName, strPublicSetName, strParamName
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; strPrivateName = "m_var"  strKey
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; strPublicSetName = "set"  strKey
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; strParamName = "param"  strKey
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; getWriteOnlyCode = _
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; "Public Sub "  strPublicSetName  _
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; "("  strParamName  ") :"  _
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; strPrivateName  "="  strParamName  " : "  _
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; "End Sub : Public Property Let "  strKey  _
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; "("  strParamName  ")"  _
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; " : "  strPrivateName  "="  strParamName  _
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; " : End Property : "
 nbsp;nbsp;nbsp; End Function
 
 nbsp;nbsp;nbsp; Private Function parse()
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; Dim i, Keys, Items
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; Keys = m_objProperties.Keys
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; Items = m_objProperties.Items
 
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; Dim init, pstr
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; init = ""
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; pstr = ""
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; parse = "Class "  m_strName  " :"  _
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; "Private Sub Class_Initialize() : "
 
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; Dim strPrivateName, strAvailableKeys
 
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; For i = 0 To m_objProperties.Count - 1
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; strPrivateName = "m_var"  Keys(i)
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; init = init  strPrivateName  "="""  _
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; Replace(CStr(Items(i)(0)), """", """""")  """:"
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; pstr = pstr  "Private "  strPrivateName  " : "
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; strAvailableKeys = strAvailableKeys  Keys(i)  ","
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; If CInt(Items(i)(1)) gt; 0 Then ' ReadOnly
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; pstr = pstr  getReadOnlyCode(Keys(i))
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; ElseIf CInt(Items(i)(1)) lt; 0 Then ' WriteOnly
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; pstr = pstr  getWriteOnlyCode(Keys(i))
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; Else ' AccessAll
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; pstr = pstr  getReadOnlyCode(Keys(i))  _
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; getWriteOnlyCode(Keys(i))
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; End If
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; Next
 
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; init = init  "m_strAvailableKeys = Replace("","  _
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; strAvailableKeys  """, "" "", """") : "
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; Dim hasstmt
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; hasstmt = "Private m_strAvailableKeys : "  _
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; "Public Function hasattr_(ByVal key) : "  _
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; "hasattr_ = CBool(InStr(m_strAvailableKeys,"  _
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; " "",""  key  "","") gt; 0) : "  _
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; "End Function : "  _
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; "Public Function getattr_(ByVal key, ByVal defaultValue) : "  _
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; "If hasattr_(key) Then : getattr_ = Eval(key) : "  _
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; "Else : getattr_ = defaultValue : End If : "  _
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; "End Function : "
 
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; parse = parse  init  "End Sub : "  _
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; hasstmt  pstr  "End Class"
 nbsp;nbsp;nbsp; End Function
 
 nbsp;nbsp;nbsp; Public Function getObject()
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; 'Response.Write parse
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; Call Execute(parse)
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; Set getObject = Eval("New "  m_strName)
 nbsp;nbsp;nbsp; End Function
 
 nbsp;nbsp;nbsp; Public Sub invokeObject(ByRef obj)
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; Call Execute(parse)
 nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp; Set obj = Eval("New "  m_strName)
 nbsp;nbsp;nbsp; End Sub
 End Class
 需要注意的几个新特性:
 1. 增加了类名和属性名验证措施,防止畸形的类名或者属性名导致动态生成的代码出现语法错误。不过处理的方式是直接忽略,本来想Raise异常的,但考虑到VBS对异常处理不是很好的,所以采取忽略策略: ' 有效的类名或属性名必须以字母开头复制代码 代码如下:Dim DynObj
 Set DynObj = New DynamicObject
 nbsp;nbsp;nbsp; DynObj.setClassName "1User" ' 此句将被忽略,因为类名不能以数字开始
 nbsp;nbsp;nbsp; ' 下面这句也会被忽略,因为属性名不能以特殊符号开始
 nbsp;nbsp;nbsp; DynObj.add "%Name", "WangYe", PROPERTY_ACCESS_READONLY
 Set DynObj = Nothing
 2. 对于动态对象增加了hasattr_方法,该属性用于检测此对象是否支持相应的属性,可以在访问一个属性前先确定该对象是否支持此属性:
 复制代码 代码如下:
 Dim DynObj
 Set DynObj = New DynamicObject
 nbsp;nbsp;nbsp; DynObj.add "Name", "WangYe", PROPERTY_ACCESS_READONLY
 
 nbsp;nbsp;nbsp; Response.Write DynObj.hasattr_("Name") ' True
 nbsp;nbsp;nbsp; Response.Write DynObj.hasattr_("Favor") ' False
 Set DynObj = Nothing
 3. 对于动态对象增加了getattr_方法,此方法可以安全的获取指定的属性值,避免因为对象不存在属性值导致出错。方法原型为getattr_(ByVal propertyName, ByVal defaultValue),参数propertyName指定属性的名字,defaultValue是当指定属性不存在是可以返回的默认值,比如下面代码:复制代码 代码如下:
 Dim DynObj
 Set DynObj = New DynamicObject
 nbsp;nbsp;nbsp; DynObj.add "Name", "WangYe", PROPERTY_ACCESS_READONLY
 
 nbsp;nbsp;nbsp; Response.Write DynObj.getattr_("Name", "N/A") ' WangYe
 nbsp;nbsp;nbsp; Response.Write DynObj.getattr_("Favor", "N/A") ' N/A
 Set DynObj = Nothing4. 动态对象的类名可以通过ClassName_属性或者getClassName_()方法获取。
 2012年11月12日更新 修复双引号导致构造类错误或导致执行任意代码的Bug。 (编辑:源码网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |