JavaScript之bind及bind的模拟实现

        在JavaScript编程中有很多改变this的方法和方式,今天说的bind与众不同,像call、apply改变this指向的时候会直接执行。而bind则不是,话不多说,直接进入正题。

        bind

        bind是函数原型上的一个方法,作用是改变this指向并且返回一个函数等待被执行。
Function.prototype.bind()
        bind()可以传入多个参数,第一个参数作为改变this的一个对象,后面的参数作为返回函数的形参。
        然而传入的第一个参数不同的话,指向也不同,看代码
var value = 0;
var obj = {
   value : 1,
}
function(name,age){
    console.log(value);
    console.log(name + " " + age);
}
var newShow = show.bind(obj,abc,18);
newShow();  //返回 1  abc 18
var newShow = show.bind(null,abc,18);
newShow();   //返回 0 abc 18
new newShow();  // 返回 undefined abc 18
        由此我们可以看出,当第一个参数是对象的时候,改变this的指向指向对象,当第一个参数为null的时候,此时的this指向window,当我们用 new newShow() 产生一个对象实例的时候,无论第一个参数填的什么,this都是指向对象实例。

        bind的运用环境

        当我们在后面进行模块化开发的时候,代码量大的时候,最容易犯的错误就是变量污染全局了,我们可以选择单变量编程来防止这件事情的发生。代码如下:
var obj = {
      init : fucntion(){
      },
      bindEvent : function(){
      },
      show : function(){
      }
}
        这种方式就是模块化编程,当我们在对象函数中写进东西的时候,我们想让这三个函数建立起来联系,想让他们每次的初始this指向这个对象。这是时候就用到bind了。
var obj = {
    init : function(){
       var btn = document.getElementById('btn');
    },
    bindEvent : function(){
       btn.onclick = this.show.bind(this);
    },
    show : function(){
       console.log(this);
    }
}  obj.init()  
        此时我们在这样调用的时候不会因为this指向的问题而 弄不清作用域是什么。
        现在我们开始想着用原生的方法模拟一下这个bind。

        bind的模拟实现

        我们现在想一下这个bind需要什么。由上面可知,bind第一个参数不用,this所指向不同。而且返回的是一个新的函数。当函数有返回值的时候还需要返回值
Function.prototype.newBind = function(target){
  var target = target || window;
  return function(){
     return  this.apply(target);
  }
}
        我们还知道,在newBind方法调用的时候是可以用多个形参的。作为返回函数的参数,而新返回的函数也是可以传参的,由于参数个数的不同我们可以选择用arguments来确定参数,这时我们可以用 [].slice.call(grguments);这种方式把类数组切成数组
Function.prototype.newBind = function(target){
  var target = target || window;
  var self = this;
  var args = [],slice.call(arguments,1);
  return function(){
     var _args = [].slice.call(arguments,0);
     return  self.apply(target,args.concat(_args));
  }
}
        当我们在原型链上编程的时候,避免不了用原型上的东西,此时我们bind的方法也是可以继承原型上的属性和方法的,这里是使用圣杯模式的一种思想实现
Function.prototype.newBind = function(target){
   var target = target || window;
   var self = this;
   var args = [].slice.call(arguments,1);
   var temp = function(){};
   var F = function(){
      var _args = [].slice.call(arguments,0);
      return self.apply(this instanceof temp ? this : target , args.concat(_args));
   }
   temp.prototype = this.prototype;
   F.prototype = new temp;
   return F;
}
JavaScript之bind及bind的模拟实现_第1张图片
JavaScript之bind及bind的模拟实现_第2张图片
        这样我们的bind方法就完全实现了。自己试着用原声的方法模拟一下bind的实现,也会加深对bind 的理解。
         喜欢收藏下吧。
         --主页传送门--

你可能感兴趣的:(JavaScript,JavaScript学习之路)