JavaScript deserialization this [translation]

Source: Internet
Author: User

This article describes how to commercialize this in JavaScript. The topic is from a tweet in Brendan Eich (father of JavaScript.

1. Uncurrying this

Anti-corryization of this means: the following method of adding a signature:

Obj. foo (arg1, arg2) is converted into another function with the following signature:

Foo (obj, arg1, arg2) wants to know how to do this. First, we need to understand the general method.

2. General Method (Generic methods)

Generally, a specific method can only be used on a specific type of object instance. however, some methods can be very useful if they can be used on other types of object instances, such:
Copy codeThe Code is as follows:
// Simplified version:
Array. prototype. forEach = function (callback ){
For (var I = 0; I <this. length; I ++ ){
If (I in this ){
Callback (this [I], I );
}
}
};

This can be seen as an implicit parameter of the forEach () method. objects that meet the following three rules can call the forEach () method, and can all be used as the implicit this:

• With the length attribute: this. length
• Access Object elements through indexes: this [I]
• Check the property existence: I in this
The arguments object (including all real parameters called by the arguments function) is not an Array instance, so it cannot directly call the forEach () method. however, you must meet the three conditions for calling the forEach method. to enable this object to call the forEach () method, we only need to make the implicit this parameter as an explicit parameter. fortunately, every function has the call () method for us to do something:

Copy codeThe Code is as follows:
Function printArgs (){
Array. prototype. forEach. call (arguments, function (elem, index ){
Console. log (index + "." + elem );
});
}

The forEach. call () method has one more parameter than the forEach () method: its first parameter is the specified this value:
Copy codeThe Code is as follows:
> PrintArgs ("a", "B ")
0.
1. B

Several similar general methods in JavaScript can be called in this way. Most of these methods come from Array. prototype.

3. Anti-corriization of this

Example 1: Call A method through map. array. prototype. the map () method allows you to call a function on each element of an array. but what if you want to call a function or method? You can use anti-Corrie this to do this:
Copy codeThe Code is as follows:
> Var toUpperCase = String. prototype. toUpperCase. uncurryThis ();
> ["Foo", "bar", "baz"]. map (toUpperCase)
['Foo', 'bar', 'baz']

Example 2: convert a common method to a function. this can be used to convert a method into a simpler function. For example:
Copy codeThe Code is as follows:
Array. forEach = Array. prototype. forEach. uncurryThis ();
Function printArgs (){
Array. forEach (arguments, function (elem, index ){
Console. log (index + "." + elem );
});
}

Many similar array methods are available in the ECMAScript specification recommendations for future versions.
Note: Firefox has been implementedArray.map,Array. forEach and other methods.

4. Implement uncurryThis ()
The following are three methods to implement the uncurryThis method.

Implementation 1: Written by Brendan Eich
Copy codeThe Code is as follows:
Function. prototype. uncurryThis = function (){
Var f = this;
Return function (){
Var a = arguments;
Return f. apply (a [0], []. slice. call (a, 1 ));
};
};

Implementation 2: calling the inverse function is equivalent to executing it by calling its call () method in the original method. we can use the bind () method to borrow the call () method:
Copy codeThe Code is as follows:
Function. prototype. uncurryThis = function (){
Return this. call. bind (this );
};

Implementation 3: It is recommended that the defined standard method not depend on too many external methods. In addition, the bind () method is only available in ECMAScript 5. Therefore, we overwrite the above implementation 2, as shown below:

Copy codeThe Code is as follows:
Function. prototype. uncurryThis = function (){
Var f = this;
Return function (){
Return f. call. apply (f, arguments)
};
};

The above code still implicitly borrowed the call () method.

5. Reverse operations are also useful-colialize this
The inverse operation of uncurryThis () is called curryThis (). It converts the first parameter of the original function to the implicit this parameter. If there is an original function:
Copy codeThe Code is as follows:
Function (self, arg ){
Return self. foo + arg;
}

Colialized this to become:
Copy codeThe Code is as follows:
Function (arg ){
Return this. foo + arg;
}

Use Case: let a method pass its this value to an embedded function. The original statement is as follows:
Copy codeThe Code is as follows:
Var obj = {
Method: function (arg ){
Var self = this; // allows nested functions to access this
SomeFunction (..., function (){
Self. otherMethod (arg );
});
},
OtherMethod: function (arg ){...}
}

You can write this statement after corialization:
Copy codeThe Code is as follows:
Var obj = {
Method: function (self, arg) {// additional parameter 'self'
SomeFunction (..., function (){
Self. otherMethod (arg );
});
}. CurryThis (), // input additional parameters
OtherMethod: function (arg ){...}
}

We convert the implicit parameter this into an explicit parameter self. in other words, we convert a dynamic this into a static variable self. if this is always an explicit parameter, JavaScript becomes simpler.

Implement curryThis ():
Copy codeThe Code is as follows:
Function. prototype. curryThis = function (){
Var f = this;
Return function (){
Var a = Array. prototype. slice. call (arguments );
A. unshift (this );
Return f. apply (null, );
};
};

6. If you do not want to extend the function prototype

The above implementation methods are added to the prototype of the built-in constructor Function (). You should be able to easily rewrite them as independent functions.
Copy codeThe Code is as follows:
Function uncurryThis (f ){
Return function (){
Return f. call. apply (f, arguments)
};
}
Function curryThis (f ){
Return function (){
Var a = Array. prototype. slice. call (arguments );
A. unshift (this );
Return f. apply (null, );
};
}

7. Use uncurryThis () Security in existing Untrusted code

Mark MillerUncurryThis () is used as an example to explain"Secure metaprogramming ":

Note: colialization this is to convert the first parameter of the function into this in the method. Inverse colialization this is to convert this in the method into the first parameter of the function.

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.