Javascript局部变量技术

时间:2009-01-23 15:00:39

标签: javascript variables local

我有一个与单行编程有关的简单问题。首先是一个例子:

function test(a)
{
   var b=a.toString();
   return b.replace("a","b");
}

这很简单(这个功能当然没用),但这里的问题稍微复杂一点:如果我在一行中做这个怎么办?我有自己的想法,但请告诉我这对于内存清理是否正常工作:

function test(a)
{
   return (arguments[1]=a.toString()).doSomething().doSomethingMore(arguments[1]);
}

这当然是一个例子,但这个想法很简单:使用参数作为局部变量的容器 - 我不确定,但据我所知,当函数结束时,参数也会被删除吗?或者在参数中创建新元素是否会使该元素全局定义?从我的测试看来,我是正确的,但我很想知道是否有人试过这个?这是一个安全而干净的解决方案吗?:)感谢您提出任何意见。

以下是One-Line脚本问题的更实际问题:

function (number,limiter)
{
return ((arguments[2] = number.toString().replace(
         new RegExp("(\\d+)(\\d{3})($|"+limiter+")"),
         '$1'+limiter+'$2$3')) == number) ?
            arguments[2] : 
            arguments.callee(arguments[2],limiter);
}

这一行函数用给定的字符串做事并返回它或递归地解析它到同一个函数。 (在其他线程上,我展示了如何在没有递归的情况下完成此操作,但这不是一个问题的例子)。

6 个答案:

答案 0 :(得分:4)

你不必要地使操作复杂化。你根本不需要申报任何东西。

function test(a) {
return a.toString().replace("a","b");
}

这不应该对性能或内存产生影响。

但是,如果您要使用闭包,则可能会遇到内存问题。

像你正在做的那样为arguments数组赋值是没有意义的,因为每个函数都有自己的arguments数组。为了解决有关范围的问题,Javascript范围是词法;函数外部的东西不能自动访问函数内部声明的东西。

编辑:使用arguments数组不比任何其他方法更清晰或更好。它实际上比清楚更糟糕。

答案 1 :(得分:4)

您的示例可能会使一个简单的操作过于复杂,但您演示的技术称为方法'链接'。它是一种完全有效的形式,实际上可用于在不需要或有意义的中间结果时使代码更具可读性。

我目前最喜欢的例子是精彩的DateJs

var nextTuesday = DateJs.today().next().tuesday();

var aBitLater = DateJs.now().addHours(1).addMinutes(30);

当然,它是语法糖,并且可以作为单独的陈述更详细地编写,但是通过仔细的方法命名,您实际上可以使其读起来像英语。

GC /内存管理不受此样式的影响,函数的参数与其他参数一样被清除。实际上它实际上可能更安全,因为在函数调用返回后参数会立即超出范围,并且不需要为值创建局部变量而只是将它们传递给下一个函数调用。

你的例子可能有点做作,但如果你在有意义的地方使用它,它就是一个有用的模式。

答案 2 :(得分:1)

“调试的难度是首先编写代码的两倍。因此,如果您尽可能巧妙地编写代码,那么根据定义,您可能不够聪明,无法对其进行调试。” - Brian W. Kernighan

我不是在敲你,我只是说小心不要过分热心。

答案 3 :(得分:0)

我认为你只需要尝试阅读它就能意识到这不是一个“干净”的解决方案! 我特别避免链接这样的任务:

return (arguments[1]=a.toString()).doSomething().doSomethingMore(arguments[1]);
// is this a or a.toString()? it's not clear at a glance -------------^

答案 4 :(得分:0)

为什么要避免在本地创建变量?这样做可以使代码更易于阅读/理解,而且我认为你并没有真正获得任何东西。

变量基本上只是对您正在创建的对象的引用。无论是将它们分配给普通变量还是将它们放入数组中,清理都是一样的。一旦方法返回,参数数组和局部变量都将超出范围,所以我认为你不会看到行为上的任何差异。 (如果通过apply()命令调用该方法,则arguments数组的范围可能不同,但我没有测试过这一点。)

答案 5 :(得分:0)

~~颤动~~

这让我想起awk,除非你在参数列表中声明额外的变量,否则除非在函数列表中声明额外的变量,否则无法在函数中使用局部变量。

如果你需要一个局部变量,那就去做吧。