關於Javascript中call與apply的進一步探討

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