最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Weird Javascript Array.prototype.constructor.apply behaviour - Stack Overflow

programmeradmin0浏览0评论

I am having this wired behaviour with javascript array. My objective is the create a new array form another array. My approach is following;

Array.prototype.constructor.apply(Array, [1,2])

and it creates a new array with 2 element in them [1,2] that works fine but when i put something like this..

Array.prototype.constructor.apply(Array, [3])

that is to create a array with one element in it i.e [3]... it creates

[undefined,undefined,undefined]

that is it creates an array with 3 empty elements!! Any idea why? and how i can create a new array object this way??

I am having this wired behaviour with javascript array. My objective is the create a new array form another array. My approach is following;

Array.prototype.constructor.apply(Array, [1,2])

and it creates a new array with 2 element in them [1,2] that works fine but when i put something like this..

Array.prototype.constructor.apply(Array, [3])

that is to create a array with one element in it i.e [3]... it creates

[undefined,undefined,undefined]

that is it creates an array with 3 empty elements!! Any idea why? and how i can create a new array object this way??

Share Improve this question asked Sep 26, 2013 at 14:27 user1179563user1179563 1233 bronze badges 4
  • Are you just trying to copy an array? – Evan Davis Commented Sep 26, 2013 at 14:33
  • No i was trying to create a new array form an existing one... – user1179563 Commented Sep 26, 2013 at 14:38
  • and that is different from copying because... – Evan Davis Commented Sep 26, 2013 at 14:41
  • :) not really different :) i guess you are right – user1179563 Commented Sep 26, 2013 at 15:32
Add a ment  | 

6 Answers 6

Reset to default 8

That's because the Array constructor with one argument, n, produces an array with n elements. With more arguments, it creates an array consisting of those arguments in order.

Actually your code is not calling Array as a constructor: Array.prototype.constructor.apply(Array, [3]) is more like Array(3) than new Array(3). However, Array behaves the same with and without new.

This all begs the question of why you're doing this in the first place when you could just use an array literal. If you're trying to copy an array, using its slice method is a simple way:

var a = [1, 2];
var copy = a.slice(0);
Array.prototype.constructor.apply(Array, [1,2])

It should have been Array.apply(null, [1, 2]) actually. Array.prototype.constructor === Array, and when you do new Array(1, 2) you're not applying it on the Array constructor function but on nothing.

when i put something like Array.prototype.constructor.apply(Array, [3]) it creates an array with 3 empty elements!! Any idea why?

That's how the Array constructor is supposed to work. When it gets called with a single numerical argument, it will create a new empty array with that .length (and you're doing that: new Array(3)).

My objective is the create a new array from another array.

Use the slice Array method for that:

[1, 2].slice();
// or, plicated, but works with array-like objects:
Array.prototype.slice.call([1, 2]);

The first ctor parameter of Array is length of the array, if passed, new Array(3) would for example create and array with 3 elements, but all elements are undefined of cause.

Because you use apply, the 2nd parameter of apply is the arguments array you pass in to the method you apply it to.

That means, if your arguments array you apply contains only one element, the default constructor new Array(<numofelemnts>) will get excecuted.

Remember that func.apply(obj, [1,2]) is the same as obj.func(1,2). And new Array(3) has the same result you gave above - [undefined,undefined,undefined]. Blame it on the spec, but that's how it works. You have to pass more than one argument in order to have them populate the array.

You just need to use concat or slice on the original array. You don't need to bother with prototypical calls, because that is reserved for creating a copy of the arguments list, in order to convert it to an array:

var new_array_copy = existing_array.slice(0)

The arguments functionality I am talking about:

function a_function_with_some_arguments(/* arguments */) {
    // Convert the special arguments list into an array
    var args = Array.prototype.slice.call(arguments, 0);

    // Returns a reference to the new copy of the arguments list.
    return args;
}

Mozilla's MDN has a good description on why this is happening, but here's the short of it:

The Array object has two constructors.

In your first version, you're providing 2 arguments, which the Array object understands as "Create an Array with the specified values."

In your second version, you're providing 1 argument, which the Array object understands as "Create an empty array with space to hold the number specified in the argument."

So if you want an array with one object, I'd remend bypassing the constructor.apply syntax and use something a little more readable (i.e. var array = [3];)

发布评论

评论列表(0)

  1. 暂无评论