来个有挑战的问题,有关Function.prototype

fangzhe 2006-03-13 10:07:57
来个有挑战的问题,各位高手请开动脑筋……

用js实现类似Function的caller属性的功能
原因是ECMA-262 Section 10.1.8规定了arguments.callee,但是没有caller,所以……

初步设想:
JS引擎里调用函数都是通过Function.prototype.call,可以通过以下重载用apply实现call
Function.prototype.call = function (obj) {
arguments.slice = Array.prototype.slice;
return this.apply(obj, arguments.slice(1));
}
在这里应该能通过stack存储函数调用顺序

请使用Gecko内核的浏览器调试

谢谢
...全文
304 13 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
fangzhe 2006-03-16
  • 打赏
  • 举报
回复
to fason:
本来用的系统的,随便搞来一个,见笑了

var _f_apply_foo = ['this', ''];
var _f_apply_obj = ['var r=obj[""]', '', 'delete obj[""]; r;'];
var _f_args = function(n){
var i=1, s='(';
if (n>0) for (s+='v[0]'; i<n; i++) s += ', v[' + i +']';
return _f_args[n] = s+');'
}

function _apply(obj, args) {
if (arguments.length=0) return this();

var v = args, a = _f_args;
var n = v?v.length.valueOf():0;
var cmd = (obj ? _f_apply_obj : _f_apply_foo).slice(0);

switch (typeof obj) {
case 'string': obj = new String(obj); break;
case 'number': obj = new Number(obj); break;
case 'boolean': obj = new Boolean(obj); break;
case 'function':;
}

// a reference of 'this' Function object
if (!(obj===undefined || obj===null)) obj[''] = this;
if (!(cmd[1]=a[n])) cmd[1]=a(n); // make arguments string
return eval(cmd.join('')); // call and return
}
最后把Function.prototype.apply=_apply就行了
fangzhe 2006-03-15
  • 打赏
  • 举报
回复
事实证明,这个是Misson Impossible
散分~
fason 2006-03-15
  • 打赏
  • 举报
回复
你的实现call是建立在apply基础上,你写个apply看看
fangzhe 2006-03-15
  • 打赏
  • 举报
回复
呵呵,你们实现call的方法都没有我的效率高
不过实现caller是不可能啦
散分……
clare2003 2006-03-15
  • 打赏
  • 举报
回复
<script language="JavaScript">
Function.prototype.call = function(sonFun)
{

if(sonFun instanceof Object == false){ // 如果 sonFun 不是 函数
return;}
sonFun.constructor.prototype.___base = this; // 定义 sonFun 的属性 __base 为当前调用 call 的函数
if(arguments.length == 1){ // 只有一个参数
sonFun.___base();
}else{
var aoEval = new Array();
for(var i=1; i<arguments.length; i++){
aoEval[aoEval.length] = "arguments["+i+"]"
}

aoEval = "sonFun.___base(" + aoEval.join(",") + ")"; // sonFun.__base(arguments[0], ...,arguments[i])
//alert(aoEval)
eval(aoEval);
}
}
</script>

<script>
// 动物类 animal
function animal(bSex){
this.sex = bSex
this.getSex = function(){
return this.sex
}
}
// 类静态变量 (如果你不修改它的话~~)
animal.SEX_G = new Object(); // 雌性
animal.SEX_B = new Object(); // 雄性

// 动物子类 鸟
function bird(bSex){
animal.call(this, bSex);
this.fly = function(iSpeed){
alert("飞行时速高达 " + iSpeed);
}
}

// 动物子类 鱼
function fish(bSex){
animal.call(this, bSex);
this.swim = function(iSpeed){
alert("游动时速高达 " + iSpeed)
}
}

// 鱼 鸟 杂交品种。。。
function crossBF(bSex){
bird.call(this, bSex);
fish.call(this, bSex);
}

var oPet = new crossBF(animal.SEX_G); // 雌性 鱼鸟
alert(oPet.getSex() == animal.SEX_G ? "雌性" : "雄性");
oPet.fly(124)
oPet.swim(254)

</script>
clare2003 2006-03-15
  • 打赏
  • 举报
回复
关注!
fangzhe 2006-03-14
  • 打赏
  • 举报
回复
meizz(梅花雪) 给的代码不行,_caller是undefined……
如果预先定义_caller,apply或者call里面对_caller的改变出了该过程就变回原样了
hbhbhbhbhb1021 2006-03-14
  • 打赏
  • 举报
回复
SORRY!忘记还有一个对象参数。楼主的代码是对的
hbhbhbhbhb1021 2006-03-14
  • 打赏
  • 举报
回复
楼主的这段代码中为什么还要slice一下啊
这个arguments本身就可以了。
<script language=javascript>
function abc(a,b,c)
{
alert(a);
alert(b);
alert(c);
}
Function.prototype.call = function (obj) {
return this.apply(obj, arguments);
}
abc.call('1','2','3');
</script>
fangzhe 2006-03-14
  • 打赏
  • 举报
回复
自己UP
meizz 2006-03-13
  • 打赏
  • 举报
回复
if(typeof(Function.prototype.apply)!="function")
{
Function.prototype.apply = function(obj, argu)
{
var s;
if(obj)
{
obj.constructor.prototype._caller=this;
s = "obj._caller";
}
else s = "this";
var a=[];
for(var i=0; i<argu.length; i++)
a[i] = "argu["+ i +"]";
return eval(s +"("+ a.join(",") +");");
};
Function.prototype.call = function(obj)
{
var a=[];
for(var i=1; i<arguments.length; i++)
a[i-1]=arguments[i];
return this.apply(obj, a);
};
}
fangzhe 2006-03-13
  • 打赏
  • 举报
回复
ps:这个是纯粹的科研……IE和Mozilla都有caller的实现
集思广益,欢迎大家提供点子
mingxuan3000 2006-03-13
  • 打赏
  • 举报
回复
mark

2,127

社区成员

发帖
与我相关
我的任务
社区描述
Web 开发 非技术区
社区管理员
  • 非技术区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧