this/call和apply this this指向一个动态的函数执行环境。
在一个普通的对象中,this的作用次域当然是对象本身
在前端最常用的浏览器中,alert(this)的结果是window。
1 2 3 4 5 6 7 8 9 10 11 12 var  name='dangjingtao'        var  obj={        name:'djtao' ,        getName:function (            return  this .name        }    }    console .log(obj.getName())     var  a=obj.getName;     console .log(a())  
现在来研究一个业务中常见的问题。
1 2 3 4 5 6 7 8 9 10 11 12 13 <a  id ="hit-me"  href ="javascript:;" > hit me</a >        <script >         document .getElementById('hit-me' ).onclick=function (            alert(this .id);            var  callback=function (                alert(this .id)            }            callback();        }     </script > 
处理方法是用一个变量存下this
1 2 3 4 5 6 7 8 9 10 11 document .getElementById('hit-me' ).onclick=function (            alert(this .id);             var  _this=this ;             var  callback=function (_ )                 alert(_this.id)             }                          callback();         } 
call用于绑定当前作用于
1 2 3 4 5 6 7 8 9 10 var  name='dangjingtao' ;      var  obj={           name:'djtao' ,           getName:function (               return  this .name           }       }       alert(obj.getName.call(this ));  
这里call(this)显然是把当前的作用域(window)绑定给了getName方法。
遗失的this 写一个简单的js选择器吧,比如document.getElementById('div1'),实在太长了。
1 2 var  getId=document .getElementById   console .log(getId('div1' )) 
运行报错。因为用getId引用了之后,getElementById失去了this。
如何既能调用方法,又不丢失this?干货在于
1 2 3 4 5 6 7 8 document .getElementById=(function (func )       return  function (            return  func.apply(document ,arguments )        }    })(document .getElementById)         var  getId=document .getElementById    console .log(getId('div1' )) 
call和apply 这两个方法非常重要。
调用apply方法的时候,第一个参数是this的指向 , 第二个参数是一个数组或类数组集合 。apply把这个集合作为参数传递给被apply的函数。
1 2 3 4 5 var  func=function (a,b,c )    alert([a,b,c])  } func.apply(null ,[1 ,2 ,3 ]) 
call是apply的高级实现。当你知道参数数量时,也可以用call来写。比如func.call(obj,'a','b','c')。
非严格模式下,如果第一个参数为null,this还是指向默认的宿主。比如在浏览器中就是window。严格模式下则为null。
应用 如果认为,call和apply作用只局限于改变this的指向,那就错了。你还可以获取别的属性方法,绑定
来看看其它用法。
访问一类对象的内部数据 大部分高级浏览器都实现了Function.protoype.bind方法,用以绑定this。学习上述知识,能否手写模拟一个bind方法?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 Function .prototype.bind=function (ctx )    var  _this=this ;          return  function (         return  _this.apply(ctx,arguments )     } } var  name='dangjingtao' var  obj={    name:'djtao'  } var  func=function (    return  this .name }.bind(obj) console .log(obj) func()  
简单地说,我们在不为这个对象注册方法的前提下,为了一个对象实现了对内部私有变量的访问。
再丰富一点点 bind的简单实现并不足以满足功能。我想扩展bind方法并允许传入多个参数,并且还可以追加这个方法的参数。
可以这么做。
1 2 3 4 5 6 7 8 9 10 11 Function .prototype.bind=function (    var  _this=this ; 	var  ctx=[].shift.call(arguments )     var  args=[].slice.call(arguments )          return  function (                           return  _this.apply(ctx,[].concat.call(args,[].slice.call(arguments )))     } } 
测试结果
1 2 3 4 5 6 7 8 9 10 11 var  obj={	name:'djtao'  } var  func=function (a,b,c,d )    alert(this .name)      alert([a,b,c,d])  }.bind(obj,1 ,2 ) func(3 ,4 ) 
借用其他构造对象的方法 读书人的事,靠偷是不对的,应该是借。以下A是一个构造函数,拥有给某个人添加”是天才”后缀的处理过程。我要拿到A的属性。
1 2 3 var  A=function (name )    this .name=name+'是天才'  } 
可以构造一个B对象来借
1 2 3 4 5 6 7 8 9 10 11 var  B=function (    A.apply(this ,arguments ) } B.prototype.getName=function (     return  this .name } var  b=new  B('djtao' );console .log(b.getName)
再比如 arguments对象不是数组。但是我想把它们作为数组来处理,比如push。我想借用Array对象的push方法,怎么做?
1 2 3 4 5 (function ( 	Array .prototype.push.call(arguments ,3 );     console .log(arguments ) })(0 ,1 ,2 ) 
更骚的操作是给对象也加个push方法
1 2 3 4 5 6 7 8 var  a={}Array .prototype.push.call(a,'0' )   Array .prototype.push.call(a,'第一个元素' );    Array .prototype.push.call(a,'第二个元素' )    console .log(a) 
只要对象的属性可读写,length属性可读写,那就可以把push方法用到上面去。