-call,apply:在javascript中,call和apply都是为了改变函数运行时的上下文而存在的,换句话说就是改变函数里面this的指针身体。JavaScript的一大特点是函数有“定义时上下文”、“运行时上下文”、“上下文可以改变”等概念。调用可以传递一个thisArgs参数和一个参数列表。thisArgs指定函数在运行时的调用者,即函数中的this对象,参数列表将被传递给调用函数。thisArgs的取值有以下四种情况:(1)没有传递,或者传递null、undefined,函数中的this指向window对象(2)传递了另一个函数的函数名,函数中的this指向引用该函数的(3)传递基本类型,如字符串、数字或布尔类型。函数中的this指向它对应的包装对象,比如String,Number,Boolean(4)传递一个对象,函数中的this指向这个对象functiona(){console.log(this);//在函数a中输出这个对象}functionb(){}//定义函数bvarobj={name:'hehe'};//定义对象obja.call();//windowa.call(null);//windowa.call(undefined);//窗口调用(1);//Numbera.call('');//Stringa.call(true);//Booleana.call(b);//函数b(){}a.call(obj);//Object这是call的核心功能,可以调用一个对象上没有定义的方法,这个方法可以访问.call中的对象属性。functionanimals(){}animals.prototype={type:"dog",say:function(){console.log("我是一个"+this.type);}}vardog=newanimals();狗。说();//Iamadogvarcat={type:'cat'};dog.say.call(cat);//我是一只猫所以可以看出call和apply出现动态改变this是的,当一个对象没有某个方法时(这个栗子中cat没有say方法),但是其他有(dog这个栗子里有个say方法),我们可以用call或者apply来操作其他对象的方法。apply和call的区别:apply和call的功能完全一样,只是接受参数的方式不同。object.functionname.call(thisArgs,arg1,arg2);object.functionname.apply(thisArgs,[arg1,arg2])其中this是你要指定的上下文,它可以是任何JavaScript对象(JavaScript对象中的一切),call需要按顺序传入参数,而applyputs数组中的参数。-bind:bind是ES5中的一个新方法。它的参数传递与call类似,但与call/apply有明显区别,即调用call或apply会自动执行相应的函数,而bind不会执行相应的函数。函数,只是返回函数的引用。MDN的解释是:bind()方法会创建一个新的函数,称为绑定函数。当调用此绑定函数时,绑定函数将使用创建时传递给bind()方法的第一个参数this,传递给bind()方法的第二个和后面的参数加上绑定函数本身的参数runtime被用作原函数的参数,以便调用原函数。varobj={id:1,eventBind:function(){var_this=this;$('.btn').on('click',function(event){alert(this.id);//undefinedalert(_this.id);//1});}}obj.eventBind();//没有这句话,点击事件不会执行。由于Javascript的独特机制,上下文转换为$(ineventBind:function(){}'.btn').on('click',function(event){})发生了变化。上面用变量保存this的方法很好用,没有问题。当然,使用bind()可以更优雅的解决这个问题:varobj={id:1,eventBind:function(){$('.btn').on('click',function(event){alert(this.id);//1}.bind(this));}}obj.eventBind();//没有这句话,点击事件不会执行——call、apply、bind的区别:varobj={x:88,};varfoo={getX:function(){返回这个.x;}}console.log(foo.getX.bind(obj)());//88console.log(foo.getX.call(obj));//88console.log(foo.getX.apply(obj));//88的三个输出都是88,但是注意bind()方法后面多了一个括号。换句话说,不同的是,当你想执行回调而不是改变上下文后立即执行时,使用bind()方法;而apply/call将立即执行函数。
