<script> if( !Function.prototype.softBind ){ Function.prototype.softBind = function( obj ){ var fn = this;//2、把函数foo的引用赋给fn //14、把函数foo的引用赋给fn var curried = [].slice.call( arguments, 1 );//3、截取softBind函数参数的第二位并返回一个函数 //15、截取softBind函数参数的第二位并返回一个函数 var bound = function(){//4、声明一个bound函数 //16、声明一个bound函数 return fn.apply(//11、执行fn.apply( obj, [] ) //23、执行fn.apply( obj2, [] ) (!this || this === (window || global)) ? obj : this, //核心程序 !this || this === (window || global)) ? obj : this //判断bound函数内this的指向 //9、this为window,|| true 对象为obj //21、this为obj2, || false 对象为this => obj2 curried.concat.apply( curried, arguments )//10、所有的参数合并为一个数组 //22、所有的参数合并为一个数组 ) } // bound.prototype = Object.create( fn.prototype );//5、函数bound的原型赋值为fn的原型 //17、函数bound的原型赋值为fn的原型 return bound;//6、返回bound函数 //18、返回bound函数 } } function foo(){//12、输出name: obj1 //23、输出name: obj2 console.log("name: "+this.name); } var obj1={name:"obj1"}, obj2={name:"obj2"}, obj3={name:"obj3"}; var fooOBJ=foo.softBind(obj1);//1、执行函数,因为每一个函数都有一个softBind方法 //7、fooOBJ = bound; fooOBJ();//8、执行fooOBJ() => bound() obj2.foo=foo.softBind(obj1);//13、执行foo.softBind(obj1) //19、obj2.foo方法引用为bound函数 obj2.foo();//20、执行obj2.foo() fooOBJ.call(obj3);//【只要改变函数内this的指向就可以改变输出的值】 setTimeout(obj2.foo,1000);//"name: obj1" /**回调函数相当于一个隐式的传参,如果没有软绑定的话,这里将会应用默认绑定将this绑定到全局环 境上,但有软绑定,这里this还是指向obj1*/ </script>