In-depth understanding of Function.prototye.bind in JavaScript

Source: Internet
Author: User
Tags mozilla developer network

function bindings are probably the least bit of a concern when you start using JavaScript, but when you realize that you need a solution to solve how to keep the this context in another function, what you really need is Function.prototype.bind (), but you may still not be aware of this.

The first time you encounter this problem, you may prefer to set this to a variable so that you can continue referencing it after changing the context. Many people choose to use Self, _this or context as the variable name (and others use that). These methods are useful and of course there is no problem. But there is a better, more dedicated way.

What is the problem we really need to solve?

In the example code below, we can justifiably cache the context into a variable:

 var  myObj = {specialfunction:  function   function   () {}, Getasyncdata:  functio    n   (CB) {CB ();  }, Render:  function   () { var  that = this  ;  this . Getasyncdata (function  Span style= "color: #000000;"            > () {that.specialfunction ();        That.anotherspecialfunction ();    }); }}; Myobj.render ();  

If we simply use This.specialfunction () to invoke the method, we will receive the following error:

Uncaught typeerror:object [Object Global] has no method ' specialfunction '

We need to keep a reference to the MYOBJ object context for the execution of the callback function. Calling That.specialfunction () allows us to maintain the scope context and execute our functions properly. However the use of Function.prototype.bind () can have a more concise and clean way:

function () {     this. Getasyncdata (function  ()}         {This. Specialfunction ();           This . Anotherspecialfunction ();     }. Bind (this)); }
What did we just do?

. Bind () Creates a function that, when called, the This keyword is set to the value passed in (this refers to the parameter passed in when bind () is called). So we pass in the desired context, this (which is actually MYOBJ), into the. bind () function. Then, when the callback function is executed, this points to the MYOBJ object.

If you are interested in knowing what the Minister of Function.prototype.bind () is and how it works, here is a very simple example:

function (scope) {    varthis;     return function () {        return  fn.apply (scope);}    ;}

There is also a very simple use case:

var foo = {    3varfunction() {    Console.log (this       //undefined var boundfunc =//3 

We have created a new function, and when it is executed, its this will be set to foo--instead of the global scope as we call Bar ().

Browser support Support
Browser Version
Chrome 7
Firefox (Gecko) 4.0 (2)
Internet Explorer 9
Opera 11.60
Safari 5.1.4

As you can see, unfortunately, Function.prototype.bind is not supported in the IE8 and below, so if you do not have a fallback option, you may run into problems.

Fortunately, the Mozilla Developer Network (a great repository) provides an absolutely reliable alternative to browsers that do not have their own implementation. Bind () Method:

if(!Function.prototype.bind) {Function.prototype.bind=function(othis) {if(typeof  This!== "function") {      //closest thing possible to the ECMAScript 5 internal iscallable function      Throw NewTypeError ("Function.prototype.bind-what is trying to be bound are not callable"); }     varAargs = Array.prototype.slice.call (arguments, 1), Ftobind= This, Fnop=function() {}, Fbound=function () {          returnFtobind.apply ( This instanceofFnop && othis? This: Othis, Aargs.concat (Array.prototype.slice.call (argume        (NTS)));     }; Fnop.prototype= This. prototype; Fbound.prototype=NewFnop (); returnFbound; };}
Applicable mode

In learning the technical point, I found that the useful is not only to thoroughly learn and understand the concept, but also to see in the work at hand there is no place to apply it, or more close to it's things. I hope that some of the examples below will apply to your code or solve the problem you are facing.

Click Handlers (TAP processing function)

One purpose is to record a click event (or to perform an action after a click), which may require us to store some information in an object, such as:

var logger = {    0,           function() {        this. x + +;        Console.log (this. x);    }}

We may specify the click handler function in the following way, and then call the Updatecount () method in the Logger object.

function () {    logger.updatecount ();});

But we have to create an extra anonymous function to make sure that the This keyword in the Updatecount () function has the correct value.

We can use the following cleaner way:

Document.queryselector (' button '). AddEventListener (' Click ', Logger.updateCount.bind (logger));

We cleverly used the convenient. Bind () function to create a new function and bind its scope to the Logger object.

SETTIMEOUT

If you have used a template engine (such as handlebars) or have used some mv* frameworks in particular (I can only talk about backbone.js from my experience), then you might be aware of the problems discussed below about accessing the new DOM node immediately after rendering the template.

Suppose we want to instantiate a jquery plugin:

 var  myView = {Template:  '/* a < Select/> Template String */'  ' #content '  function   () { this . $el. Find (' SELECT '  function   () { this . $el. html (this  .template ());     this  .afterrender (); }} myview.render ();  

You may find it works-but not every time, because there are problems. This is a competition problem: only the first arrival can win. Sometimes the rendering is first, and sometimes the plugin is instantiated first. The Translator notes: If the rendering process has not been completed (DOM node has not been added to the DOM tree), then find (' select ') will not be able to find the corresponding node to perform the instantiation. 】

Now, perhaps not a lot of people know, we can use SetTimeout () based slight hack to solve the problem.

Let's rewrite our code a little bit and then safely instantiate our jquery plugin after the DOM node is loaded:

function () {        this. $el. Find (' select '). Myplugin ();    },     function  () {         this. $el. html (this. Template ());        SetTimeout (this. AfterRender, 0);            

However, what we get is the function. AfterRender () cannot find the error message.

What we're going to do next is use. bind () in our code:

function (    ) {        this. $el. Find (' select '). Myplugin ();},             function () {        this. $el. html (this. Template ());        SetTimeout (this. Afterrender.bind (This), 0);             //

Source: http://blog.jobbole.com/58032/

Reference: Https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/bind

In-depth understanding of Function.prototye.bind in JavaScript

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.