我一直认为代码是最能说明问题的.必要的地方我写有注释.参考一些相关的文章.下面的代码作了进一步的探讨.或许能让理解call和apply更进一步!
function log(a) { //我习惯使用firebug和chrome本身的调试器.您也能够手动修改成alert console.log(a); } function ObjB() { this.message = "messageB"; this.setMessage = function(arg) { this.message = arg; }; } function ObjA() { this.message = "messageA"; this.getMessage = function() { return this.message; }; } var b = new ObjB(); var a = new ObjA(); //能够直接访问属性.输出为messageA log(a.message); //给对象ObjA动态指派ObjB的setMessage方法,注意,ObjA自己是没有这方法的! b.setMessage.call(a, "A的消息"); //输出"A的消息" log(a.getMessage()); //给对象b动态指派a的getMessage方法,注意,b自己也是没有这方法的!能够理解为获得A里面的getMessage方法体.而后用call注入到B里面执行.由于上下文变成了B,因此B多了getMessage方法体. var result = a.getMessage.call(b); //输出"messageB" log(result); //Uncaught TypeError: Object #<ObjB> has no method 'getMessage' 出错了.由于call并无把getMessage永久注入进ObjB //log(b.getMessage()); function print(a, b, c, d) { log("调用者是:" + arguments.callee.caller.name + " 上下文是:" + this + " 参数是:" + a + b + c + d); } //经过example里面 的三次调用,能够看出:call, apply方法区别是,从第二个参数起, call方法参数将依次传递给借用的方法做参数, 而apply直接将这些参数放到一个数组中再传递, 最后借用方法的参数列表是同样的. function example1(a, b, c, d) { //用call方式借用print,参数次序传递. print.call(this, a, b, c, d); //用apply方式借用print, 参数做为一个数组传递, //这里直接用JavaScript方法内自己有的arguments数组 print.apply(this, arguments); //或者封装成数组 print.apply(this, [a, b, c, d]); } //此方法和example1同样.可是突出分析this表明什么东西. function example2(a, b, c, d) { print.call(window, a, b, c, d); print.apply(window, arguments); print.apply(window, [a, b, c, d]); } example1("参数1", "参数2", "参数3", "参数4"); example2("参数1", "参数2", "参数3", "参数4"); /*----------------------------------------------------------------------*/ function SimulateFun() { this.print = function(a, b, c, d) { log("调用者是:" + arguments.callee.caller.name + " 上下文是:" + this + " 参数是:" + a + b + c + d); } } var simulateFun = new SimulateFun(); function example3(a, b, c, d) { simulateFun.print.call(this, a, b, c, d); simulateFun.print.apply(this, arguments); simulateFun.print.apply(this, [a, b, c, d]); } example3("参数1", "参数2", "参数3", "参数4"); /*------------------------------------------------------------------------------*/ function ContentSimulate() { this.example4 = function example4(a, b, c, d) { simulateFun.print.call(this, a, b, c, d); simulateFun.print.apply(this, arguments); simulateFun.print.apply(this, [a, b, c, d]); } this.example5 = function example5(a, b, c, d) { print.call(this, a, b, c, d); print.apply(this, arguments); print.apply(this, [a, b, c, d]); } } var contentSimulate = new ContentSimulate(); //这里的上下文变成了ContentSimulate对象 contentSimulate.example4("参数1", "参数2", "参数3", "参数4"); //这里的上下文变成了ContentSimulate对象 contentSimulate.example5("参数1", "参数2", "参数3", "参数4");