`
achun
  • 浏览: 314187 次
  • 性别: Icon_minigender_1
  • 来自: 河南郑州
社区版块
存档分类
最新评论

善用arguments.callee.apply,让递归兼容Mixin,正确继承this

阅读更多

javascript 中递归的使用也是常见的.比如遍历DOM树.

在我们熟悉的js框架(jQuery,prototype等)中都有递归的身影.

Mixin在很多语言里都有实现,对于动态的javascript实现更是简单,只不过是成员赋值就行了.

那么这两者有什么联系?兼容又从何而来?

代码说话:

function foo1(c){
  alert(c+a +':'+(this.constructor));//这里的信息足以说明不同了
  a++;
  if (a>1) return;//跳出递归
  foo1(c);//直接递归
}
function foo2(c){
  alert(c+a +':'+(this.constructor));//这里的信息足以说明不同了
  a++;
  if (a>1) return;//跳出递归
  arguments.callee.apply(this,arguments);//兼容Mixin的递归
}

var a=0;//为了跳出递归设置的变量
foo1('foo1:');
var a=0;
foo2('foo2:');
var f={};
f.ff=foo1;//这就是javascript最简单形式的Mixin了
var a=0;
f.ff('foo1Mixin:');
f.ff=foo2;
var a=0;
f.ff('foo2Mixin:');

 

分享到:
评论
24 楼 csf178 2008-07-06  
afcn0 写道
SCIM识别率还是很高,比智能ABC错误少,(第一天使用Ubuntu8.04)

嗯 这几个输入法都跟马尔可夫链有关系......
23 楼 afcn0 2008-07-06  
SCIM识别率还是很高,比智能ABC错误少,(第一天使用Ubuntu8.04)
22 楼 afcn0 2008-07-06  
最后一句,是另外一帖里面的,我只能那么表述,后面也详细解释了,就是错误的scope对象被eval使用了,评价lz的帖子,只是评价起中的修改this以及callee概念,对于楼主要讲得东西,只有代马上的认识
21 楼 achun 2008-07-06  
还是hax说话,逻辑性,理论性强.
鲁棒
好词。
20 楼 hax 2008-07-06  
csf178 写道
知道马尔可夫链不?马尔可夫链算法可以用于随机生成一些可以阅读的文本(请参看《程序设计实践》)。

你说的话实在太像根据关于JS的各种文档用马尔可夫链算法生成的文本了,词还是那些词,不过组合出来完全不知道是什么意思。

像什么"this的context"、"call和.可以改变函数执行的context"、"apply call修改的context"

特别是"对于function默认执行aaa自己变量返回的特有对于eval产生scope当作context特殊对象有关",说实话,我真的看到这句话第一眼就想到马尔可夫链了.

不但把所有概念全都用错了 而且中文根本不成句 更不用提话本身的正确性了



前面几句话的意思还是很明确的,当然是可以说得更易懂一些,不过这是论坛么,大家看得懂就好了。

至于最后那个话,确实太曲折了,怀疑当中有打错字。不过联系上下文还是能知道他说的是什么问题的。
19 楼 hax 2008-07-06  
afcn0 写道
你们在讨论什么,arguments.callee什么含义?就是调用当前参数对象的被调用函数,废话当然就是foo1或foo2函数本身,为什么你说开始会有不同,废话,apply(this和foo1()直接能一样吗,this的context就会随着执行变化而变化,而foo1(可能吗?

foo1就===arguments.callee

最后,你们说的什么ms不支持什么ff.i_temp什么东西,哪个是ie只支持FunctionDeclaration不支持FunctionExpression,结果更是废话,回去好好看看权威指南再来发帖子


火气不用那么大吧?

我觉得楼主的用意是好的,不过其实可以说的更明白一点。

那就是:

arguments.callee 是一个鲁棒的引用自身的方式,而直接用函数名则不够鲁棒。如果是内部函数自然无所谓,但是如果你的函数是面向外部用户的,则就要小心,因为外部用户的使用改函数的方式可能超出你的本意。

例如不是作为函数,而是作为一个对象上的方法。或者可能被用作所谓mixin。另外有可能在调用过程中(恶意或不经意的)修改名称。这参见:改写函数实际上违背了FP的无副作用的精神
18 楼 csf178 2008-07-06  
知道马尔可夫链不?马尔可夫链算法可以用于随机生成一些可以阅读的文本(请参看《程序设计实践》)。

你说的话实在太像根据关于JS的各种文档用马尔可夫链算法生成的文本了,词还是那些词,不过组合出来完全不知道是什么意思。

像什么"this的context"、"call和.可以改变函数执行的context"、"apply call修改的context"

特别是"对于function默认执行aaa自己变量返回的特有对于eval产生scope当作context特殊对象有关",说实话,我真的看到这句话第一眼就想到马尔可夫链了.

不但把所有概念全都用错了 而且中文根本不成句 更不用提话本身的正确性了
17 楼 afcn0 2008-07-06  
楼上这种物质言论我就不评价了,apply call修改的context如果不是this那就没必要讨论了,我的语文还是很清楚地
16 楼 csf178 2008-07-06  
afcn0 写道
this的context就会随着执行变化而变化

话说 一知半解比无知更可怕啊......
this的context是什么东西呢
15 楼 afcn0 2008-07-05  
2个相关帖子http://www.iteye.com/post/408365 http://www.iteye.com/post/438660
用arguments.callee.call执行完全递归好似是理所应当的
14 楼 achun 2008-07-05  
afcn0 写道
我的blog上面那个只是说明利用中间对象修改__proto__属性,实现原型链多继承一种方式,因为多继承实体继承简单,圆形继承困难
而我回你的帖子只是说明你所讨论的所有问题就是arguments.callee===本函数,并且解释了call和.可以改变函数执行的context
最后关于ie问题,我只是作出了ie不支持函数直接表达式的解释,所有都是函数声明,在我以前也讨论过

我这个帖子真不是讨论什么arguments.callee,讨论的是arguments.callee在继承中发挥的作用.
也就是怎么样写代码才能真正的实现无错误继承(还有虚函数).
换句话就是:
如果我们写一个函数目的就是为了让别的对象继承的.那这个函数怎么写才能万无一失(这个词有些夸张,要靠实践才能认定).
13 楼 afcn0 2008-07-05  
我的blog上面那个只是说明利用中间对象修改__proto__属性,实现原型链多继承一种方式,因为多继承实体继承简单,圆形继承困难
而我回你的帖子只是说明你所讨论的所有问题就是arguments.callee===本函数,并且解释了call和.可以改变函数执行的context
最后关于ie问题,我只是作出了ie不支持函数直接表达式的解释,所有都是函数声明,在我以前也讨论过
12 楼 achun 2008-07-05  
<div class='quote_title'>afcn0 写道</div>
<div class='quote_div'>你们在讨论什么,arguments.callee什么含义?就是调用当前参数对象的被调用函数,废话当然就是foo1或foo2函数本身,为什么你说开始会有不同,废话,apply(this和foo1()直接能一样吗,this的context就会随着执行变化而变化,而foo1(可能吗?<br/><br/>foo1就===arguments.callee <br/><br/>最后,你们说的什么ms不支持什么ff.i_temp什么东西,哪个是ie只支持FunctionDeclaration不支持FunctionExpression,结果更是废话,回去好好看看权威指南再来发帖子</div>
<p> </p>
<p>同学,你还记得你的博客上有一篇</p>
<h3><a href='http://afcn0.iteye.com/blog/132590'>JavaScript原形链多继承函数</a></h3>
<p>我这里讨论的和你的这篇文章有相似之处,只不过我没有用多继承这个词汇.</p>
<p>arguments.callee是如此的至关重要.</p>
<p>善用了arguments.callee不但兼容了<strong><span style='background-color: #ff6600;'>多继承</span></strong>,而且还可以兼容向c++里的<strong style='background-color: #ff6600;'>虚函数</strong>的方法.</p>
<p>你再仔细对比一下你的方法,和我这里说的方法的区别.</p>
<p>对你的</p>
<div class='quote_title'>afcn0 写道</div>
<div class='quote_div'>.....废话.....</div>
<p>无所谓,因为我要表达的东西,往往很难让人明白我在说什么.</p>
<p>对你的</p>
<div class='quote_title'>afcn0 写道</div>
<div class='quote_div'>.....回去好好看看权威指南再来发帖子.......</div>
<p>我不是在这里讨论javascript的特性的,是为了解决问题的.是在找方法,做实验的.</p>
<p>你再仔细看看这一段</p>
<pre name='code' class='js'>var a=0;//为了跳出递归设置的变量 
foo1('foo1:'); 
var a=0; 
foo2('foo2:'); 
var f={}; 
f.ff=foo1;//这就是javascript最简单形式的Mixin了 
var a=0; 
f.ff('foo1Mixin:'); 
f.ff=foo2; 
var a=0; 
f.ff('foo2Mixin:');  </pre>
 
<p>foo1就===arguments.callee,但是写法不同对于继承的影响可就不一样了.</p>
11 楼 bbs 2008-07-05  
afcn0 写道
回去好好......再来......

这是JavaEye特色么 haha 这几天经常看到
10 楼 afcn0 2008-07-05  
还有这个论坛不登陆回帖,登陆回来就没了,太郁闷了,管理员修改修改代码
9 楼 afcn0 2008-07-05  
你们在讨论什么,arguments.callee什么含义?就是调用当前参数对象的被调用函数,废话当然就是foo1或foo2函数本身,为什么你说开始会有不同,废话,apply(this和foo1()直接能一样吗,this的context就会随着执行变化而变化,而foo1(可能吗?

foo1就===arguments.callee

最后,你们说的什么ms不支持什么ff.i_temp什么东西,哪个是ie只支持FunctionDeclaration不支持FunctionExpression,结果更是废话,回去好好看看权威指南再来发帖子
8 楼 achun 2008-07-05  
<p>刚刚产生了一个新的想法.<br/>既然javascript有如此这般的特性.<br/>那能否把一些常用的算法都重新写成<br/><strong><span style='color: #993300;'>完全兼容Mixin的形式</span></strong><br/>通过组合这些基本的函数,就可以形成不同的应用需求.<br/>目前只是一个想法.<br/>那到底哪些方面的函数可以这样写呢?</p>
7 楼 csf178 2008-07-01  
笨笨狗 写道
IE不支持么?这个倒没证实过,因为并不常用,一般都callee了。
如果真是如此,也无话可说,M$的德行就那样,直接无视罢了。

社区的力量是如此巨大......
所谓众口铄金啊......
怎么也想不出FF如何变成的社区里正义的化身
OK 大家继续打倒蓝色幽浮 拯救人类吧 - -!
潜水吃饭
6 楼 achun 2008-07-01  
各位帮我看看这个帖子
http://www.iteye.com/topic/209575
帮忙起个标题吧,我找不到合适的词汇.
5 楼 笨笨狗 2008-07-01  
IE不支持么?这个倒没证实过,因为并不常用,一般都callee了。
如果真是如此,也无话可说,M$的德行就那样,直接无视罢了。

相关推荐

    JavaScript arguments.callee作用及替换方案详解

    4. **ES6的箭头函数**:箭头函数没有自己的`this`、`arguments`、`.call`、`.apply`和`.constructor`等方法,因此它们无法使用`arguments.callee`。在ES6中,通常建议使用`let`或`const`来声明一个内部函数,然后...

    js arguments.callee的应用代码

    这个特性在现代JavaScript编程中已经不推荐使用,但在老旧的代码中还是可以看到它的影子,特别是在使用递归调用函数时,arguments.callee可以用来引用函数自身,无需使用函数名。 在介绍arguments.callee的应用之前...

    Javascript中arguments和arguments.callee的区别浅析

    在JavaScript中,`arguments` 和 `arguments.callee` 都是与函数参数相关的特殊对象,但它们的作用和用途略有不同。下面将详细解释这两个概念及其区别。 `arguments` 对象是一个类数组对象,它包含了函数调用时传入...

    Javascript函数中的arguments.callee用法实例分析

    这样一来,即使fac函数名被重新赋值为另一个函数,arguments.callee仍然能够引用到原来的递归函数,使得递归调用可以正常工作。具体来说,arguments.callee(num-1)能够继续递归地计算阶乘,即使fac已经被覆盖。 在...

    js代码-arguments.callee

    总的来说,虽然`arguments.callee`在过去的JavaScript开发中起到了重要作用,但随着语言的进化,开发者应逐渐适应不依赖`arguments.callee`的编程风格,充分利用ES6及更高版本提供的新特性,编写更加高效、简洁的...

    js的隐含参数(arguments,callee,caller)使用方法.docx

    这意味着你可以通过`arguments.callee`来引用调用函数,这对于匿名函数或者递归调用非常有用,因为匿名函数没有名字,无法直接引用自身。 ```javascript (function sum(n) { if (n === 1) return 1; return n + ...

    js中arguments,caller,callee,apply的用法小结.docx

    然而,由于这种用法可能导致难以调试的代码,ES5严格模式下会禁止使用arguments.callee。 4. **apply方法** apply是Function对象的一个方法,允许改变函数调用的上下文(即this值)以及传入参数。它接受两个参数:...

    解析 this.initialize.apply(this, arguments)

    标题 "解析 this.initialize.apply(this, arguments)" 涉及到的是JavaScript编程中的一个关键概念,尤其是在对象构造和类继承的情景下。`this` 关键字在JavaScript中扮演着核心角色,它指的是函数调用时的上下文,而...

    js的隐含参数(arguments,callee,caller)使用方法

    在JavaScript编程中,arguments、caller和callee是函数对象自带的三个隐含参数,它们为开发者提供了额外的函数执行信息,尤其在处理函数参数、递归调用以及调用栈追踪时非常有用。下面详细介绍这些隐含参数的使用...

    详解JavaScript函数callee、call、apply的区别

    以下是一个使用`arguments.callee`实现递归的例子: ```javascript function sum(num) { if (num ) { return 1; } else { console.log(num, arguments.callee(num - 1)); return num * arguments.callee(num -...

    【JavaScript源代码】JavaScript中arguments的使用方法详解.docx

    JavaScript中的`arguments`对象是一个...通过`arguments.length`可以获取参数个数,通过索引访问参数值,以及利用`arguments.callee`实现递归等功能。在编写函数时,善用`arguments`可以使代码更具灵活性和可扩展性。

    javascript中arguments,callee,caller详解

    例如,在匿名递归函数中,你可以通过arguments.callee来避免因函数名改变而需要修改递归调用的地方。但是,在ECMAScript 5的严格模式中,对arguments.callee的引用也是不允许的,使用时也会抛出TypeError。 在实际...

    理解JavaScript的caller callee call apply

    2. **`length`属性**:`arguments.length`返回传递给函数的实际参数数量。 3. **动态性**:即使函数定义时没有指定参数,`arguments`也可以捕获所有传入的参数。 #### caller属性:追踪函数调用链 `caller`属性...

    Javascript - 全面理解 caller,callee,call,apply (转载)

    // 在旧版本浏览器中,arguments.callee会指向这个匿名函数 ``` 接下来,我们讨论`call`和`apply`,它们是JavaScript中函数调用的两种特殊方式。`call`和`apply`的主要区别在于传递参数的方式:`call`接受一个参数...

    Javascript 实现匿名递归的实例代码

    匿名递归主要通过`arguments.callee`属性来实现,但在现代JavaScript中,应尽可能避免使用这一非标准特性,转而采用更现代的解决方案,如闭包和`self`引用。理解这些递归技巧对于提升JavaScript编程能力非常重要。

Global site tag (gtag.js) - Google Analytics