JavaScrtipt动态变换运行时上下文特性,这种特性主要就体现在apply,call两个方法的运用上。
JavaScrtipt中有一个call和apply方法,其作用基本相同,但也有略微的区别。call,apply都属于Function.prototype的一个方法,它是JavaScrtipt引擎内在实现的,因为属于Function.prototype,所以每个Function对象实例,也就是每个方法都有call, apply属性。既然作为方法的属性,那它们的使用就当然是针对方法的了。这两个方法的作用一样,只是使用方式不同。
在JavaScript中,代码总是有一个上下文对象,代码处理该对象之内。 上下文对象是通过this变量来体现的,
这个this变量永远指向当前代码所处的对象中。javascript对象所有属性都是公开的(public),没私有(private)之说,所以可直接访问javascript对象的属性。
call,apply作用就是借用别人的方法来调用,就像调用自己的一样。
1.call方法
Html代码
1 call([thisObj] [,arg1][, arg2][,...][,argN]) 2 thisObj 可选项。将被用作当前对象的对象。 3 arg1, arg2,..., argN 可选项。将被传递方法参数序列。
call方法可以用来代替另一个对象调用一个方法。call方法可将一个函数的对象上下文从初始的上下文改变为由thisObj指定的新对象。如果没有提供thisObj参数,那么Global对象被用作 thisObj。
(1).简单举例
Html代码
1 <input type="button" name="na_but" id="id_but" value="测试call" onclick="testFun()"/> 2 <script type="text/javascript"> 3 var value = "Global Object"; 4 var testFun = function () { 5 /** 6 没有传递参数 7 */ 8 window.printValue(); //Global Object 9 printValue.call(window); //Global Object 10 printValue.call(document.getElementById("id_but")); //测试call 11 printValue.call(new objCall()); //call Object 12 testObj.call(this, "hello", "world", "luchunli"); //调用构造方法 13 } 14 function objCall () { 15 this.value = "call Object"; 16 } 17 function printValue () { 18 alert(this.value); 19 } 20 function testObj () { 21 var str = ""; 22 for(var j = 0 ,end = arguments.length ; j < end ; j++){ 23 str += arguments[j]; 24 } 25 alert(str); //helloworldluchunli 26 } 27 </script>
call函数和apply方法的第一个参数都是要传入给当前对象的对象,及函数内部的this。后面的参数都是传递给当前对象的参数。
HTML代码
1 <input type="button" name="na_but" id="id_but" value="测试call" onclick="testFun()"/> 2 <script type="text/javascript"> 3 var value = "Global Object"; 4 var testFun = function () { 5 //value : Global Object str : Hello Window 6 printValue.call(window, "Hello Window"); 7 //value : call Object str : Hello 8 printValue.call(new objCall(), "Hello"); 9 //value : 测试call str : input 10 printValue.call(document.getElementById("id_but"), "input"); 11 } 12 function objCall () { 13 this.value = "call Object"; 14 } 15 function printValue (str) { 16 var value = "print value"; 17 alert("value : " + this.value); 18 alert("str : " + str); 19 } 20 </script>
(2).应用进阶
HTML代码
1 <input type="button" name="na_but" id="id_but" value="测试call" onclick="testFun()"/> 2 <script type="text/javascript"> 3 var value = "Global Object"; 4 var message = "Global Message"; 5 var testFun = function () { 6 var b = new objB(); 7 var a = new objA(); 8 b.setMessage.call(a, "a的消息"); //==>a.setMessage('a的消息'); 9 //message : a的消息; str : This is a; value : call ObjectA 10 printMessage.call(a, "This is a"); 11 } 12 function objA () { 13 this.value = "call ObjectA"; 14 this.setMessage = setMessage; 15 } 16 function objB () { 17 this.value = "call ObjectB"; 18 this.setMessage = setMessage; 19 } 20 function printMessage (str) { 21 alert("message : " + this.message + "; str : " + str + "; value : " + this.value); 22 } 23 function setMessage (message) { 24 this.message = message; 25 } 26 </script>
2.apply方法
对于apply和call两者在作用上是相同的,但两者在参数上有区别的。
对于第一个参数意义都一样,但对第二个参数:
apply传入的是一个参数数组,也就是将多个参数组合成为一个数组传入,而call则作为call的参数传入(从第二个参数开始)。
HTML代码
1 func.call(func1,var1,var2,var3)对应的apply写法为:func.apply(func1,[var1,var2,var3])
同时使用apply的好处是可以直接将当前函数的arguments对象作为apply的第二个参数传入.
HTML代码
1 <html> 2 <head> 3 <title>测试call/apply方法</title> 4 <meta http-equiv="Content-Type" content="text/html; charset=gbk"> 5 <script type="text/javascript"> 6 var testFun = function () { 7 testApply("中", "国", "人", "民"); 8 } 9 function testApply(a, b, c, d) { 10 print.call(this, a, b, c, d); 11 print.apply(this, [a, b, c, d]); 12 print.apply(this, arguments); 13 } 14 function print (a, b, c, d) { 15 alert(a + b + c + d); //中国人民 16 } 17 </script> 18 </head> 19 <body> 20 <input type="button" name="na_but" id="id_but" value="测试apply" onclick="testFun()"/> 21 </body> 22 </html>
由于直接调用testFun方法, 所以在该方法中的上下文对象this就是window对象。
注意:当参数明确时可用call, 当参数不明确时可用apply给合arguments。