4

在这样的情况下,我听到了关于使用的不同意见var

function(maybeUndefined) {
    if(typeof maybeUndefined === 'undefined')
        var maybeUndefined = 'bob';
}

是否有必要标注var,因为maybeUndefinedargumentof function

4

4 回答 4

10

var在这种情况下,您不需要,因为mayBeUndefined它已经在函数范围内分配(提示:在函数定义中列出参数变量会导致这些变量在本地声明)。因此,这var完全是可选的,尽管完全没有意义(并且会降低可读性)。

于 2013-05-29T20:46:41.660 回答
6

例子:

function func ( arg1, arg2 ) {
    var local1, local2;

    function nested1 () {}
    function nested2 () {}

    // other code
}

这里我们有一个函数声明。当将此声明解析为函数对象时,将为该函数创建一个词法环境(= 范围),并具有以下绑定:

  • 参数1
  • arg2
  • 本地1
  • 本地2
  • 嵌套1
  • 嵌套2
  • 这个
  • 论据

(注意还有两个特殊的内置绑定:thisarguments。它们总是为所有函数对象创建的。)

这些名称被定义为本地绑定。(这个过程在“声明绑定实例化”中有详细说明。警告:这个算法并不意味着人类可以阅读:-))因此,当一个名字被定义为一个参数时,没有必要将它声明为一个局部变量。此机制与调用函数时是否为该参数传递值(参数)无关。

所以,即使你像这样调用函数:

func(123);

该名称arg2仍将被定义(作为函数环境中的绑定),尽管它的值最初将undefined用于该特定调用。

顺便说一句,如果您使用严格的语言(推荐!),函数环境是静态的,这意味着上述绑定保证是函数环境中的唯一绑定。另一方面,默认语言提供了某些机制来动态函数环境中添加/删除绑定。例子:

(function () {

    // the name "temp" does not exist as a binding in the function's environment

    eval('var temp');

    // now it does

    delete temp;

    // and it's gone again

}());
于 2013-05-29T20:58:34.563 回答
3

您不应该var再次使用,它不利于可读性,并且由于作为参数,该变量已经在本地范围内。

另外,您应该注意它不是this. this如果使用了关键字,则仅将作用域限定为函数对象new,并且由于您没有命名函数,因此在这种情况下似乎不太可能。如果没有 new,this则指的是 window(或者 is undefinedifuse strict;被使用),由于参数具有局部范围,因此您的变量绝对不是其中的一部分。

于 2013-05-29T20:51:18.460 回答
1

界面

包含函数参数实际上与定义变量的范围相同(换句话说,它实际上与使用var关键字定义函数级引用相同)。提供函数参数(在 JavaScript 中)的主要原因是您自己的接口偏好。

arguments对象_

参数仍然可以传递给没有参数的函数,并且仍然可以在“隐藏”arguments对象中访问——这是一种“伪数组”(如果你愿意的话),因为它在功能上是一个数组,但不是配备相同的 API JavaScript 配备Array(伪类型):

// The following functions do the same thing, but one is "more readable"

function foo() {
  return arguments;
}

function bar(baz, qux) {
  return arguments;
}

评估(接口)与执行(实现)

当两个函数都被评估时(在文件'load'上),arguments对象undefined在每个函数定义中;在函数体执行其中的代码之前,该对象不会成为“已定义” ;使用伪代码将其可视化,它看起来像这样:

// Function bodies (as objects)
foo : {
  arguments : new Array // [undefined]
  __proto__ : Empty() // the super-object that allows this object to inherit "functionality"
}

bar : {
  arguments : new Array(baz, qux) // [undefined, undefined]
  __proto__ : Empty()
}

函数调用

所以当你调用一个函数时,它“实现”或“执行”它的主体(它的“对象”)。当它这样做时,如果已经定义了已推入arguments对象的对象,则该函数可以引用它们。如果不是,将引发引用错误,记录变量undefined在该范围内。

简而言之:

没有必要使用接口函数范围级变量(也称为“私有成员”),var因为该语言已经将arguments对象附加到所有function主体对象。

更多阅读:

JavaScript 记忆:“函数缓存”多个参数以获得更好的性能: http ://decodize.com/javascript/javascript-memoization-caching-results-for-better-performance/

于 2013-05-29T21:28:05.517 回答