简体   繁体   English

为什么.join()不使用函数参数?

[英]Why doesn't .join() work with function arguments?

Why does this work (returns "one, two, three"): 为什么这样做(返回“一,二,三”):

var words = ['one', 'two', 'three'];
$("#main").append('<p>' + words.join(", ") + '</p>');

and this work (returns "the list: 111"): 这项工作(返回“列表:111”):

var displayIt = function() {
    return 'the list: ' + arguments[0];
}   
$("#main").append('<p>' + displayIt('111', '222', '333') + '</p>');

but not this (returns blank): 但不是这个(返回空白):

var displayIt = function() {
    return 'the list: ' + arguments.join(",");
}   
$("#main").append('<p>' + displayIt('111', '222', '333') + '</p>');

What do I have to do to my "arguments" variable to be to use .join() on it? 我必须对我的“arguments”变量做什么才能使用.join()?

It doesn't work because the arguments object is not an array, although it looks like it. 它不起作用,因为arguments对象不是数组,尽管看起来像它。 It has no join method: 它没有join方法:

>>> var d = function() { return '[' + arguments.join(",") + ']'; }
>>> d("a", "b", "c")
TypeError: arguments.join is not a function

To convert arguments to an array, you can do: 要将arguments转换为数组,您可以执行以下操作:

var args = Array.prototype.slice.call(arguments);

Now join will work: 现在join将工作:

>>> var d = function() {
  var args = Array.prototype.slice.call(arguments);
  return '[' + args.join(",") + ']';
}
>>> d("a", "b", "c");
"[a,b,c]"

Alternatively, you can use jQuery's makeArray , which will try to turn "almost-arrays" like arguments into arrays: 或者,您可以使用jQuery的makeArray ,它将尝试将“几乎数组”(如arguments转换为数组:

var args = $.makeArray(arguments);

Here's what the Mozilla reference (my favorite resource for this sort of thing) has to say about it: 以下是Mozilla引用 (我最喜欢的这类资源)必须说明的内容:

The arguments object is not an array. arguments对象不是数组。 It is similar to an array, but does not have any array properties except length . 它类似于数组,但除了length之外没有任何数组属性。 For example, it does not have the pop method. 例如,它没有pop方法。 ... ...

The arguments object is available only within a function body. arguments对象仅在函数体中可用。 Attempting to access the arguments object outside a function declaration results in an error. 尝试访问函数声明之外的arguments对象会导致错误。

If you are not interested on other Array.prototype methods, and you want simply to use join , you can invoke it directly, without converting it to an array: 如果您对其他Array.prototype方法不感兴趣,并且只想使用join ,则可以直接调用它,而无需将其转换为数组:

var displayIt = function() {
    return 'the list: ' + Array.prototype.join.call(arguments, ',');
};

Also you might find useful to know that the comma is the default separator, if you don't define a separator, by spec the comma will be used. 另外,您可能会发现逗号是默认分隔符很有用,如果您没有定义分隔符,则通过规范将使用逗号。

Just use the jQuery utility function makeArray 只需使用jQuery实用程序函数makeArray

arguments is not an Array, it is an object. arguments不是一个Array,它是一个对象。 But, since it so "array-like", you can call the jQuery utility function makeArray to make it work: 但是,既然它是“像数组一样”,你可以调用jQuery实用程序函数makeArray使其工作:

var displayIt = function() {
    return 'the list: ' + $.makeArray(arguments).join(",");
}   
$("#main").append('<p>' + displayIt('111', '222', '333') + '</p>');

Which will output: 哪个会输出:

<p>the list: 111,222,333</p>

You could use this jQuery .joinObj Extension/Plugin I made. 你可以使用我制作的这个jQuery .joinObj扩展/插件

As you'll see in that fiddle, you can use it as follows: 正如您在小提琴中看到的那样,您可以按如下方式使用它:

$.joinObj(args, ",");

or 要么

$.(args).joinObj(",");

Plugin Code: 插件代码:

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

You can use typeof to see what's happening here: 您可以使用typeof查看此处发生的情况:

>>> typeof(['one', 'two', 'three'])
"object"
>>> typeof(['one', 'two', 'three'].join)
"function"
>>> typeof(arguments)
"object"
>>> typeof(arguments.join)
"undefined"

Here you can see that typeof returns "object" in both cases but only one of the objects has a join function defined. 在这里,您可以看到typeof在两种情况下都返回“object”,但只有一个对象定义了join函数。

arguments is not a jQuery object, just a regular JavaScript object. arguments不是jQuery对象,只是一个常规的JavaScript对象。 Extend it before you try to call .join() . 在尝试调用.join()之前扩展它。 I think you would write: 我想你会写:

return 'the list:' + $(arguments)[0];

(I'm not too familiar with jQuery, only Prototype, so I hope this is not completely bogus.) (我对jQuery不太熟悉,只有Prototype,所以我希望这不是完全虚假的。)

Edit: It's wrong! 编辑:这是错的! But in his response, Doug Neiner describes what I'm trying to accomplish. 但在他的回答中,道格内纳描述了我想要实现的目标。

I don't know if there's a simple way to convert arguments into an array, but you can try this: 我不知道是否有一种简单的方法将参数转换为数组,但你可以试试这个:

var toreturn = "the list:";
for(i = 0; i < arguments.length; i++)
{
   if(i != 0) { toreturn += ", "; }
   toreturn += arguments[i];
}

At the moment you can't join array arguments, because they aren't an array, shown here 目前您无法加入数组参数,因为它们不是数组,如此处所示

so you have to either first turn them into an array like this, 所以你必须先将它们变成这样的数组,

function f() {
  var args = Array.prototype.slice.call(arguments, f.length);
  return 'the list: ' + args.join(',');
}

or like this, a bit shorter 或者像这样,有点短

function displayIt() {
  return 'the list: ' + [].join.call(arguments, ',');
}

if you are using something like babel or a compatible browser to use es6 features, you can also do this using rest arguments. 如果您使用像babel或兼容的浏览器这样的东西来使用es6功能,您也可以使用rest参数执行此操作。

function displayIt(...args) {
  return 'the list: ' + args.join(',');
}

displayIt('111', '222', '333');

which would let you do even cooler stuff like 这会让你做更酷的事情

function displayIt(start, glue, ...args) {
  return start + args.join(glue);
}

displayIt('the start: ', '111', '222', '333', ',');

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM