为什么.join()不能使用函数参数?
为什么这个工作(返回“一,二,三”):
var words = ['one', 'two', 'three']; $("#main").append('<p>' + words.join(", ") + '</p>');
和这个工作(返回“列表:111”):
var displayIt = function() { return 'the list: ' + arguments[0]; } $("#main").append('<p>' + displayIt('111', '222', '333') + '</p>');
但不是这样(返回空白):
var displayIt = function() { return 'the list: ' + arguments.join(","); } $("#main").append('<p>' + displayIt('111', '222', '333') + '</p>');
我有什么要做我的“参数”variables是使用.join()呢?
它不起作用,因为arguments
对象不是数组,虽然它看起来像。 它没有join
方法:
>>> var d = function() { return '[' + arguments.join(",") + ']'; } >>> d("a", "b", "c") TypeError: arguments.join is not a function
要将arguments
转换为数组,可以这样做:
var args = Array.prototype.slice.call(arguments);
现在join
将工作:
>>> var d = function() { var args = Array.prototype.slice.call(arguments); return '[' + args.join(",") + ']'; } >>> d("a", "b", "c"); "[a,b,c]"
或者,你可以使用jQuery的makeArray
,它将尝试将“几乎数组”的arguments
变成数组:
var args = $.makeArray(arguments);
下面是Mozilla的参考资料 (我最喜欢的资源)就是这样说的:
arguments
对象不是一个数组。 它与数组类似,但除length
外没有任何数组属性。 例如,它没有pop方法。 …
arguments
对象只能在函数体中使用。 尝试访问函数声明外的参数对象会导致错误。
如果您对其他Array.prototype
方法不感兴趣,并且只想使用join
,则可以直接调用它,而不必将其转换为数组:
var displayIt = function() { return 'the list: ' + Array.prototype.join.call(arguments, ','); };
另外,如果你没有定义一个分隔符,你可能会发现这个逗号是默认的分隔符,按照规格 ,逗号将被使用。
只需使用jQuery实用程序函数makeArray
arguments
不是一个数组,它是一个对象。 但是,既然它是“数组”的,你可以调用jQuery实用函数makeArray
使其工作:
var displayIt = function() { return 'the list: ' + $.makeArray(arguments).join(","); } $("#main").append('<p>' + displayIt('111', '222', '333') + '</p>');
哪个会输出:
<p>the list: 111,222,333</p>
你可以使用这个jQuery .joinObj扩展/我所做的插件 。
正如你将在小提琴中看到的那样,你可以使用它如下:
$.joinObj(args, ",");
要么
$.(args).joinObj(",");
插件代码:
(function(c){c.joinObj||(c.extend({joinObj:function(a,d){var b="";if("string"===typeof d)for(x in a)switch(typeof a[x]){case "function":break;case "object":var e=c.joinObj(a[x],d);e!=__proto__&&(b+=""!=b?d+e:e);break;default:"selector"!=x&&"context"!=x&&"length"!=x&&"jquery"!=x&&(b+=""!=b?d+a[x]:a[x])}return b}}),c.fn.extend({joinObj:function(a){return"object"===typeof this&&"string"===typeof a?c.joinObj(this,a):c(this)}}))})(jQuery);
你可以使用typeof来看看这里发生了什么:
>>> typeof(['one', 'two', 'three']) "object" >>> typeof(['one', 'two', 'three'].join) "function" >>> typeof(arguments) "object" >>> typeof(arguments.join) "undefined"
在这里你可以看到typeof在两种情况下都返回“object”,但是只有一个对象定义了连接函数。
arguments
不是一个jQuery对象,只是一个普通的JavaScript对象。 在尝试调用.join()
之前将其扩展。 我想你会写:
return 'the list:' + $(arguments)[0];
(我不太熟悉jQuery,只有Prototype,所以我希望这不是完全假的。)
编辑:这是错的! 但是在他的回应中,Doug Neiner描述了我想要完成的事情。
我不知道是否有一个简单的方法来将参数转换成数组,但你可以试试这个:
var toreturn = "the list:"; for(i = 0; i < arguments.length; i++) { if(i != 0) { toreturn += ", "; } toreturn += arguments[i]; }
目前你不能join数组参数,因为它们不是数组, 如下所示
所以你必须先把它们变成像这样的数组,
function f() { var args = Array.prototype.slice.call(arguments, f.length); return 'the list: ' + args.join(','); }
或者像这样,缩短一点
function displayIt() { return 'the list: ' + [].join.call(arguments, ','); }
如果您正在使用类似babel或兼容的浏览器来使用es6function,您也可以使用rest参数来执行此操作。
function displayIt(...args) { return 'the list: ' + args.join(','); } displayIt('111', '222', '333');
这会让你做更酷的东西
function displayIt(start, glue, ...args) { return start + args.join(glue); } displayIt('the start: ', '111', '222', '333', ',');