Javascript中变量声明语法之间的差异(包括全局变量)?

Javascript中变量声明语法之间的差异(包括全局变量)?,javascript,Javascript,声明变量之间有什么区别吗: var a=0; //1 …这样: a=0; //2 …或: window.a=0; //3 在全局范围内?在全局范围内没有语义差异 但是您确实应该避免a=0,因为您将值设置为未声明的变量 还可以使用闭包来避免编辑全局范围 (function() { // do stuff locally // Hoist something to global scope window.someGlobal = someLocal }()); 在绝对必要

声明变量之间有什么区别吗:

var a=0; //1
…这样:

a=0; //2
…或:

window.a=0; //3

在全局范围内?

在全局范围内没有语义差异

但是您确实应该避免
a=0
,因为您将值设置为未声明的变量

还可以使用闭包来避免编辑全局范围

(function() {
   // do stuff locally

   // Hoist something to global scope
   window.someGlobal = someLocal
}());
在绝对必要的情况下,始终使用封闭装置,并始终提升至全球范围。无论如何,大多数通信都应该使用异步事件处理

正如@AvianMoncellor所提到的,有一个IE bug,它的
var a=foo
只声明了一个全局文件范围。这是IE臭名昭著的坏翻译的问题。这个bug听起来很熟悉,所以可能是真的


因此,请坚持使用window.globalName=someLocalpointer是的,有两个不同之处,尽管实际上它们通常不是很大的差别

有第四种方式,从ES2015(ES6)开始,还有两种。我在末尾添加了第四种方式,但在#1之后插入了ES2015方式(你会看到原因),因此我们有:

var a = 0;     // 1
let a = 0;     // 1.1 (new with ES2015)
const a = 0;   // 1.2 (new with ES2015)
a = 0;         // 2
window.a = 0;  // 3
this.a = 0;    // 4
这些发言解释了这一点 #1
var a=0

这将创建一个全局变量,它也是的一个属性,我们在浏览器上作为
窗口
访问它(或通过
全局范围,在非严格代码中)。与其他一些属性不同,该属性不能通过
delete
删除

在规范术语中,它为对象创建标识符绑定。这使其成为全局对象的属性,因为全局对象是保存全局环境的对象环境记录的标识符绑定的位置。这就是属性不可删除的原因:它不仅仅是一个简单的属性,它是一个标识符绑定

绑定(变量)是在第一行代码运行之前定义的(请参阅下面的“When
var
发生时”)

请注意,在IE8及更早版本中,在
窗口中创建的属性不可枚举(不显示在
for..in
语句中)。在IE9、Chrome、Firefox和Opera中,它是可枚举的


#1.1
设a=0

这将创建一个不是全局对象属性的全局变量。从2015年起,这是一个新事物

在规范方面,它在全局环境的声明性环境记录上而不是对象环境记录上创建标识符绑定。全局环境的独特之处在于有一个拆分的环境记录,一个用于全局对象上的所有旧内容(对象环境记录),另一个用于全局对象上没有的所有新内容(
let
const
,以及由
class
创建的函数)

绑定是在执行其封闭块中的任何分步代码之前创建的(在本例中,是在任何全局代码运行之前),但在分步执行到达
let
语句之前,它无法以任何方式访问。一旦执行到达
let
语句,就可以访问变量。(请参阅下面的“当
常量发生时”。)


#1.2
常数a=0

创建一个全局常量,该常量不是全局对象的属性

const
let
完全相同,只是您必须提供一个初始值设定项(
=value
部分),并且一旦创建了常量,就不能更改其值。在封面下,它与
let
完全相同,但标识符绑定上有一个标志,表示其值不能更改。使用
const
可以为您做三件事:

  • 如果尝试分配给常量,则会导致解析时间错误
  • 为其他程序员记录其不变的性质
  • 让JavaScript引擎在不改变的基础上进行优化

  • #2
    a=0

    这将隐式地在全局对象上创建属性。因为它是普通属性,所以可以删除它。我建议不要这样做,以后阅读您的代码的人可能不清楚。如果使用ES5的严格模式,那么这样做(分配给不存在的变量)是错误的。这是使用严格模式的几个原因之一

    有趣的是,同样在IE8和更早版本中,创建的属性不可枚举(不显示在
    for..in
    语句中)。这很奇怪,特别是考虑到下面的第3条


    #3
    窗口。a=0

    这将使用引用全局对象的
    窗口
    global显式地在全局对象上创建属性(在浏览器上;某些非浏览器环境具有等效的全局变量,例如NodeJS上的
    global
    )。因为它是普通属性,所以可以删除它

    此属性在IE8和更早版本以及我尝试过的所有其他浏览器上都是可枚举的


    #4
    这个.a=0

    与#3完全相同,只是我们通过
    而不是全局
    窗口
    引用全局对象。但是,这在严格模式下不起作用,因为在严格模式全局代码中,
    This
    没有对全局对象的引用(它的值为
    undefined


    删除属性 我所说的“删除”或“删除”
    a
    是什么意思?确切地说:通过
    delete
    关键字(完全)删除属性:

    window.a = 0;
    display("'a' in window? " + ('a' in window)); // displays "true"
    delete window.a;
    display("'a' in window? " + ('a' in window)); // displays "false"
    
    delete
    从对象中完全删除属性。如果通过
    var
    间接向
    窗口添加属性,则无法执行此操作,
    delete
    要么被静默忽略,要么抛出异常(取决于JavaScript实现以及您是否处于严格模式)

    警告:再次执行IE8(
    try {
        delete window.prop;
    }
    catch (e) {
        window.prop = undefined;
    }
    
    display("foo in window? " + ('foo' in window)); // displays "true"
    display("window.foo = " + window.foo);          // displays "undefined"
    display("bar in window? " + ('bar' in window)); // displays "false"
    display("window.bar = " + window.bar);          // displays "undefined"
    var foo = "f";
    bar = "b";
    display("foo in window? " + ('foo' in window)); // displays "true"
    display("window.foo = " + window.foo);          // displays "f"
    display("bar in window? " + ('bar' in window)); // displays "true"
    display("window.bar = " + window.bar);          // displays "b"
    
    a = 0
    
    var a = 0;
    
    window.a = 0;
    
    <title>Index.html</title>
    <script>
        var varDeclaration = true;
        noVarDeclaration = true;
        window.hungOnWindow = true;
        document.hungOnDocument = true;
    </script>
    <script src="external.js"></script>
    
    /* external.js */
    
    console.info(varDeclaration == true); // could be .log, alert etc
    // returns false in IE8
    
    console.info(noVarDeclaration == true); // could be .log, alert etc
    // returns false in IE8
    
    console.info(window.hungOnWindow == true); // could be .log, alert etc
    // returns true in IE8
    
    console.info(document.hungOnDocument == true); // could be .log, alert etc
    // returns ??? in IE8 (untested!)  *I personally find this more clugy than hanging off window obj
    
    <!DOCTYPE html>
    <html>
      <head>
        <script type="text/javascript" src="init.js"></script>
        <script type="text/javascript">
          MYLIBRARY.init(["firstValue", 2, "thirdValue"]);
        </script>
        <script src="script.js"></script>
      </head>
    
      <body>
        <h1>Hello !</h1>
      </body>    
    </html>
    
    var MYLIBRARY = MYLIBRARY || (function(){
        var _args = {}; // private
    
        return {
            init : function(Args) {
                _args = Args;
                // some other initialising
            },
            helloWorld : function(i) {
                return _args[i];
            }
        };
    }());
    
    // Here you can use the values defined in the html as if it were a global variable
    var a = "Hello World " + MYLIBRARY.helloWorld(2);
    
    alert(a);