Array expansion in JavaScript parameters [translation]_javascript tips

Source: Internet
Author: User
Tags in python

Translator Note: This article is about the ECMAScript 6 knowledge points, if you do not even understand the ES5. I must say, you are very behind. CSS4,HTML6, even ES7 ES8 have already begun planning, hurriedly shape move up, otherwise eliminated!

Sometimes we need to expand an array into multiple elements and then take these elements as arguments to the function call. In JavaScript, you can use Function.prototype.apply to implement this expansion , However, it cannot be applied in the case of a constructor. This article explains what an unwind operation is and how to expand the operation with the new operator.

1. Unfold (spreading)

Expanding means providing the required arguments in a function call or method call, or when executing a constructor, using an array. In Python, this operation is called unpacking. Ecmascript.next already has (expand operator) spread operator (represented as a prefix ...) To perform this expansion. In the current JavaScript, you can achieve the same effect by Function.prototype.apply methods.

The expansion operator can also be used in the position of the parameter to represent the remaining parameters, in addition to being able to use the position of the argument and the array to expand. Please see my translated MDN document remaining parameters

2. Expand function Parameters

The Math.max () method returns the maximum value of its arguments from 0 to several numeric types. With the expand operator, you can use an array directly as an argument:

Math.max (.....) [13, 7, 30])
This is equivalent to the following wording

Copy Code code as follows:

Math.max (13, 7, 30)

In the current JavaScript, you can use apply ().
Copy Code code as follows:

> Math.max.apply (NULL, [13, 7, 30])
30

The Apply method works by using the following calling method:
Copy Code code as follows:

Func.apply (Thisvalue, [param1, Param2, ...])

To replace this
Copy Code code as follows:

Thisvalue.func (param1, param2, ...)

It should be noted that Func is not necessarily a thisvalue method, and apply allows it to temporarily own this method.

3. Expand the parameters of the constructor

The date constructor accepts arguments for several numeric types, resulting in a Date object. By expanding the operator, you can pass in an array directly.
Copy Code code as follows:

New Date (...). [2011, 11, 24]) Christmas Eve of 2011

However, this time we cannot use the Apply method to implement the unwind operation because it cannot work with new:
Copy Code code as follows:

> New date.apply (NULL, [2011, 11, 24])
Typeerror:function apply () {[native code]} is not a constructor

The new operator expects Date.apply to be a constructor. Even if you enclose this expression in parentheses, the fundamental problem persists: Apply performs a function call that cannot pass arguments to the new operator.

3.1 Solutions
First step. Let's first make the result correct, and then consider how to use an array instead of the split argument.

Copy Code code as follows:

New (Date.bind (NULL, 2011, 11, 24))

We first use BIND () to create a function without parameters (the parameter is already bound to the inside of the bound function), and then call it with new, just like calling a normal constructor. The function signature of bind is as follows:
Copy Code code as follows:

Func.bind (Thisvalue, arg1, arg2, ...)

The BIND function converts the original function func into a whole new function, this new function This value is always a parameter Thisvalue The specified value, and its initial parameters contain all parameters starting from Arg1 to the last. When this new function is invoked, the newly added parameters are followed by the existing after the parameters of bind bind. More detailed information is available on the MDN. Note In the above example, the first parameter is NULLBecause The date function does not require a Thisvalue: When called as a constructor, the The new operator overrides the T specified by bind Hisvalue.

Step two. we want to pass the array to bind. So again , apply is used to convert an array to an expanded parameter to pass to the BIND function .

Copy Code code as follows:

New (Function.prototype.bind.apply (
Date, [Null].concat ([2011, 11, 24]))


We've raised the Apply method on the function Function.prototype.bind with two parameters:

• First parameter: This value is specified as date and is equivalent to the Date.bind (...) written above.
• Second parameter: A new array of parameters passed to the Bind method, NULL, and subsequent arrays [2011, 11, 24].

3.2 A library function

Mozilla recommends that the above work be encapsulated into a library method. The following code is slightly modified on top of their recommendations:

Copy Code code as follows:

if (! Function.prototype.construct) {
Function.prototype.construct = function (Argarray) {
if (! Array.isarray (Argarray)) {
throw new TypeError ("Argument must is an array");
}
var constr = this;
var nullaryfunc = Function.prototype.bind.apply (
Constr, [Null].concat (Argarray));
return new Nullaryfunc ();
};
}

Run it:
Copy Code code as follows:

> date.construct ([2011, 11, 24])
Sat Dec 00:00:00 gmt+0100 (CET)

3.3 A seemingly simpler solution
You can manually implement the operation of the new operator. For example:
Copy Code code as follows:

var foo = new Foo ("abc");

is actually equivalent to:
Copy Code code as follows:

var foo = object.create (Foo.prototype);
Foo.call (foo, "abc");

Based on this principle, we can write a simple library method:
Copy Code code as follows:

Function.prototype.construct = function (Argarray) {
var constr = this;
var inst = object.create (Constr.prototype);
Constr.apply (inst, argarray);
Return inst;
};

Alas! Date is called as a normal function and invoked as a constructor: it ignores the this value specified by the first parameter in call () and the Apply () method, and always generates and returns a new instance.

Translator Note: Here the author is mistaken, date as a normal function call and called as a constructor is completely different. Without the new, date () will only return the string of the current time, that is, (new Date ()). ToString ()
Copy Code code as follows:

> date.construct ([2011, 11, 24])
{}

Translator Note: In the built-in constructor, array (), function (), REGEXP (), error (), and so on are called with new or no more. For example, array (10) is also an array, but number (), String (), Boolean () is not the same. No new. They are type conversion functions that return the original value, plus new is the constructor, and the object value is returned.
Copy Code code as follows:

>typeof number ("1")
"Number"
>typeof New Number ("1")
"Object"

As you can see, when you manipulate the date () method, the construct () method we write does not work as expected, and there are other built-in constructors that behave like date. But if you're manipulating a custom constructor in a library, This method is basically functional (a few constructors return the object value that they specify instead of returning the default auto-generated instance of this).

A constructor's return statement will overwrite the default this value as long as it returns an object value. For example:
Copy Code code as follows:

function Func1 () {
This.value = "this"; return {}
}

function Func2 () {
This.value = "this"; return 1}function Func3 () {this.value = ' this ';} >new Func1 ()//returned {} is an object value that overrides the default this. {}>new FUNC2 ()//returned 1 is a raw value, so still return the default this. {value: ' This '}>new Func3 ()//No return statement, returned undefined by default, is a raw value, so still returns the default this. {value: ' This '}>new Func3//without parameters, parentheses can be omitted. {value: ' This '}

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.