声明空javascript变量的最佳实践

时间:2013-06-04 08:18:11

标签: javascript

在为它们分配值之前,在javascript中声明变量时是否有类似的最佳实践?有时它是因为范围原因所必需的,但如果范围无关紧要怎么办?

// Declare first
(function() {
    var foo = 'bar',
        a = 500,
        b = 300,
        c;

    // Some things get done here with a and b before c can use them...

    c = a * b;    

    // c is now ready to use...
    doSomething(c);
}());

// Declare when needed
(function() {
    var foo = 'bar',
        a = 500,
        b = 300;

    // Some things get done here with a and b before c can use them...

    var c = a * b; 

    // c is now ready to use...
    doSomething(c);
}());

我也想知道与对象文字相似的最佳做法是什么:

// Add property with null assigned to it
var myObj = {
    foo: null,

    doSomething: function() {
        this.foo = 'bar';
    }
};

// Property gets added when value is set
var myObj = {
    doSomething: function() {
        this.foo = 'bar';
    }
};

1 个答案:

答案 0 :(得分:19)

这主要是风格问题。

由于var声明自动hoisted up到示波器的顶部,因此将它们置于其作用域的顶部是有意义的,这样您就可以更接近解释器执行它的方式读取代码

在其范围顶部声明变量为Crockford's recommendation。它确实有意义,因为它清除了一些常见的误解。

例如:

for (var i = 0; i < 3; i++) {
    setTimeout(function() {
        console.log(i);
    }, 0);
}

由于var具有函数作用域,因此所有迭代(及其中的函数)都引用相同的i。由于所有三个定时函数将在循环结束后执行,因此上面的代码段会将3三次记录。

现在对于具有块体验范围经验的人来说,上述行为并不十分清楚。重写代码段:

var i;
for (i = 0; i < 3; i++) {
    // ...
}

现在,i在全局范围内声明,与上一个片段完全相同。但是,这一点在这方面要清楚得多。


另一种误解:

(function() {
    if (true) {
        var foo = 1;
    } else {
        var foo = 1;
    }
}());

同样,在块范围的语言中,上述内容完全有效。但是,由于var声明在解析时被提升到当前函数范围的顶部,因此上述内容相当于:

(function() {
    var foo;
    var foo;
    if (true) {
        foo = 1;
    } else {
        foo = 1;
    }
}());

变量被声明两次。大多数浏览器只会忽略第二个声明,代码将“正常工作”,但JSHint等静态代码分析工具会对你大喊大叫。

你可以只用一个声明重写它,它完全有效:

(function() {
    if (true) {
        var foo = 1;
    } else {
        foo = 1;
    }
}());

但像我一样的类似强迫症的编码员会觉得它很难看。再次,在范围的顶部声明:

(function() {
    var foo;
    if (true) {
        foo = 1;
    } else {
        foo = 1;
    }
}());

看起来更整洁。


同样,这主要是风格问题。就个人而言,如果我有一个巨大的功能,我讨厌一直向上滚动,只是为了检查变量是否已经声明并将其添加到列表中。在这种情况下,我可能会在函数中间添加几个var声明(针对Crockford的推荐),我个人认为这些声明更易于阅读和维护。

因为这是一个风格问题,所以请确保您的代码最易于维护和简洁。


在硬币的另一面,我承认,就个人而言,我已经开始并且在首次使用变量时大多使用var声明。这是该语言的一个方面,您可以毫无问题地使用它。

但我也承认,如果我从一开始就遵循Crockford的建议,我就会有更少的麻烦(如上面所示的误解),并且会更快地掌握JavaScript的函数范围方面。


¹请注意,JS 1.7通过let引入了块范围的变量,但它尚未得到广泛支持。