当前位置: 代码迷 >> JavaScript >> 详解javascript function中的caller,callee,call,apply-转
  详细解决方案

详解javascript function中的caller,callee,call,apply-转

热度:492   发布时间:2012-10-07 17:28:51.0
详解javascript function中的caller,callee,call,apply--转

详解javascript function中的caller,callee,call,apply

caller

返回一个对函数的引用,该函数调用了当前函数。也就是说,返回的是调用该函数的函数。
functionName.caller
functionName
对象是所执行函数的名称。

说明
对于函数来说,caller 属性只有在函数执行时才有定义。如果函数是由顶层调用的,那么 caller 包含的就是 null 。如果在字符串上下文中使用 caller 属性,那么结果和 functionName.toString 一样,也就是说,显示的是函数的反编译文本。值得注意的一点是,事件的触发总是带着一个匿名的函数。

点击查看--caller测试示例


callee

返回正被执行的 Function 对象,也就是所指定的 Function 对象的正文,他是arguments对象的一个属性。[function.]arguments.callee,可选项 function 参数是当前正在执行的 Function 对象的名称。

说明
callee
属性的初始值就是正被执行的 Function 对象。

callee
属性是 arguments 对象的一个成员,它表示对函数对象本身的引用,这有利于匿名函数的递归或者保证函数的封装性,例如下边示例的递归计算1n的自然数之和。而该属性仅当相关函数正在执行时才可用。还有需要注意的是callee拥有length属性,这个属性有时候用于验证还是比较好的。arguments.length是实参长度,arguments.callee.length是形参长度,由此可以判断调用时形参长度是否和实参长度一致。

点击查看--callee测试示例

apply and call
它们的作用都是将函数绑定到另外一个对象上去运行,两者仅在定义参数方式有所区别:
apply(thisArg,argArray);
call(thisArg[,arg1,arg2
] ]);
即所有函数内部的this指针都会被赋值为thisArg,这可实现将函数作为另外一个对象的方法运行的目的

apply的说明
如果 argArray 不是一个有效的数组或者不是 arguments 对象,那么将导致一个 TypeError。如果没有提供 argArray thisArg任何一个参数,那么 Global 对象将被用作 thisArg,并且无法被传递任何参数。

call的说明
call
方法可将一个函数的对象上下文从初始的上下文改变为由 thisArg指定的新对象。如果没有提供 thisArg参数,那么 Global 对象被用作 thisArg

相关技巧:
应用callapply还有一个技巧在里面,就是用callapply应用另一个函数(类)以后,当前的
函数(类)就具备了另一个函数(类)的方法或者是属性,这也可以称之为“继承”。

点击查看--call 和 apply 测试示例

?

=====================================================================

基础练习,call,apply,caller,callee,prototype

<!DOCTYPE?HTML?PUBLIC?"-//W3C//DTD?HTML?4.0?Transitional//EN">
<
html>
?<
head>
??<
title>?New?Document?</title>
??<
meta?name="Generator"?content="EditPlus">
??<
meta?name="Author"?content="">
??<
meta?name="Keywords"?content="">
??<
meta?name="Description"?content="">
??<
meta?http-equiv="Content-Type"?content="text/html;?charset=utf-8"?/>
??<
script?type='text/javascript'>
??
//<![CDATA[
//---------------------arguments?demo---------------------
function?argDemo(a,?b){
????
var?i,?msg?=?"The?argDemo?function?expected?";
????
var?numargs?=?arguments.length;????//获取被传递参数的数值
????
var?expargs?=?argDemo.length;????????//获取期望参数的数值
????
if?(expargs?<?2){
????????msg?+=?expargs?+?
"argument.";
????}
else{
????????msg?+=?expargs?+?
"arguments.";
????}
????
if?(numargs?<?2){
????????msg?+=?numargs?+?
"was?passed.";
????}
else{
????????msg?+=?numargs?+?
"were?passed.";
????}
????msg?+=?
"\n\n";
????for?(i?=?0;?i?<?numargs;?i++?){????????
//获取参数内容
????????msg?+=?
"?arg"?+?i?+?"?=?"?+?arguments[i]?+?"\n";
????}
????alert(msg);
????
return?msg;
}
function?testArg(){
????alert(argDemo);
????argDemo(
"aaa","bbb");
}
//---------------------?caller?demo?---------------------
function?callerDemo()?{
????
if?(callerDemo.caller)?{
????????
var?a=?callerDemo.caller.toString();
????????alert(
"the?caller?is?\n"?+?a);
????}?
else?{
????????alert(
"this?is?a?top?function");
????}
}
function?handleCaller()?{
????callerDemo();
}
function?handleCaller2(){
????callerDemo();
}
function?testCaller(){
????alert(callerDemo);
????alert(testCaller);
????callerDemo();
????alert(handleCaller);
????handleCaller();
????alert(handleCaller2);
????handleCaller2();
}

//---------------callee?demo--------------
function?calleeDemo(){
????alert(arguments.callee);
}
//用于验证参数
function?calleeLengthDemo(arg1,?arg2){
????
if?(arguments.length?==?arguments.callee.length){
????????window.alert(
"验证形参和实参长度正确!");
????}
else{
????????alert(
"实参长度="?+?arguments.length?+?"\n形参长度="?+?arguments.callee.length);????
????}
}
//递归
var?calleeSum?=?function(n){
????
if?(n?<=?1){
????????
return?1;
????}
else{
????????
return?n?+?arguments.callee(n?-?1);????
????}
}
var?calleeSum2?=?function(n){
????
if?(n?<=?1){
????????
return?1;
????}
else{
????????
return?n?+?calleeSum2(n?-?1);????
????}
}
function?testCallee(){
????alert(calleeDemo);
????calleeDemo();
????alert(calleeLengthDemo);
????calleeLengthDemo(
"aabb");
????alert(calleeSum);
????alert(
"calleeSum="?+?calleeSum(5));
????alert(calleeSum2);
????alert(
"calleeSum2="?+?calleeSum2(5));
}
//-------------call?apply------------------
function?callBase(){
????
this.member?=?"callbase's?property";
????
this.method?=?function(){
????????alert(
"base:"+this.member);
????}
}
function?callExtend(){
????callBase.call(
this);
????alert(member);
????alert(
"extend:"?+?this.method);
}
function?testCall(){
????alert(callExtend);
????callExtend();????
}
var?applyShow?=?function?(s){
????alert(s);
}
function?applyDemo(){
????applyShow.apply(
this,arguments);
????alert(
this.applyShow);
}
function?testApply(){
????applyDemo(
"hahahahah");
}

//-----------------prototype?继承---------------------
var?Class?=?{
????create:?
function(){
????????
return?function(){this.initialize.apply(this,?arguments);}
????}
}
var?testClass?=?Class.create();
testClass.prototype={
????initialize:?
function(name){
????????
this.name?=?name;
????},
????al:?
function(){
????????
this.show.apply(this,arguments);
????},
????al2?:?
function(){
????????
return?function(){
????????????alert(
"this.show?=?\n"?+?this.show);
????????????
this.applyShow.apply(this,arguments);
????????};
????},
????show:?
function(s){
????????alert(s+
"ccc"+this.name);
????}
}
function?testPrototype(){
????
var?c?=?new?testClass("gemini");
????c.al(
"aaaa");
????c.al2()(
"zzzzz");
}
??
//]]>
??</
script>
?</
head>

?<
body>
?<
input?type='button'?value='测试Arguments'?onclick='testArg();'?/><br?/>
??<
input?type='button'?value='测试Caller'?onclick='testCaller();'?/><br?/>
??<
input?type='button'?value='测试Callee'?onclick='testCallee();'?/><br?/>
??<
input?type='button'?value='测试Call'?onclick='testCall();'?/><br?/>
??<
input?type='button'?value='测试Apply'?onclick='testApply();'?/><br?/>
??<
input?type='button'?value='测试Prototype'?onclick='testPrototype();'?/><br?/>
???</
body>
</
html>

?

?

  相关解决方案