我一直認爲代碼是最能說明問題的.必要的地方我寫有註釋.參考一些相關的文章.下面的代碼作了進一步的探討.或許能讓理解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");