当前位置: 代码迷 >> JavaScript >> JavaScript的apply()跟call()
  详细解决方案

JavaScript的apply()跟call()

热度:96   发布时间:2012-10-08 19:54:56.0
JavaScript的apply()和call()
            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方法
call([thisObj] [,arg1][, arg2][,...][,argN])
thisObj		可选项。将被用作当前对象的对象。
arg1, arg2,  , argN		可选项。将被传递方法参数序列。

            call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。如果没有提供 thisObj 参数,那么 Global 对象被用作 thisObj。
foo.call(thisObj, arg1,arg2,arg3) == thisObj.foo(arg1, arg2, arg3)

             (1).简单举例
<input type="button" name="na_but" id="id_but" value="测试call" onclick="testFun()"/>	
<script type="text/javascript">	
	var value = "Global Object";
	var testFun = function () {
		/**
			没有传递参数
		*/
		window.printValue();	//Global Object
		printValue.call(window);	//Global Object
		printValue.call(document.getElementById("id_but"));	//测试call
		printValue.call(new objCall());		//call Object
		testObj.call(this, "hello", "world", "luchunli");	//调用构造方法
	}		
	function objCall () {
		this.value = "call Object";
	}
	function printValue () {
		alert(this.value);
	}
	function testObj () {
		var str = "";
		for(var j = 0 ,end = arguments.length ; j < end ; j++){
			str += arguments[j];
		}
		alert(str);		//helloworldluchunli
	}
</script>

           call函数和apply方法的第一个参数都是要传入给当前对象的对象,及函数内部的this。后面的参数都是传递给当前对象的参数。
<input type="button" name="na_but" id="id_but" value="测试call" onclick="testFun()"/>	
	<script type="text/javascript">	
	var value = "Global Object";
	var testFun = function () {
		//value : Global Object  str : Hello Window
		printValue.call(window, "Hello Window");
		//value : call Object  str : Hello
		printValue.call(new objCall(), "Hello");
		//value : 测试call  str : input
		printValue.call(document.getElementById("id_but"), "input");	
	}		
	function objCall () {
		this.value = "call Object";
	}
	function printValue (str) {
		var value = "print value";
		alert("value : " + this.value);			
		alert("str : " + str);		
	}
</script>

              (2).应用进阶
<input type="button" name="na_but" id="id_but" value="测试call" onclick="testFun()"/>	
<script type="text/javascript">	
	var value = "Global Object";
	var message = "Global Message";
	var testFun = function () {
		var b = new objB();
		var a = new objA();				
		b.setMessage.call(a, "a的消息");	//==>a.setMessage('a的消息');
		//message : a的消息;	str : This is a;	value : call ObjectA
		printMessage.call(a, "This is a");		
	}		
	function objA () {
		this.value = "call ObjectA";
		this.setMessage = setMessage;
	}
	function objB () {
		this.value = "call ObjectB";
		this.setMessage = setMessage;
	}
	function printMessage (str) {		
		alert("message : " + this.message + ";\tstr : " + str + ";\tvalue : " + this.value);			
	}
	function setMessage (message) {
		this.message = message;
	}
</script>

            2.apply方法
            对于apply和call两者在作用上是相同的,但两者在参数上有区别的。
            对于第一个参数意义都一样,但对第二个参数:
            apply传入的是一个参数数组,也就是将多个参数组合成为一个数组传入,而call则作为call的参数传入(从第二个参数开始)。
func.call(func1,var1,var2,var3)对应的apply写法为:func.apply(func1,[var1,var2,var3])

            同时使用apply的好处是可以直接将当前函数的arguments对象作为apply的第二个参数传入.
<html>
	<head>
		<title>测试call/apply方法</title>
		<meta http-equiv="Content-Type" content="text/html; charset=gbk">
		<script type="text/javascript">	
			var testFun = function () {
				testApply("中", "国", "人", "民");	
			}
			function testApply	(a, b, c, d) {
				print.call(this, a, b, c, d);
				print.apply(this, [a, b, c, d]);
				print.apply(this, arguments);
			}
			function print (a, b, c, d) {
				alert(a + b + c + d);	//中国人民
			}
		</script>
	</head>
	<body>	
		<input type="button" name="na_but" id="id_but" value="测试apply" onclick="testFun()"/>		
	</body>
</html>

            由于直接调用testFun方法, 所以在该方法中的上下文对象this就是window对象。
            注意:当参数明确时可用call, 当参数不明确时可用apply给合arguments。
  相关解决方案