JavaScript anti-]_javascript This [translation of the skills

Source: Internet
Author: User
This article mainly discusses the JavaScript in the branch and the anti-branch of this method. The topic comes from a tweet from Brendan Eich, the father of JavaScript.

1. Anti-KLA (uncurrying) this

Anti-KLA This means: put a signature on the following method:

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

Foo (obj, arg1, arg2) want to know what's the use of doing this, we first have to understand the common method.

2. General method (Generic methods)

In general, a particular method can only be used on a particular type of object instance. However, there are some methods that can be useful if they are also used on other types of object instances, such as:
Copy Code code as follows:

Simplified version of the actual implementation:
Array.prototype.forEach = function (callback) {
for (var i=0; i<this.length; i++) {
if (i in this) {
Callback (This[i], i);
}
}
};

This can be viewed as an implied parameter to the foreach () method. Objects that satisfy these three rules can invoke the foreach () method, which can be used as this implied this:

• Has the length attribute: this.length
• Ability to access object elements via index: This[i]
• Ability to check the existence of attributes: I in this
The arguments object, which contains all the arguments of a function call, is not an array instance, so it cannot call the foreach () method directly. But you it satisfies the three conditions that invoke the Foreach method. In order for the object to invoke to the foreach () method, All we need to do is to have the implied this argument as an explicit argument. Luckily, every function has a call () method to do something:

Copy Code code as follows:

function Printargs () {
Array.prototype.forEach.call (arguments, function (Elem, index) {
Console.log (index+). "+elem);
});
}

Foreach.call () has one more argument than the foreach () method: Its first argument is the specified this value:
Copy Code code as follows:

> Printargs ("A", "B")
0. A
1. b

There are several similar common methods in JavaScript that can be invoked in this way, most of which come from Array.prototype.

3. Several uses of the anti-KLA this

Use Case 1: A method is called through a map (). The Array.prototype.map () method allows you to raise a function for each element in an array. But what if you want to call not a function or a method? You can use the anti-branch to do this:

Copy Code code as follows:

> var touppercase = String.prototype.toUpperCase.uncurryThis ();
> ["foo", "Bar", "Baz"].map (touppercase)
[' FOO ', ' BAR ', ' BAZ ']

Use case 2: Converts a common method into a function. The use of anti-KLA this can transform a method into a function that is simpler to use. For example:
Copy Code code 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 already available in future versions of the ECMAScript specification recommendations.
The translator note: Firefox has been implemented Array.map, Array.foreach and other methods.

4. Implementation of Uncurrythis ()
Here are three ways to implement the Uncurrythis method.

Implementation of 1:brendan Eich written
Copy Code code 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 an inverse of a function is equivalent to executing it by calling its call () method on the original method. We can borrow this called () method by using the Bind () method:
Copy Code code as follows:

Function.prototype.uncurryThis = function () {
Return This.call.bind (this);
};

Implement 3: The standard approach defined is best not to rely on too many external methods. In addition, the bind () method is only available in ECMAScript 5. So we rewrote the above implementation 2, as follows:

Copy Code code as follows:

Function.prototype.uncurryThis = function () {
var f = this;
return function () {
Return f.call.apply (f, arguments)
};
};

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

5. Reverse operation is also useful – Zhongke this
The reverse operation of Uncurrythis () is called currythis (). It converts the first argument of the original function to the implied this parameter. If there is a primitive function:
Copy Code code as follows:

function (self, arg) {
return Self.foo + arg;
}

The branch of this becomes after:
Copy Code code as follows:

Function (ARG) {
return This.foo + arg;
}

Use case: Let a method pass its own this value into an inline function. The original wording:
Copy Code code as follows:

var obj = {
Method:function (ARG) {
var self = this; Allow nested functions to access this
SomeFunction (..., function () {
Self.othermethod (ARG);
});
},
Othermethod:function (ARG) {...}
}

You can write this in the following section:
Copy Code code as follows:

var obj = {
Method:function (self, arg) {//additional parameter ' self '
SomeFunction (..., function () {
Self.othermethod (ARG);
});
}.currythis (),//Incoming additional parameters
Othermethod:function (ARG) {...}
}

We convert the implied parameter this to an explicit argument self. In other words: We convert a dynamic this to a static variable self. If this is always an explicit argument, JavaScript becomes simpler.

Implement Currythis ():

Copy Code code 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, a);
};
};

6. If you don't want to extend the function prototype

The methods implemented above are all added to the prototype of the built-in constructor function (). You should be able to easily rewrite them as separate functions.

Copy Code code 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, a);
};
}

7. In Uncurrythis () safe use in existing untrusted code

Mark Miller把uncurryThis()作为例子讲解了“安全的元编程”:

译者注:科里化this就是把函数的第一个参数转换成方法中的this.反科里化this就是把方法中的this转换成函数的第一个参数.

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.