首先,我来自.NET世界,那里有静态类(C#,也称为VB中的模块)和实例类 - 可以实例化的那些。
这个问题是关于Javascript的,我试图重新创建我已经知道的模式并制作模块/静态类。这是代码:
<SolidColorBrush x:Key="Expander.MouseOver.Circle.Stroke" Color="#FF3C7FB1"/>
<SolidColorBrush x:Key="Expander.MouseOver.Circle.Fill" Color="Transparent"/>
<SolidColorBrush x:Key="Expander.MouseOver.Arrow.Stroke" Color="#222"/>
<SolidColorBrush x:Key="Expander.Pressed.Circle.Stroke" Color="#FF526C7B"/>
<SolidColorBrush x:Key="Expander.Pressed.Circle.Fill" Color="Transparent"/>
<SolidColorBrush x:Key="Expander.Pressed.Arrow.Stroke" Color="#FF003366"/>
<SolidColorBrush x:Key="Expander.Disabled.Circle.Stroke" Color="DarkGray"/>
<SolidColorBrush x:Key="Expander.Disabled.Circle.Fill" Color="Transparent"/>
<SolidColorBrush x:Key="Expander.Disabled.Arrow.Stroke" Color="#666"/>
<SolidColorBrush x:Key="Expander.Static.Circle.Fill" Color="Transparent"/>
<SolidColorBrush x:Key="Expander.Static.Circle.Stroke" Color="DarkGray"/>
<SolidColorBrush x:Key="Expander.Static.Arrow.Stroke" Color="#666"/>
<Style x:Key="ExpanderRightHeaderStyle" TargetType="{x:Type ToggleButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border Padding="{TemplateBinding Padding}">
<Grid Background="Transparent" SnapsToDevicePixels="False">
<Grid.RowDefinitions>
<RowDefinition Height="19"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid>
<Grid.LayoutTransform>
<TransformGroup>
<TransformGroup.Children>
<TransformCollection>
<RotateTransform Angle="-90"/>
</TransformCollection>
</TransformGroup.Children>
</TransformGroup>
</Grid.LayoutTransform>
<Ellipse x:Name="circle" Fill="{StaticResource Expander.Static.Circle.Fill}" HorizontalAlignment="Center" Height="19" Stroke="{StaticResource Expander.Static.Circle.Stroke}" VerticalAlignment="Center" Width="19"/>
<Path x:Name="arrow" Data="M 1,1.5 L 4.5,5 L 8,1.5" HorizontalAlignment="Center" SnapsToDevicePixels="false" Stroke="{StaticResource Expander.Static.Arrow.Stroke}" StrokeThickness="2" VerticalAlignment="Center"/>
</Grid>
<ContentPresenter HorizontalAlignment="Center" Margin="0,4,0,0" Grid.Row="1" RecognizesAccessKey="True" SnapsToDevicePixels="True" VerticalAlignment="Top"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="true">
<Setter Property="Data" TargetName="arrow" Value="M 1,4.5 L 4.5,1 L 8,4.5"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Stroke" TargetName="circle" Value="{StaticResource Expander.MouseOver.Circle.Stroke}"/>
<Setter Property="Fill" TargetName="circle" Value="{StaticResource Expander.MouseOver.Circle.Fill}"/>
<Setter Property="Stroke" TargetName="arrow" Value="{StaticResource Expander.MouseOver.Arrow.Stroke}"/>
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter Property="Stroke" TargetName="circle" Value="{StaticResource Expander.Pressed.Circle.Stroke}"/>
<Setter Property="StrokeThickness" TargetName="circle" Value="1.5"/>
<Setter Property="Fill" TargetName="circle" Value="{StaticResource Expander.Pressed.Circle.Fill}"/>
<Setter Property="Stroke" TargetName="arrow" Value="{StaticResource Expander.Pressed.Arrow.Stroke}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Stroke" TargetName="circle" Value="{StaticResource Expander.Disabled.Circle.Stroke}"/>
<Setter Property="Fill" TargetName="circle" Value="{StaticResource Expander.Disabled.Circle.Fill}"/>
<Setter Property="Stroke" TargetName="arrow" Value="{StaticResource Expander.Disabled.Arrow.Stroke}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ExpanderUpHeaderStyle" TargetType="{x:Type ToggleButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border Padding="{TemplateBinding Padding}">
<Grid Background="Transparent" SnapsToDevicePixels="False">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="19"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid>
<Grid.LayoutTransform>
<TransformGroup>
<TransformGroup.Children>
<TransformCollection>
<RotateTransform Angle="180"/>
</TransformCollection>
</TransformGroup.Children>
</TransformGroup>
</Grid.LayoutTransform>
<Ellipse x:Name="circle" Fill="{StaticResource Expander.Static.Circle.Fill}" HorizontalAlignment="Center" Height="19" Stroke="{StaticResource Expander.Static.Circle.Stroke}" VerticalAlignment="Center" Width="19"/>
<Path x:Name="arrow" Data="M 1,1.5 L 4.5,5 L 8,1.5" HorizontalAlignment="Center" SnapsToDevicePixels="false" Stroke="{StaticResource Expander.Static.Arrow.Stroke}" StrokeThickness="2" VerticalAlignment="Center"/>
</Grid>
<ContentPresenter Grid.Column="1" HorizontalAlignment="Left" Margin="4,0,0,0" RecognizesAccessKey="True" SnapsToDevicePixels="True" VerticalAlignment="Center"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="true">
<Setter Property="Data" TargetName="arrow" Value="M 1,4.5 L 4.5,1 L 8,4.5"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Stroke" TargetName="circle" Value="{StaticResource Expander.MouseOver.Circle.Stroke}"/>
<Setter Property="Fill" TargetName="circle" Value="{StaticResource Expander.MouseOver.Circle.Fill}"/>
<Setter Property="Stroke" TargetName="arrow" Value="{StaticResource Expander.MouseOver.Arrow.Stroke}"/>
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter Property="Stroke" TargetName="circle" Value="{StaticResource Expander.Pressed.Circle.Stroke}"/>
<Setter Property="StrokeThickness" TargetName="circle" Value="1.5"/>
<Setter Property="Fill" TargetName="circle" Value="{StaticResource Expander.Pressed.Circle.Fill}"/>
<Setter Property="Stroke" TargetName="arrow" Value="{StaticResource Expander.Pressed.Arrow.Stroke}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Stroke" TargetName="circle" Value="{StaticResource Expander.Disabled.Circle.Stroke}"/>
<Setter Property="Fill" TargetName="circle" Value="{StaticResource Expander.Disabled.Circle.Fill}"/>
<Setter Property="Stroke" TargetName="arrow" Value="{StaticResource Expander.Disabled.Arrow.Stroke}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ExpanderLeftHeaderStyle" TargetType="{x:Type ToggleButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border Padding="{TemplateBinding Padding}">
<Grid Background="Transparent" SnapsToDevicePixels="False">
<Grid.RowDefinitions>
<RowDefinition Height="19"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid>
<Grid.LayoutTransform>
<TransformGroup>
<TransformGroup.Children>
<TransformCollection>
<RotateTransform Angle="90"/>
</TransformCollection>
</TransformGroup.Children>
</TransformGroup>
</Grid.LayoutTransform>
<Ellipse x:Name="circle" Fill="{StaticResource Expander.Static.Circle.Fill}" HorizontalAlignment="Center" Height="19" Stroke="{StaticResource Expander.Static.Circle.Stroke}" VerticalAlignment="Center" Width="19"/>
<Path x:Name="arrow" Data="M 1,1.5 L 4.5,5 L 8,1.5" HorizontalAlignment="Center" SnapsToDevicePixels="false" Stroke="{StaticResource Expander.Static.Arrow.Stroke}" StrokeThickness="2" VerticalAlignment="Center"/>
</Grid>
<ContentPresenter HorizontalAlignment="Center" Margin="0,4,0,0" Grid.Row="1" RecognizesAccessKey="True" SnapsToDevicePixels="True" VerticalAlignment="Top"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="true">
<Setter Property="Data" TargetName="arrow" Value="M 1,4.5 L 4.5,1 L 8,4.5"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Stroke" TargetName="circle" Value="{StaticResource Expander.MouseOver.Circle.Stroke}"/>
<Setter Property="Fill" TargetName="circle" Value="{StaticResource Expander.MouseOver.Circle.Fill}"/>
<Setter Property="Stroke" TargetName="arrow" Value="{StaticResource Expander.MouseOver.Arrow.Stroke}"/>
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter Property="Stroke" TargetName="circle" Value="{StaticResource Expander.Pressed.Circle.Stroke}"/>
<Setter Property="StrokeThickness" TargetName="circle" Value="1.5"/>
<Setter Property="Fill" TargetName="circle" Value="{StaticResource Expander.Pressed.Circle.Fill}"/>
<Setter Property="Stroke" TargetName="arrow" Value="{StaticResource Expander.Pressed.Arrow.Stroke}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Stroke" TargetName="circle" Value="{StaticResource Expander.Disabled.Circle.Stroke}"/>
<Setter Property="Fill" TargetName="circle" Value="{StaticResource Expander.Disabled.Circle.Fill}"/>
<Setter Property="Stroke" TargetName="arrow" Value="{StaticResource Expander.Disabled.Arrow.Stroke}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ExpanderHeaderFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Border>
<Rectangle Margin="0" SnapsToDevicePixels="true" Stroke="Black" StrokeThickness="1" StrokeDashArray="1 2"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ExpanderDownHeaderStyle" TargetType="{x:Type ToggleButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border Padding="{TemplateBinding Padding}">
<Grid Background="Transparent" SnapsToDevicePixels="False">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="19"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Ellipse x:Name="circle" Fill="{StaticResource Expander.Static.Circle.Fill}" HorizontalAlignment="Center" Height="19" Stroke="{StaticResource Expander.Static.Circle.Stroke}" VerticalAlignment="Center" Width="19"/>
<Path x:Name="arrow" Data="M 1,1.5 L 4.5,5 L 8,1.5" HorizontalAlignment="Center" SnapsToDevicePixels="false" Stroke="{StaticResource Expander.Static.Arrow.Stroke}" StrokeThickness="2" VerticalAlignment="Center"/>
<ContentPresenter Grid.Column="1" HorizontalAlignment="Left" Margin="4,0,0,0" RecognizesAccessKey="True" SnapsToDevicePixels="True" VerticalAlignment="Center"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="true">
<Setter Property="Data" TargetName="arrow" Value="M 1,4.5 L 4.5,1 L 8,4.5"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Stroke" TargetName="circle" Value="{StaticResource Expander.MouseOver.Circle.Stroke}"/>
<Setter Property="Fill" TargetName="circle" Value="{StaticResource Expander.MouseOver.Circle.Fill}"/>
<Setter Property="Stroke" TargetName="arrow" Value="{StaticResource Expander.MouseOver.Arrow.Stroke}"/>
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter Property="Stroke" TargetName="circle" Value="{StaticResource Expander.Pressed.Circle.Stroke}"/>
<Setter Property="StrokeThickness" TargetName="circle" Value="1.5"/>
<Setter Property="Fill" TargetName="circle" Value="{StaticResource Expander.Pressed.Circle.Fill}"/>
<Setter Property="Stroke" TargetName="arrow" Value="{StaticResource Expander.Pressed.Arrow.Stroke}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Stroke" TargetName="circle" Value="{StaticResource Expander.Disabled.Circle.Stroke}"/>
<Setter Property="Fill" TargetName="circle" Value="{StaticResource Expander.Disabled.Circle.Fill}"/>
<Setter Property="Stroke" TargetName="arrow" Value="{StaticResource Expander.Disabled.Arrow.Stroke}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="MatchExpanderStyle" TargetType="{x:Type Expander}">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="VerticalContentAlignment" Value="Stretch"/>
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Expander}">
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" CornerRadius="3" SnapsToDevicePixels="true">
<DockPanel>
<ToggleButton x:Name="HeaderSite" Visibility="Hidden" ContentTemplate="{TemplateBinding HeaderTemplate}" ContentTemplateSelector="{TemplateBinding HeaderTemplateSelector}" Content="{TemplateBinding Header}" DockPanel.Dock="Top" Foreground="{TemplateBinding Foreground}" FontWeight="{TemplateBinding FontWeight}" FocusVisualStyle="{StaticResource ExpanderHeaderFocusVisual}" FontStyle="{TemplateBinding FontStyle}" FontStretch="{TemplateBinding FontStretch}" FontSize="{TemplateBinding FontSize}" FontFamily="{TemplateBinding FontFamily}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" IsChecked="{Binding IsExpanded, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" Margin="1" MinWidth="0" MinHeight="0" Padding="{TemplateBinding Padding}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
<ContentPresenter x:Name="ExpandSite" DockPanel.Dock="Bottom" Focusable="false" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" Visibility="Collapsed" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</DockPanel>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsExpanded" Value="true">
<Setter Property="Visibility" TargetName="ExpandSite" Value="Visible"/>
</Trigger>
<Trigger Property="ExpandDirection" Value="Right">
<Setter Property="DockPanel.Dock" TargetName="ExpandSite" Value="Right"/>
<Setter Property="DockPanel.Dock" TargetName="HeaderSite" Value="Left"/>
<Setter Property="Style" TargetName="HeaderSite" Value="{StaticResource ExpanderRightHeaderStyle}"/>
</Trigger>
<Trigger Property="ExpandDirection" Value="Up">
<Setter Property="DockPanel.Dock" TargetName="ExpandSite" Value="Top"/>
<Setter Property="DockPanel.Dock" TargetName="HeaderSite" Value="Bottom"/>
<Setter Property="Style" TargetName="HeaderSite" Value="{StaticResource ExpanderUpHeaderStyle}"/>
</Trigger>
<Trigger Property="ExpandDirection" Value="Left">
<Setter Property="DockPanel.Dock" TargetName="ExpandSite" Value="Left"/>
<Setter Property="DockPanel.Dock" TargetName="HeaderSite" Value="Right"/>
<Setter Property="Style" TargetName="HeaderSite" Value="{StaticResource ExpanderLeftHeaderStyle}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
请解释为什么命名空间内声明的方法不可见,但变量是什么?另外,有没有办法阻止这些变量在var MyModule = {
variable1: 0,
variable2: 1,
method1: function() {
//code goes here
},
method2: function() {
//mode code goes here
},
method3: function() {
//and some more just to prove the pattern
}
}
method1(); //error - no such method - ok, good, I expect that
variable1 = 5; //silently assigns a variable inside MyModule to 5 ?
之外可见,即使在同一个脚本中也是如此?
答案 0 :(得分:7)
我将首先尝试解决一些误解 - 您的模块实际上是使用文字初始化的plain JavaScript object。对象不会隐藏任何信息 - JavaScript没有private
和public
范围,就像Java一样。此外,访问对象属性的唯一方法是通过它访问它们
method1();
这会失败,因为您正在尝试获取名为method1
的变量并执行它。这不存在,因此错误。但 可以做的是MyModule.method1()
。这是因为MyModule
是一个实际的对象。在Java中,这与Object MyModule = new Object()
类似。因此,您可以在其上调用方法,例如MyModule.toString()
- 唯一的&#34;非传统的&#34;事实上,实例是用大写字母命名的 - Java和JavaScript中的变量通常以小写字母开头,但只能按惯例开头 - 没有任何语言功能可以强制执行。
接下来,有这一行:
variable1 = 5; //silently assigns a variable inside MyModule to 5 ?
要回答该行的评论 - 不,它没有。上述行等同于执行window.variable1 = 5
。你在那里所拥有的被称为&#34;隐含的全球&#34;。这个名称是相当自我描述性的,但只是为了澄清window.foo = 42
是一个明确的全局foo = 42
暗示,因为它回退到window
对象。但是,var foo = 42
不是全局的 - var关键字不会附加或使用全局window
对象。如果使用"use strict"指令,则会导致JavaScript引擎在遇到隐含的全局时抛出错误。
现在,除了这些误解之外,还有另一个小问题,我只会掩饰它,但它实际上是一件大事 - MyModule.method1
依旧是函数而不是比方法。方法是用于子例程的面向对象的术语,该子例程还带有隐含状态,该隐含状态是它被分配给的对象。但是,函数是一个自由浮动的可执行代码,它本身并不属于#34;到一个对象。这种区别似乎相当具有学术性,但它具有很大的影响。但是,我会请求您相信我,因为这里涉及的主题太广泛了。
那么,这是错误的。我们如何使它正确?首先,关于范围,其余部分需要:
JavaScript有两个范围 - 全局和功能。这就是这意味着:
var foo = 42;
function bar(input) {
var foo = input;
return foo;
}
console.log(bar(5)); //5
console.log(foo); //42
我们也有一些名为foo
的变量 - 一个不在函数内。分配一个不会改变另一个 - 它是因为它们在不同的范围内。这要归功于var
关键字 - 如果在函数内省略了,那么我们将访问相同的东西
var foo = 42;
function bar(input) {
foo = input;
return foo;
}
console.log(bar(5)); //5
console.log(foo); //5
这是因为内部foo
未声明在功能范围内,因此它访问外部(并且没有外部 - window.foo
属性)。
这很简单。但是,这里有一个隐藏的方面并不是很明显,但值得一提的是:只有两个范围。这就是我的意思
function bar(condition) {
var foo = 5;
if (condition) {
var foo = 42;
}
return foo;
}
console.log( bar(false) ); //5
console.log( bar(true) ); //42
所以,即使我们似乎在if语句中声明了一个新的foo
属性,它实际上与第一个属性相同。其他语言在{ }
内有一个块范围,所以在那里声明的变量就在那里。在JavaScript中不正确。容易错过,所以需要注意。
现在,解决你的问题。有关JavaScript模块模式的优秀资源,仅举几例:Addy Osmani's "Learning JavaScript Design Patterns" book有一个非常好的描述,Todd Motto也有,我相信,这是一篇适合初学者的好文章{{3}更深入,但它仍然可以访问。它们都涵盖了模块模式。实际上,您将在这些资源和Web上找到许多模块模式。该模块允许您执行的操作与其他语言的public
和private
类似。我不会试图解释它,因为我认为其他人已经做得比我更好。但是,我将简要解释一下模块是什么。同样,其他资源可以更好地涵盖这一点。
模块利用名为Closure的JavaScript功能更多信息the Adequately Good post和here(最受欢迎的StackOverflow问题之一)。还记得我说过,JavaScript中有两个范围吗?简单地说,一个闭包提供了一个功能范围。这是它的样子:
(function() { /* your code goes here */ })()
要简要剖析一下,您的代码函数将包含在(/* function goes here */)()
中。实际上,这样做是执行函数所以内部的所有内容都被放入功能范围。然而,这是非常强大的,这是一个例子
var closure = (function() {
var privateVar = "secret";
return {
publicVar: 42,
getPrivateVar() { return privateVar; }
}
})()
console.log(closure.publicVar); //42
console.log(closure.getPrivateVar()); //"secret"
//let's change this
closure.publicVar = 5;
closure.privateVar = "changed";
console.log(closure.publicVar); //5
console.log(closure.getPrivateVar()); //"secret"
就像我们拥有(类似的东西)私人领域一样。同样,var privateVar
将保持&#34;装瓶&#34;在功能范围内,不能在外面访问。顺便提一下,这是模块模式的一个例子。而不是var closure
我可以称之为myModule
。这是一个相当简单的看法,但是,事情就是这样 - 它并没有变得更复杂。所有不同的模块归结为非常相似的东西 - 您只是以不同的方式公开数据。然而,这个概念是相似的 - &#34;私人&#34;田野留在里面,&#34;公共&#34;那些,你可以从其他地方访问。
这很长,但希望能涵盖你需要的基础知识。
答案 1 :(得分:0)
在向Stack Overflow询问问题之前,I created a JSFiddle附上问题,之后的几个步骤确定了问题所在。这实际上经常发生。但这次我想与公众分享我的发现。 JS大师可能已经知道这一点,而一些经验不足的开发人员可能会发现这些信息很有帮助。
I had two instances of variable MyModule
,一个属于variable1
,另一个属于MyModule
(全局范围)。当我将鼠标悬停在window
调试器中时,即使它位于variable1
内,调试器也会显示全局值。看起来像Visual Studio 2015中的一个错误,但这是它的工作原理。然后我在MyModule
的一个函数中放了一个断点,并注意到如果一个变量以MyModule
为前缀,它会显示一个不同的值。显然,JS语法不允许在声明this
期间放置this
,所以只需要了解JS调试器在Visual Studio中的工作方式。
如果我的解释没有意义,请尝试将鼠标悬停在C#项目内任何类定义顶部的变量上。在调试过程中的任何时候,无论谁声明了什么,您都会在那里看到最新和正确的值。 IDE行为的不同之处在于给我带来了困惑。另外,如果你对变量声明不够谨慎,那么Javascript就有创建全局变量的倾向。