2

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

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

这很简单(这个函数当然没用),但这里的问题稍微复杂一点:如果我要在一行中完成这个怎么办?我有我的想法,但请告诉我这在内存清理方面是否正常工作:

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

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

这是一个更实际的单行脚本问题:

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);
}

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

4

6 回答 6

4

您不必要地使操作复杂化。你根本不需要声明任何东西。

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

这不应该对性能或内存造成影响。

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

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

编辑:使用参数数组并不比任何其他方法更干净或更好。这实际上比清楚更糟糕。

于 2009-01-23T15:12:46.107 回答
4

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

我目前最喜欢的例子是美妙的DateJs

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

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

当然,它是语法糖,可以更冗长地写成单独的语句,但是通过仔细的方法命名,您实际上可以使它读起来像英语。

GC / 内存管理不受这种风格的影响,函数的参数和其他的一样被清理。事实上,它实际上可能更安全,因为参数在函数调用返回后立即超出范围,并且不需要为值创建本地变量只是为了将它们传递给下一个函数调用。

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

于 2009-01-23T15:21:44.937 回答
1

“首先,调试的难度是编写代码的两倍。因此,如果你尽可能巧妙地编写代码,那么根据定义,你就不够聪明,无法调试它。” ——布赖恩·W·克尼根

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

于 2009-01-23T15:13:45.263 回答
0

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

return (arguments[1]=a.toString()).doSomething().doSomethingMore(arguments[1]);
// is this a or a.toString()? it's not clear at a glance -------------^
于 2009-01-23T15:08:48.393 回答
0

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

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

于 2009-01-23T15:12:22.333 回答
0

~~颤抖~~

这让我想起了awk在函数中没有局部变量的地方,除非您在参数列表中声明额外的变量。

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

于 2009-01-23T15:19:25.610 回答