为什么你不必在javascript中声明变量? [英] why don't you have to declare variables in javascript?

查看:77
本文介绍了为什么你不必在javascript中声明变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述




任何人都可以提出一个合理的论证javascript'的行为

每当我分配给以前未申报的时候创建一个新的全局变量

变量。我不能相信这只是为了方便起见(当然我们从基本学到了很多东西)。


这里是我的建议:所有全球 (文档范围)变量必须在功能块外面用''var''声明



失败,有没有人知道任何模式或技巧我可以用来确保

当我不小心拼错一个变量

名字时我不会创建一个新的全局变量?


Andy

Hi,

can anybody put forward a sensible argument javascript''s behaviour of
creating a new global variable whenever I assign to a previously undeclared
variable. I can''t beleive this is just for the sake of convenience (surely
we learned this much from basic).

here''s my proposal: all "global" (document scope) variables must be declared
by ''var'' outside a function block.

failing that, does anyone know any patterns or tricks I can use to make sure
I don''t create a new global variable when I accidentally misspell a variable
name?

Andy

推荐答案

" Andy Fish" < AJ **** @ blueyonder.co.uk>写道:
"Andy Fish" <aj****@blueyonder.co.uk> writes:
失败了,有没有人知道我可以用来确保的任何模式或技巧
当我意外拼错一个变量时我不会创建一个新的全局变量
名称?
failing that, does anyone know any patterns or tricks I can use to make sure
I don''t create a new global variable when I accidentally misspell a variable
name?




在代码上使用JSLint。它强制执行漂亮的代码并报告所有使用的本地和

全局变量。任何无法识别的全局变量都是错误的。

< URL:http://www.crockford.com/javascript/jslint.html>


/ L $ / $
-

Lasse Reichstein Nielsen - lr*@hotpop.com

Art D''HTML:< URL:http://www.infimum.dk/HTML/randomArtSplit.html>

''没有判断的信仰只会降低精神神圣。'



Use JSLint on your code. It enforces pretty code and reports all local and
global variables used. Any unrecognizable global variable would be a typo.
<URL:http://www.crockford.com/javascript/jslint.html>

/L
--
Lasse Reichstein Nielsen - lr*@hotpop.com
Art D''HTML: <URL:http://www.infimum.dk/HTML/randomArtSplit.html>
''Faith without judgement merely degrades the spirit divine.''


" Andy Fish" < AJ **** @ blueyonder.co.uk>在消息新闻中写道:< JF ******************* @ news-text.cableinet.net> ...
"Andy Fish" <aj****@blueyonder.co.uk> wrote in message news:<JF*******************@news-text.cableinet.net>...
任何人都可以提出一个合理的论证javascript的行为
每当我分配给一个以前未声明的变量时创建一个新的全局变量。我不能相信这只是为了方便(当然我们从基础学到了很多东西)。


好​​吧我不知道为什么,ECMA提供了一些有趣的论证

面向对象,我会在下面给出一些细节 - 见如果这使得

有意义,则判断var是否为var。关键字很有用,如果无聊则跳过

:-)


因此,Javascript是面向对象的,可变实例化

参与这个逻辑。要完全理解为什么你已经获得了所描述的行为,你需要熟悉变量

对象(10.1.3)和参考对象(8.7)。 br />

短版本如下。当输入特定的执行

上下文(全局代码,函数代码)时,有一个所谓的变量

对象,它保存对所有变量和函数的引用。 />
在上下文中。换句话说,使用

var声明一个变量。 keyword将变量添加为此变量对象的属性。


使用的Variable对象取决于代码的类型;对于函数

代码,这是激活对象(其中arguments是

属性);对于全局代码,这是全局对象,即在输入任何输出上下文之前创建的对象

,并保存所有全局

变量和属性(例如Math,Date)等等...) - 在HTML中,

" window" object指的是这个全局对象(你也可以使用

" this"关键字);对于Eval Code,它取决于调用上下文。


现在,如果你不使用var,该怎么办呢?关键词?答案是你,你不是真的做出变量声明。考虑以下

声明:


函数f(){

a = 3;

}


我们有一项任务,所以根据ECMA 11.13.1,以下是

执行


1。评估LeftHandSideExpression。

2.评估AssignmentExpression。

3.调用GetValue(结果(2))。

4.调用PutValue(结果( 1),结果(3))。

5.返回结果(3)。

LeftHandsideExpression是a,AssignmentExpression是3。 。所以在

之前将值设为3。在a,a中被评估。这是在

之后完成的(标识符解析,10.1.4):


1.获取范围链中的下一个对象。如果没有,请转到

步骤5.

2.调用Result(1)的[[HasProperty]]方法,传递

标识符作为属性。

3.如果Result(2)为true,则返回类型为Reference的值,其基数为

对象为Result(1)其属性名称为标识符。

4.转到步骤1.

5.返回类型为Reference的值,其基础对象为null并且

,其属性名称是标识符。


如您所见,第1步到第4步被重复,直到范围内没有更多的对象

chain,可以匹配propertyNamea。因此,执行步骤5

,即带有null的引用。 base为

提供赋值表达式。


引用只是对对象属性的引用。它
包含两个组件,基础对象和属性名称;正如您所看到的那样,评估标识符的结果总是值为参考类型的价值

(要么因为找到它,要么因为它'''不是

找到了。


当在assignement表达式中时,JS尝试将值加到

引用中,使用:


PutValue(V,W)

1.如果Type(V)不是Reference,抛出ReferenceError异常。

2.调用GetBase(V)。

3.如果Result(2)为null,请转到步骤6.

4.调用[[Put]]方法结果(2),传递GetPropertyName(V)

为属性名称,W为值。

5.返回。

6 。调用全局对象的[[Put]]方法,传递

GetPropertyName(V)作为属性名称,W传递给值。

7.返回。


如果仔细观察算法,你会看到第2步将会因为参考a而返回null。后面没有任何对象。

因此,执行步骤6,并在全局对象上直接声明属性

- 即声明一个变量而不是使用

var关键字将导致变量为全局变量。

这里是我的建议:allglobal (文档范围)变量必须由功能块外的''var'声明
can anybody put forward a sensible argument javascript''s behaviour of
creating a new global variable whenever I assign to a previously undeclared
variable. I can''t beleive this is just for the sake of convenience (surely
we learned this much from basic).
Well I don''t know the why, ECMA offers some interesting argument with
object-orientation, I''ll give some details below - see if this makes
sense, decide whether the "var" keyword is useful, and skip if bored
:-)

So, Javascript is object-oriented, and variable instantiation
participates of this logic. To fully understand why you have obtained
the described behavior you need to get familiar with the the Variable
Object (10.1.3) and the Reference Object (8.7).

The "short" version is as follows. When entering a specific execution
context (global code, function code), there is a so-called Variable
Object, which holds references to all variables and functions defined
in the context. To put it another way, declaring a variable using the
"var" keyword adds the variable as a property of this Variable Object.

The Variable object in use depends on the type of code; for function
code, this is the Activation Object (of which "arguments" is a
property); for global code, this is the Global Object, i.e. an object
created before any exuction context is entered, and holding all global
variables and properties (such as Math, Date etc...) - in HTML, the
"window" object refers to this global object (you can also use the
"this" keyword); for Eval Code, it depends on the calling context.

Now, what if you don''t use the "var" keyword? The answer is that you
don''t really make a variable declaration. Consider the following
statement:

function f() {
a = 3;
}

We have an assignment, so according to ECMA 11.13.1 the following is
executed

1. Evaluate LeftHandSideExpression.
2. Evaluate AssignmentExpression.
3. Call GetValue(Result(2)).
4. Call PutValue(Result(1), Result(3)).
5. Return Result(3).

LeftHandsideExpression is "a", AssignmentExpression is "3". So before
putting the value "3" in "a", "a" is evaluated. This is done as
follows (Identifier Resolution, 10.1.4):

1. Get the next object in the scope chain. If there isn''t one, go to
step 5.
2. Call the [[HasProperty]] method of Result(1), passing the
Identifier as the property.
3. If Result(2) is true, return a value of type Reference whose base
object is Result(1) and whose property name is the Identifier.
4. Go to step 1.
5. Return a value of type Reference whose base object is null and
whose property name is the Identifier.

As you can see, step 1 to 4 are iterated until there is no more object
in the scope chain, which could match the propertyName "a". So step 5
is executed, that is, a Reference with a "null" base is provided for
the assignment expression.

A Reference is simply a reference to a property of an object. It
consists in two components, the base object, and the property name; as
you''ve seen, the result of evaluating an identifier is always a value
of type Reference (either because it''s found, or because it''s not
found).

When in the assignement expression, JS tries to put a value to the
reference, using:

PutValue (V, W)
1. If Type(V) is not Reference, throw a ReferenceError exception.
2. Call GetBase(V).
3. If Result(2) is null, go to step 6.
4. Call the [[Put]] method of Result(2), passing GetPropertyName(V)
for the property name and W for the value.
5. Return.
6. Call the [[Put]] method for the global object, passing
GetPropertyName(V) for the property name and W for the value.
7. Return.

If you look closely at the algorithm, you''ll see the step 2 will
return null, since the Reference "a" doesn''t have any object behind.
Therefore, step 6 is executed, and the property is declared directly
on the Global Object - that is, declaring a variable without using the
var keyword will result in the variable being global.
here''s my proposal: all "global" (document scope) variables must be declared
by ''var'' outside a function block.




这是有道理的,但你会越多用javascript编写的程序越多

你将使用高级作用域来构建你的脚本,你就越少b
有全局变量(在js你甚至可以运行)一个完整的脚本没有

一个全局变量,使用匿名函数表达式。)

HTH

是的。



That makes sense, but the more you''ll program in javascript, the more
you''ll use advanced scoping to build your scripts, the less you''ll
have global variables (in js you can even run a full script without
one global variable, using an anonymous function expression).
HTH
Yep.


2003年8月18日14:29:31 -0700,是的< y - ******* @ em-lyon.com>写道:
On 18 Aug 2003 14:29:31 -0700, Yep <y-*******@em-lyon.com> wrote:
这是有道理的,但你在javascript中编程的越多,你将使用高级范围来构建脚本越多,你就越少'll
有全局变量(在js中你甚至可以运行一个完整的脚本,而不是一个全局变量,使用匿名函数表达式)。
That makes sense, but the more you''ll program in javascript, the more
you''ll use advanced scoping to build your scripts, the less you''ll
have global variables (in js you can even run a full script without
one global variable, using an anonymous function expression).



抱歉声音n00bish,但我看过一个脚本使用function()表达式

来创建函数。我真的很惊讶

它的工作原理。是你在说什么?


i不记得细节,但它的语法是这样的:


功能(" name"," code",var1,var2,var3,...,varn);

其中" name"是函数的名称,代码是是完整的内容

函数作为字符串表达式,var1 - varn是参数

传递给它。

$ b $我很高兴能够找到更多关于这一点的信息,因为我只看过它曾经使用过

,我想利用它。


-

Charles Banas


sorry to sound n00bish, but i''ve seen a script use a function() expression
to create functions as it executes. i was actually quite surprised by how
it worked. is that what you''re talking about?

i don''t recall the details, but its syntax was like this:

function("name", "code", var1, var2, var3, ... , varn);
where "name" was the name of the function, "code" was the complete contents
of the function as a string expression, and var1 - varn were the parameters
passed to it.

i''d appreciate finding out more about this, because i''ve only seen it used
once, and i wanted to take advantage of it.

--
Charles Banas


这篇关于为什么你不必在javascript中声明变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆