我了解全局范围和 javascript 变量的问题及其普遍的不受欢迎;而且你到处都能找到它们。以下(在浏览器中)是等效的:
var foo = 3; // foo === 3, window.foo === 3
bazz = 10; // bazz === 10, window.bazz === 10
在全局范围内使用 var 关键字声明变量与在代码中任何地方不使用 var 声明它是一样的:您的变量被分配给根(窗口)对象。
我经常看到的一种技术(例如设置谷歌分析)是这样的:
var _gaq = _gaq || [];
... 我遵循的推理是,如果已声明 _gaq,则使用它,如果未声明,则将其创建为数组。它允许粗心的编码不会覆盖已分配给全局变量 _gaq 的任何值。
我不明白的是为什么这会引发错误:
_gaq = _gaq || [];
它们看起来和我一样:_gaq 应该采用 _gaq 的值或初始化为数组。但它会引发引用错误 - 我的问题是:它们为什么不同?
最佳答案
您永远无法读取 未声明的变量,这就是您尝试使用表达式 _gaq || 的原因[] 在最后一个例子中。
在这种情况下
_gaq = _gaq || [];
_qaq 在评估右侧 (_gaq || []) 之前未声明,它会抛出错误。
这里是对这种情况下发生的事情的逐步解释:
赋值运算符在section 11.13.1中有描述。规范:
The production
AssignmentExpression : LeftHandSideExpression = AssignmentExpressionis evaluated as follows:1. Let
lrefbe the result of evaluatingLeftHandSideExpression.
2. Letrrefbe the result of evaluatingAssignmentExpression.
...
LeftHandSideExpression是_gaq,AssignmentExpression是_gqa || [].
因此,首先对 _qaq 求值,结果为 unresolvable reference ,因为变量 _gaq 没有声明。此评估不会引发错误。
然后 _gqa || [] 被评估。这是一个 LogicalORExpression,在 section 11.11 中有描述。作为 LogicalORExpression ||逻辑与表达式。在这种情况下,左侧的 LogicalORExpression 是 _gaq,右侧的 LogicalANDExpression 是 [].
表达式的计算如下:
1. Let
lrefbe the result of evaluatingLogicalORExpression.
2. LetlvalbeGetValue(lref).
...
我们已经知道 lref 将是一个无法解决的引用,因为 _gaq 没有声明。那么让我们看看 GetValue 在做什么(在 section 8.7.1 中定义,V 是传递给 GetValue 的值):
1. If
Type(V)is notReference, returnV.
2. Letbasebe the result of callingGetBase(V).
3. IfIsUnresolvableReference(V), throw aReferenceErrorexception.
...
如您所见,此过程的第三步抛出一个 ReferenceError 错误,该错误又通过评估赋值的右侧执行,这就是错误所在抛出。
那么,为什么 var _gaq = _gaq || 不会发生这种情况? []; ?
这一行:
var _gaq = _gaq || [];
实际上是
var _gaq;
_gaq = _gaq || [];
因为一个叫做 hoisting [MDN] 的东西.这意味着当 _gaq 被求值时,它不会产生一个不可解析的引用,而是一个值为未定义的引用.
(如果变量 _gaq 已经声明(并且可能有一个值),那么 var _gaq 将没有任何效果。)
如果您想从函数内部全局创建 _gaq,请通过引用 window 来显式执行此操作:
window._gaq = window._gaq || [];
关于Javascript 全局范围分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15388654/
通过rubykoans.com,我在about_array_assignment.rb中遇到了这两段代码你怎么知道第一个是非并行赋值,第二个是一个变量的并行赋值?在我看来,除了命名差异之外,代码几乎完全相同。4deftest_non_parallel_assignment5names=["John","Smith"]6assert_equal["John","Smith"],names7end45deftest_parallel_assignment_with_one_variable46first_name,=["John","Smith"]47assert_equal'John
请帮助我理解范围运算符...和..之间的区别,作为Ruby中使用的“触发器”。这是PragmaticProgrammersguidetoRuby中的一个示例:a=(11..20).collect{|i|(i%4==0)..(i%3==0)?i:nil}返回:[nil,12,nil,nil,nil,16,17,18,nil,20]还有:a=(11..20).collect{|i|(i%4==0)...(i%3==0)?i:nil}返回:[nil,12,13,14,15,16,17,18,nil,20] 最佳答案 触发器(又名f/f)是
我正在尝试从Postgresql表(table1)中获取数据,该表由另一个相关表(property)的字段(table2)过滤。在纯SQL中,我会这样编写查询:SELECT*FROMtable1JOINtable2USING(table2_id)WHEREtable2.propertyLIKE'query%'这工作正常:scope:my_scope,->(query){includes(:table2).where("table2.property":query)}但我真正需要的是使用LIKE运算符进行过滤,而不是严格相等。然而,这是行不通的:scope:my_scope,->(que
我刚刚被困在这个问题上一段时间了。以这个基地为例:moduleTopclassTestendmoduleFooendend稍后,我可以通过这样做在Foo中定义扩展Test的类:moduleTopmoduleFooclassSomeTest但是,如果我尝试通过使用::指定模块来最小化缩进:moduleTop::FooclassFailure这失败了:NameError:uninitializedconstantTop::Foo::Test这是一个错误,还是仅仅是Ruby解析变量名的方式的逻辑结果? 最佳答案 Isthisabug,or
假设我有这个范围:("aaaaa".."zzzzz")如何在不事先/每次生成整个项目的情况下从范围中获取第N个项目? 最佳答案 一种快速简便的方法:("aaaaa".."zzzzz").first(42).last#==>"aaabp"如果出于某种原因你不得不一遍又一遍地这样做,或者如果你需要避免为前N个元素构建中间数组,你可以这样写:moduleEnumerabledefskip(n)returnto_enum:skip,nunlessblock_given?each_with_indexdo|item,index|yieldit
我早就知道Ruby中的“常量”(即大写的变量名)不是真正常量。与其他编程语言一样,对对象的引用是唯一存储在变量/常量中的东西。(侧边栏:Ruby确实具有“卡住”引用对象不被修改的功能,据我所知,许多其他语言都没有提供这种功能。)所以这是我的问题:当您将一个值重新分配给常量时,您会收到如下警告:>>FOO='bar'=>"bar">>FOO='baz'(irb):2:warning:alreadyinitializedconstantFOO=>"baz"有没有办法强制Ruby抛出异常而不是打印警告?很难弄清楚为什么有时会发生重新分配。 最佳答案
我正在尝试查询我的Rails数据库(Postgres)中的购买表,我想查询时间范围。例如,我想知道在所有日期的下午2点到3点之间进行了多少次购买。此表中有一个created_at列,但我不知道如何在不搜索特定日期的情况下完成此操作。我试过:Purchases.where("created_atBETWEEN?and?",Time.now-1.hour,Time.now)但这最终只会搜索今天与那些时间的日期。 最佳答案 您需要使用PostgreSQL'sdate_part/extractfunction从created_at中提取小时
假设您在Ruby中执行此操作:ar=[1,2]x,y=ar然后,x==1和y==2。是否有一种方法可以在我自己的类中定义,从而产生相同的效果?例如rb=AllYourCode.newx,y=rb到目前为止,对于这样的赋值,我所能做的就是使x==rb和y=nil。Python有这样一个特性:>>>classFoo:...def__iter__(self):...returniter([1,2])...>>>x,y=Foo()>>>x1>>>y2 最佳答案 是的。定义#to_ary。这将使您的对象被视为要分配的数组。irb>o=Obje
我正在尝试使用在我的代码中是动态的Time.local来安排时间。在每个月的第一天,我传递的值是Time.local(2009,9,-1,0)。在PHP中,这会将时间设置为上个月的最后一天。在ruby中,我只是得到“ArgumentError:参数超出范围”。是我用错了方法还是什么?谢谢。 最佳答案 您应该使用DateTime类而不是Time。(您可能需要先require'date'并安装activesupportgem。)它比Time更通用,并且可以用DateTime.civil(2009,9-1,-1,0)做你想做的事。为天
我有一个gem,它有一个根据Rails.env的不同行为的方法:defself.envifdefined?(Rails)Rails.envelsif...现在我想编写一个规范来测试这个代码路径。目前我是这样做的:Kernel.const_set(:Rails,nil)Rails.should_receive(:env).and_return('production')...没关系,只是感觉很丑。另一种方法是在spec_helper中声明:moduleRails;end而且效果也很好。但也许有更好的方法?理想情况下,这应该有效:rails=double('Rails')rails.sho