声明没有var关键字的变量

xra*_*alf 52 javascript variables declaration global-variables

在w3schools写道:

如果声明变量而不使用"var",则变量始终变为GLOBAL.

在函数内声明全局变量是否有用?我可以想象在某个事件处理程序中声明一些全局变量,但它有什么用呢?更好地使用RAM?

T.J*_*der 86

不,没有RAM的好处或类似的东西.

w3schools正在谈论的是我称之为隐性全球恐怖的东西.考虑这个功能:

function foo() {
    var variable1, variable2;

    variable1 = 5;
    varaible2 = 6;
    return variable1 + variable2;
}
Run Code Online (Sandbox Code Playgroud)

看起来很简单,但由于线路上的拼写错误,它NaN不会返回.它创建了一个带有拼写错误名称的全局变量:11varaible2 = 6;

function foo() {
    var variable1, variable2;

    variable1 = 5;
    varaible2 = 6;
    return variable1 + variable2;
}
console.log(foo());     // NaN
console.log(varaible2); // 6?!?!?!
Run Code Online (Sandbox Code Playgroud)

这是因为函数分配给varaible2(注意拼写错误),但varaible2没有在任何地方声明.通过JavaScript中作用域链的机制,这最终成为对全局对象(可以window在浏览器上访问)上的(新)属性的隐式赋值.

这只是松散模式JavaScript的"功能",分配给完全未声明的标识符不是错误; 相反,它在全局对象上创建属性,全局对象上的属性是全局变量.(最多通过ES5,所有全局是全局对象的属性.作为ES2015的,虽然加入了一种新的全球性的,是不是全局对象的属性.全球范围的let,constclass创建新的全球.)

我的例子是一个错字,但当然,如果你愿意,你可以故意这样做.毕竟,这是语言中明确定义的一部分.所以:

myNewGlobal = 42;
Run Code Online (Sandbox Code Playgroud)

...... myNewGlobal未声明的任何地方都将创建新的全局.

但我强烈建议不要故意这样做:它使代码难以阅读和维护,并且当代码变得更加普遍和普遍时,代码将与JavaScript模块不兼容.如果你真的需要在运行时从一个函数内创建一个全局变量(已经是一个红色的标志,但它有正当理由),通过分配给一个属性window(或者你的环境中指向全局对象的任何东西)来显式地做它;它window在浏览器上):

window.myNewGlobal = 42;
Run Code Online (Sandbox Code Playgroud)

事实上,我建议使用ES5的严格模式.严格模式会将未声明的标识符分配给错误,而不是静默创建全局.如果我们一直在使用严格模式,foo上面的问题会更容易诊断:

"use strict"; // Turns on strict mode for this compilation unit

function foo() {
    var variable1, variable2;

    variable1 = 5;
    varaible2 = 6;                 // <=== ReferenceError
    return variable1 + variable2;
}
console.log(foo());
Run Code Online (Sandbox Code Playgroud)


有点切向,但总的来说我建议尽可能避免使用全局变量.全局命名空间已经非常混乱在浏览器上.浏览器为DOM中的每个元素创建一个全局id,对于大多数具有a的元素name,并且具有自己的几个预定义全局变量(例如title),这很容易与您的代码冲突.

相反,只需定义一个不错的作用域函数并将符号放入其中:

(function() {
    var your, symbols, here, if_they_need, to_be_shared, amongst_functions;

    function doSomething() {
    }

    function doSomethingElse() {
    }
})();
Run Code Online (Sandbox Code Playgroud)

如果你这样做,你可能想要启用严格模式:

(function() {
    "use strict";
    var your, symbols, here, if_they_need, to_be_shared, amongst_functions;

    function doSomething() {
    }

    function doSomethingElse() {
    }
})();
Run Code Online (Sandbox Code Playgroud)

......如上所述,它具有将未声明的标识符的赋值转换为错误(以及其他各种有用的东西)的优点.

请注意,在JvaScript 模块中(在ES2015中添加,但现在才开始进入野外),默认情况下启用严格模式.(class定义也是如此,在ES2015中也是新的.)


use*_*064 17

忘记var时的副作用

隐含全局变量和明确定义的变量之间存在一个细微差别.区别在于使用delete运算符取消定义这些变量的能力:

•无法删除使用var创建的全局变量(在任何函数之外的程序中创建的全局变量).

•可以删除在没有var的情况下创建的隐含全局变量(无论是否在函数内创建).

这表明隐含的全局变量在技术上不是真正的变量,但它们是全局对象的属性.可以使用delete运算符删除属性,而变量不能:

// define three globals
var global_var = 1;
global_novar = 2; // antipattern
(function () {
   global_fromfunc = 3; // antipattern
}());
// attempt to delete
delete global_var; // false
delete global_novar; // true
delete global_fromfunc; // true
// test the deletion
typeof global_var; // "number"
typeof global_novar; // "undefined"
typeof global_fromfunc; // "undefined"
Run Code Online (Sandbox Code Playgroud)

在ES5严格模式下,对未声明变量的赋值(例如前面代码段中的两个反模式)将引发错误.

JavaScript模式,作者:Stoyan Stefanov(O'Reilly).版权所有2010 Yahoo!,Inc.,9780596806750.


Guf*_*ffa 5

全局变量的唯一用途是如果您需要全局访问它们。在这种情况下,您应该var在函数外部使用关键字来声明它们,以明确表示您确实想要创建全局变量,并且var在尝试声明局部变量时不要忘记。

通常,您应该尝试限定代码的范围,以便在全局范围内尽可能少地需要。您在脚本中使用的全局变量越多,将其与另一个脚本一起使用的机会就越少。

通常函数中的变量应该是局部的,这样当你退出函数时它们就会消失。

  • @xralf:所有语言都允许可能被滥用的构造。`while (true);` 浮现在脑海中。 (3认同)