Interesting anti-Curry in JavaScript deep analysis _ Basics

Source: Internet
Author: User
Tags bind closure jquery library

Written in front of the words: the domestic front of the research in some respects is not inferior to foreign countries, this article although not very understand, but I appreciate this in-depth study of the spirit!

The topic of anti-Brendan comes from Twitter, the father of JavaScript, Eich last year. In recent days to study a bit, think this dongdong very interesting, share. Forget its name first and see what it can do.

Do not underestimate this function, imagine, we write a library, often write such code, take WEBQQ JX Library for example.


What we want, in fact, is to borrow some of the functions on the array prototype chain. It is not necessary to explicitly construct a new function to change their parameters and to recalculate them.

If the uncurrying way is clearly more elegant and wonderful, like this:

There are a lot of interesting and convenient things to do.

Even the call and apply methods are uncurrying, and functions are used as normal data. Making a function call in JavaScript more like its previous scheme, this invocation method is particularly handy when the function name itself is a variable.

Scheme inside the calling function is this:

JavaScript can be written in very close proximity.

Then look at the jquery library, because the jquery object (that is, the object created by $ ()) is an object pseudo array, it has the length property, and can find the corresponding element by subscript, when you need to add a member to the jquery object, pseudo code is probably:

If you use uncurrying, you can

The push function of the array object is borrowed to allow the engine to automatically manage the array members and length properties.

And you can borrow all the functions you need once, once and for all. A piece of test code:

In general, using uncurrying technology, you can make any object have a method of native objects. Well, if you're still not interested in getting here, then you can do something else.

The next step is to look at the principle and implementation.
Before we know the strange name of currying, we have to figure out currying.

Definition on Wikipedia: currying (); Also called partial evaluation is the technique of transforming a function that accepts multiple parameters into a function that accepts a single parameter, and returns a new function that accepts the remaining parameters and returns the result.

Popular point of speaking, currying a bit similar to buy a house on the way to installment, first to a part of the down payment (some parameters), return a passbook (return a function), the appropriate time to give the remaining parameters and evaluate the value.

To see the currying we've all used, we often implement a Function.prototype.bind function when we bind the context.

Higher-order functions are the basis for implementing currying, and the so-called higher order functions satisfy at least 2 characteristics:
1, functions can be passed as parameters,
2, the function can be a return value.

At the beginning of design, JavaScript referenced the features of many scheme languages. Scheme is one of the 2 dialects of functional language originator Lisp, so JavaScript also has some features of functional languages, including higher-order functions, closures, lambda expressions, and so on.

When a function in JavaScript returns another function, a closure is formed, and the parameters of the first operation can be saved in the closure, and we use this idea to write a generic currying function.

We agree that when the parameters are passed in, the arguments are currying and the parameters are empty before the evaluation begins.

Let's say that when we implement a function that calculates the cost of a month, we have to keep a record of how much we spend today, but we only care about the total cost of the month at the end of the day, without having to count it every day.

Using the currying function, you can delay to the last minute to calculate together, the benefits are self-evident, in many cases can avoid unnecessary calculation, save performance, but also to achieve a lazy evaluation of a scheme.

Okay, now we're getting to the point.

Curring are pre-filled with some parameters.

Anti-curring is to defer to future delivery the previously fixed parameters or the this context as parameters.

is actually doing such a thing, will:

Obj.foo (arg1)//foo is a function that is only on obj. It's like the push was only on the Array.prototype.

into this form.

Foo (obj, arg1)//is the same as our first example. Convert [].push to push ([])

Just like a socket on a TV plug, it can actually be used to connect to the fridge after it is removed.

ECMA of each prototype method on array and string is followed by a phrase such as push:

The push function is intentionally generic; It does not require the IT this value is an Array object.
Therefore it can be transferred to the other kinds of the objects for use as a. Whether the CONCAT function can be applied.

Why do JavaScript design this way, let's review the important duck type ideas in the dynamic language first.

Tell a story:

Once upon a time an emperor liked to hear the duck croak, so he summoned the minister to form a choir of 1000 ducks. The minister arrested all the Ducks in the country and finally one. One day finally came a volunteer chicken, the chicken said it will also croak, well, in the setting of this story, it does croak. Later, the story grew very clear, and the chicken mingled with the duck's choir. -The emperor just wants to hear the quack, he doesn't care if you're a duck or a chicken.

This is the concept of duck type, in JavaScript, many functions do not do object type detection, but only care about what these objects can do.

The method on the prototype of the array constructor and string constructor is deliberately designed to be a duck type. These methods do not validate any data types for this. This is why arguments can invoke the push method as an array.

Look at the Array.prototype.push code inside the V8 engine:

Copy Code code as follows:

function Arraypush () {
var n = to_uint32 (this.length);
var m =%_argumentslength ();
for (var i = 0; i < m; i++) {
This[i+n] =%_arguments (i); Property Copy
This.length = n + M; Fixed length
return this.length;
}
}

As you can see, the Arraypush method does not have any display restrictions on the type of this, so theoretically any object can be passed in to arraypush this visitor.

The only problem we need to solve is how to get an object to impersonate an array object in a common way.

The real implementation code is really simple:

Although this code is very short, the initial understanding of the time is still a little laborious. Let's take the example of a push to see what happened to it.

Copy Code code as follows:

var push = Array.prototype.push.uncurrying ();

Push (obj, ' a ');

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.