How is this possible without instantiating (new-'ing): var a = Array.prototype.slice.call (arguments)?

In a context within a function, here's the code (based on the standard template for creating a function "arguments" into an array):

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

I'm trying to learn this (JavaScript newbie starting in C #).

I understand that it slice

is an instance method due to the fact that it is a function prototype

for an array.

I also understand that this is not a static "utility function", that is, to use it, you have new

to do it like this: (example)var myArray = new Array(); myArray.slice(...);

call

passes the object here to change the context to arguments

In this regard, I also don't know the difference between Array.prototype.slice.call([32,32,121,412])

and Array.prototype.slice([32,32,121,412])

not in context call

.

So here's my question:

I just don't understand how this works in relation to instance versus static methods ... so can someone explain the finer points var args = Array.prototype.slice.call(arguments);

?

Why can this be used without calling new

?

Why is this possible? This is not a static method and it should be "new" and it only works when using a function call

... (at least in my C # mentality ...)

+2


source to share


4 answers


Unlike C # / Java, functions are actually first-class citizens of JavaScript.

In its general sense:

This means there is no need to "update" it. It works exactly the same way as because it is its own object.

A "new" function (in a general sense) simply changes the 'this' value of that function to the variable to which it will be assigned and then returns it.



It is possible to use a function in JavaScript without "newbies", because they are "first-class citizens" in JavaScript.

In a deeper sense, this is what "new" does:
- it creates a new object derived from MyConstructor.prototype
- assigns the value of the constructor function's 'this' to the new object
- execute the code inside (adds properties to the new object / instance)
- returns a new one an object

A couple of additional notes on what I learned from instances:
- they don't have a .prototype property like their constructor functions
- although they do have a [[prototype]] property derived from MyConstructor.prototype
- overriding a property on an instance masks the object MyConstructor.prototype [property] ..

0


source


The difference between Array.prototype.slice.call([32, 32, 121, 412])

and Array.prototype.slice([32, 32, 121, 412])

is that in the first case, the actual Array

[32, 32, 121, 412]

becomes the "this" object to call. In other words, it is exactly the same as this code: [32, 32, 121, 412].slice()

. Just calling slice

on the prototype does it in the context of the prototype object, which probably won't do anything.



+1


source


When you add a function to an object's prototype, it becomes a function that you can use on instances of that object. The context of this function is the instance. i.e.

Array.prototype.myFunction = function() {
     alert( this[0] ); // this should refer to the Array instance
};
var x = new Array(1);
x[0] = 5;
x.myFunction(); // alerts 5

      

However, sometimes you may have an array-like structure that is not a subclass or instance of an array (such as an Arguments object). What a function calling method does is change the context to whatever has the first parameter to call. In this case, the invocation method is called on the Array prototype function. In all reality Array.prototype.myFunction

, it is simply a function defined in the above code block. call

is a method that can be called on any function to change its context. Therefore, instead of an Array instance, you must have an arguments object as a context.

function foo() {
    Array.prototype.myFunction.call( arguments ); // arguments is [6]
    // alerts 6
}
foo( 6 );

      

Additional information about call

.

+1


source


I think you may be confused about the behavior of "instance" and "static" methods in languages ​​like Java that have classes. JavaScript doesn't work the same way.

Also you are confused with another issue, since all JS function calls work in terms of setting this

inside the called function (i.e. setting which object the function will work on is likely to work) and what effect .call()

matters this

.

A method is .slice()

defined as a property Array.prototype

, not as a Java-style "instance method" on separate array instances. You can call Array.prototype.slice()

unnecessarily an instance of an array created with new

.

When you speak:

myArray.slice()

      

JS will first see if the .slice()

method of the object is valid myArray

and then (given that it is not) it will see if it is the Array prototype method that it is, so it runs that method.

When you call any JS function with dot notation, i.e. myArray.slice()

, inside this function, a special variable will be assigned to the object this

. this

is a reference to the object on which the function should work. But if you call a JS function with .call()

, within that function this

, the object you pass as a parameter to .call()

. So

myArray.slice()

      

says to call .slice()

and work with myArray

.

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

      

Says to call .slice()

and work with himarguments

PS don't use var myArray = new Array();

- better sayvar myArray = [];

+1


source







All Articles