首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >声明不带var关键字的变量

声明不带var关键字的变量
EN

Stack Overflow用户
提问于 2011-07-31 17:20:40
回答 8查看 85.7K关注 0票数 86

在w3schools上是这样写的:

如果您声明了一个变量,但没有使用"var",则该变量始终成为全局变量。

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

EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2011-07-31 17:23:16

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

w3schools所说的是我称之为的东西。考虑这个函数:

function foo() {
    var variable1, variable2;

    variable1 = 5;
    varaible2 = 6;
    return variable1 + variable2;
}

看起来很简单,但由于varaible2 = 6;行上的输入错误,它返回NaN,而不是11。它创建了一个全局变量,其名称为拼写错误的名称:

function foo() {
    var variable1, variable2;

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

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

这只是松散模式JavaScript的一个“特性”,给一个完全未声明的标识符赋值并不是一个错误;相反,它在全局对象上创建了一个正确的,全局对象上的属性是全局变量。(直到ES5,所有全局变量都是全局对象的属性。然而,在ES2015中,添加了一种新的全局类型,它不是全局对象的属性。全局作用域letconstclass创建了新的全局类型。)

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

myNewGlobal = 42;

未声明myNewGlobal的...anywhere将创建新的全局。

但我强烈建议不要刻意这样做:这会使代码难以阅读和维护,并且当JavaScript模块变得更加常见和普及时,这些代码将与它们不兼容。如果你真的需要在运行时从一个函数中创建一个全局变量(这已经是一个危险的信号,但也有充分的理由),可以通过在window (或任何引用你的环境中的全局对象的任何东西;在浏览器上是window )上的属性赋值来显式地实现:

window.myNewGlobal = 42;

事实上,我建议使用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());

有点离题,但总的来说,我建议尽可能避免使用全局变量。在浏览器上,全局名称空间已经非常、非常混乱。浏览器使用id为DOM中的每个元素创建全局变量,为大多数带有name的元素创建全局变量,并且有几个预定义的全局变量(如title),它们很容易与您的代码冲突。

相反,只需为自己定义一个很好的作用域函数,并将符号放入其中:

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

    function doSomething() {
    }

    function doSomethingElse() {
    }
})();

如果这样做,您可能希望启用严格模式:

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

    function doSomething() {
    }

    function doSomethingElse() {
    }
})();

如前所述,...which的优点是可以将对未声明的标识符的赋值转换为错误(与various other helpful things一样)。

请注意,在JavaScript模块(在ES2015中添加,但现在才开始使用)中,严格模式在默认情况下是启用的。(ES2015中的新特性class定义也是如此。)

票数 138
EN

Stack Overflow用户

发布于 2011-07-31 18:16:52

忘记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"

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

JavaScript Pattern,作者: Stoyan Stefanov (O‘’Reilly)。版权所有2010年雅虎公司,9780596806750。

票数 27
EN

Stack Overflow用户

发布于 2011-07-31 17:25:56

只有在需要全局访问全局变量时,才能使用全局变量。在这种情况下,您应该在函数外部使用var关键字来声明它们,以清楚地表明您确实希望创建全局变量,并且在尝试声明局部变量时不要忘记var

通常,您应该尝试对代码进行作用域划分,以便在全局作用域中需要尽可能少的代码。在脚本中使用的全局变量越多,将其与其他脚本一起使用的机会就越小。

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

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6888570

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档