Classic ASP中Dim和Public有什么区别?

Lan*_*art 9 vbscript asp-classic

今天提出了关于范围的问题,它让我思考.

我一直都了解VBScript范围以及如何声明全局和本地.我想到,虽然我从不使用Public变量,但Dim在全局声明时往往会使用变量.

据我所知,它Dim是相同的Public,但如果是这样的话,为什么同时拥有它们呢?这两者之间是否存在差异,使用其中一种是不错的做法?


更新:

这个问题纯粹是针对VBScript而不是VBA,特别是在Classic ASP的背景下.

Ekk*_*ner 16

访问限制在模块化或面向对象语言中是有意义的.由于Basic是一种简单的过程语言,后来添加这些功能使得使用Dim,Public和Private的严格规则变得困难.

以下所有内容都是关于VBScript(不是VBA,不是ASP,不是VB.NET)

事实:

  1. 在Sub/Function/Class代码中,Dim,Public和Private是等效的:所有声明都适用于全局范围
  2. 在Subs/Functions/Methods中,您只能使用Dim.声明适用于Func/Sub/Method-local范围
  3. 在类定义中,Dim Public声明可以访问out-of-classe代码的变量; Private创建的变量只能从类代码访问.私有方法只能从类代码中调用,公共方法(默认)可以从"外部空间"调用.

规则集I:

  1. 使用Dim进行顶级声明,因为Public/Private没有明显的效果
  2. 在子 /函数/方法中使用Dim ,因为必须
  3. 使用Public或Private(但不是Dim)进行成员变量声明,因为访问权限很重要
  4. 对私有方法使用Private,但不要使用Public,因为它是默认方法

示例代码:

Option Explicit

Dim     gsDim  : gsDim  = "gsDim"
Public  gsPub  : gsPub  = "gsPub"
Private gsPriv : gsPriv = "gsPriv"

Class cX
  Dim     m_sDim
  Public  m_sPub
  Private m_sPriv
  Private Sub Class_Initialize()
    m_sDim  = "m_sDim"
    m_sPub  = "m_sPub"
    m_sPriv = "m_sPriv"
  End Sub
  Function ToString()
    ' Public Whatever => syntax error
    ' Private Whatever => syntax error
    Dim Whatever ' => no problem to use Dim for local declaration
    ToString = ToStringPriv()
  End Function
  Private Function ToStringPriv()
    ToStringPriv = Join(Array(m_sDim, m_sPub, m_sPriv))
  End Function
End Class

Function main()
  ' Public Whatever => syntax error
  ' Private Whatever => syntax error
  Dim Whatever ' => no problem to use Dim for local declaration
  main = 0
  WScript.Echo "in func main():", Join(Array(gsDim, gsPub, gsPriv))
  Execute "WScript.Echo ""via Execute:"", Join(Array(gsDim, gsPub, gsPriv))"
  Dim oX : Set oX = New cX
  WScript.Echo "oX.ToString():", oX.ToString()
  Dim s
 On Error Resume Next
  s = oX.ToStringPriv()
  WScript.Echo Err.Description
  s = oX.m_sPriv
  WScript.Echo Err.Description
 On Error GoTo 0
End Function

WScript.Echo "top level code:", Join(Array(gsDim, gsPub, gsPriv))
WScript.Quit main()
Run Code Online (Sandbox Code Playgroud)

输出:

cscript dimpubpriv.vbs
top level code: gsDim gsPub gsPriv
in func main(): gsDim gsPub gsPriv
via Execute: gsDim gsPub gsPriv
oX.ToString(): m_sDim m_sPub m_sPriv
Object doesn't support this property or method
Object doesn't support this property or method
Run Code Online (Sandbox Code Playgroud)

更新Kul-Tigin的评论:

规则集II(为支持模块的主机编写代码时):

  1. 将模块视为类,即将I.3和I.4应用于顶级变量rsp.子/函数声明(因为现在访问权限很重要/被强制执行)

码:

Option Explicit

Public  gsPub   : gsPub = "gsPub"
Private gsPriv  : gsPriv = "gsPriv"

Class AContext
    Public CodeObject
End Class

With (New AContext)
    Set .CodeObject = Me
    WScript.Echo .CodeObject.gsPub
    WScript.Echo .CodeObject.gsPriv
End With
Run Code Online (Sandbox Code Playgroud)

证据:

cscript dimpubpriv.vbs
gsPub
... Microsoft VBScript runtime error: Object doesn't support this property or method: 'CodeObject.gsPriv''
Run Code Online (Sandbox Code Playgroud)

  • 当其他语言使用脚本/模块时,VBScript中的`Public/Private` _does_问题.例如,WSF文件中的JScript代码将无法在包含的`VBS`文件中调用定义为"Private"的VBScript子/函数. (3认同)