我遇到了一个javascript难题:
编写一行JavaScript代码,用于连接传递给函数的所有字符串:
function concatenate(/*any number of strings*/) {
var string = /*your one line here*/
return string;
}
@ meebo
看到函数参数表示为索引对象可能是一个数组,我认为可以以递归方式完成。但是我的递归实现会抛出错误。 - “conc.arguments.shift不是函数” -
function conc(){
if (conc.arguments.length === 0)
return "";
else
return conc.arguments.shift() + conc(conc.arguments);
}
似乎conc.arguments不是数组,但可以通过数字索引访问并具有长度属性???令人困惑 - 请分享意见和其他递归实施。
由于
答案 0 :(得分:12)
arguments
is said to be类似于数组的对象。正如您已经看到的那样,您可以通过索引访问其元素,但是您没有所有可用的Array方法。类似Array的对象的其他示例是getElementsByTagName()或getElementsByClassName()返回的HTML集合。 jQuery,如果你曾经使用它,它也是一个类似数组的对象。在查询了一些DOM对象之后,在DOM选项卡中使用Firebug检查生成的jQuery对象,你会看到我的意思。
这是我对Meebo问题的解决方案:
function conc(){
if (arguments.length === 0)
return "";
else
return Array.prototype.slice.call(arguments).join(" ");
}
alert(conc("a", "b", "c"));
Array.prototype.slice.call(arguments)
是将arguments
转换为可验证的Array对象的好方法。在Firefox Array.slice.call(arguments)
就足够了,但它在IE6中不起作用(至少),所以前一版本是常用的。此外,这个技巧不适用于IE6中DOM API方法返回的集合(至少);它会抛出一个错误。顺便说一下,可以使用call
代替apply
。
关于类似数组的对象的一点解释。在JavaScript中,您可以使用几乎任何东西来命名对象的成员,而数字也不例外。所以你可以构造一个看起来像这样的对象,这是完全有效的JavaScript:
var Foo = {
bar : function() {
alert('I am bar');
},
0 : function() {
alert('I am 1');
},
length : 1
}
上述对象是一个类似于Array的对象,原因有两个:
length
属性,没有该属性,您无法使用构造将对象转换为可验证的数组:Array.prototype.slice.call(Foo);
Function对象的arguments对象与Foo对象非常相似,只是它有其特殊用途。
答案 1 :(得分:7)
arguments对象不是数组。它 类似于数组,但没有任何数组 除长度外的属性。例如, 它没有pop方法。 但它可以转换为真实的 阵列:
var args = Array.prototype.slice.call(arguments);
因此,您的问题的解决方案非常简单:
var string = Array.prototype.slice.call(arguments).join("");
BTW:它进一步指出:
arguments对象是本地的 所有变量都可用 功能;作为财产的论据 无法再使用该功能。
您应该只使用arguments
代替func.arguments
答案 2 :(得分:6)
这有效:
function concatenate(){
return [].join.call(arguments, "");
}
alert(concatenate("one", "two", "three"));
答案 3 :(得分:1)
参数列表不是真正的数组。我认为你可以借用数组方法并在带有“call”或“apply”的参数上使用它们。
答案 4 :(得分:1)
你可以这样做:
function concatenate() {
if (arguments.length > 1) {
return arguments[0] + concatenate.apply(this, Array.prototype.splice.call(arguments, 1));
}
return arguments[0];
}
答案 5 :(得分:0)
它可以与Array.prototype
的至少6种不同方法(我怀疑还有更多)配合使用,即join
,slice
,splice
,concat
, reduce
,flat
。可能最短的方法是使用join
,这是@@ svinto的上述解决方案。 g
与@GeorgSchölly的答案相同。
Voilà的六个解决方案:
function f(){
return [].join.call(arguments,'');
}
function g(){
return [].slice.call(arguments).join('');
}
function h(){
return [].splice.call(arguments,0).join('');
}
function i(){
return [].concat.apply([], arguments).join('');
}
function j(){
return [].reduce.call(arguments,function(buff,x){return buff+x},'');
}
function k(){
return [].flat.call(arguments).join('');
}
document.getElementById('F').textContent = f('a','b','c');
document.getElementById('G').textContent = g('a','b','c');
document.getElementById('H').textContent = h('a','b','c');
document.getElementById('I').textContent = i('a','b','c');
document.getElementById('J').textContent = j('a','b','c');
document.getElementById('K').textContent = k('a','b','c');
<pre id='F'></pre>
<pre id='G'></pre>
<pre id='H'></pre>
<pre id='I'></pre>
<pre id='J'></pre>
<pre id='K'></pre>