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

caller 仿冒,有浏览器兼容性问题!纯属探讨测试

阅读更多

首先,我不知道这个方法能怎么应用,仅仅知道这是一种无副作用的方法(虽然看似多余的丑陋的怪异的方法,),而且有浏览器兼容性问题,不知道ecma-262是如何定义caller的.

function foo(s){
  if (!s){
    f.caller=function(s){alert('ya......'+s)};
    f();
  }else
    alert(s);
}
function f(){
  var caller=arguments.callee.caller;
  delete arguments.callee.caller;
  arguments.callee.caller('foo');
  caller('foo');
}
foo();
 

 

分享到:
评论
16 楼 hax 2008-07-26  
zbm2001 写道
什么叫“一个函数在调用链上出现两次”?

“但是这样为什么不直接作为参数传入呢”,你指的是类似W3C事件函数的事件对象(e)传参方式?



假设调用链是:
a -> b -> c -> c -> ...

其中 c 进行了递归调用。
则 c.caller 就是 c,你无法回溯到b了。


除非caller不是在function实例上,而是一个函数局部变量类似arguments。但是在这种情况下,实际相当于函数增加了一个参数(即调用者)。

所以在实践中caller是几乎没有意义的。
15 楼 zbm2001 2008-07-25  
什么叫“一个函数在调用链上出现两次”?

“但是这样为什么不直接作为参数传入呢”,你指的是类似W3C事件函数的事件对象(e)传参方式?

14 楼 hax 2008-07-25  
Function.caller现在的定义显然有一个问题,就是无法支持一个函数在调用链上出现两次。而且在function实例上不可能支持。除非定义在一个调用时的变量上,类似arguments(但是这样为什么不直接作为参数传入呢)。

而且总的来说caller似乎也没什么特别用途。
13 楼 afcn0 2008-07-17  
为什么要知道每个函数对象execution context对应的调用函数,如果非得想知道,大可以把函数引用传近来,caller意义不大
12 楼 csf178 2008-07-17  
zbm2001 写道
arguments是运行期的这个一点没错,但是我相信规范制定者不会看不到这点的。
丢弃它,我猜想一定是引擎实现上的某些原因导致的。

引擎需要获得一个函数运行时的arguments.caller,根据调用栈scope逐步查找,首先当然是找到创建这个arguments的函数运行时scope,然后再找到调用这个函数的上层scope,然后再查找(如果存在)上层scope的arguments.caller……
表现为:
arguments.caller.arguments.caller.arguments.caller……

而arguments.callee.caller则表现为:
arguments.callee.caller.caller.caller……

所以我觉得arguments.caller在引擎实现上的实际过程可能就是基于后者的(不一定是脚本里的.caller)。

至于arguments.callee.caller有二义性,arguments.caller也一样啊,只不过因为arguments本身定死了是只读的而已。
按一楼这种硬编码式的修改,javascript等动态语言很多基本属性都有这种问题。

还是老话,任何事情只有更好,没有最好,希望老大们更好的指正。

其实标准里面没有caller
我说arguments.caller比较合适的唯一理由是每次arguments构造对应着一个function call
caller没法从scope chain上找出来 是个麻烦的事情
11 楼 zbm2001 2008-07-17  
arguments是运行期的这个一点没错,但是我相信规范制定者不会看不到这点的。
丢弃它,我猜想一定是引擎实现上的某些原因导致的。

引擎需要获得一个函数运行时的arguments.caller,根据调用栈scope逐步查找,首先当然是找到创建这个arguments的函数运行时scope,然后再找到调用这个函数的上层scope,然后再查找(如果存在)上层scope的arguments.caller……
表现为:
arguments.caller.arguments.caller.arguments.caller……

而arguments.callee.caller则表现为:
arguments.callee.caller.caller.caller……

所以我觉得arguments.caller在引擎实现上的实际过程可能就是基于后者的(不一定是脚本里的.caller)。

至于arguments.callee.caller有二义性,arguments.caller也一样啊,只不过因为arguments本身定死了是只读的而已。
按一楼这种硬编码式的修改,javascript等动态语言很多基本属性都有这种问题。

还是老话,任何事情只有更好,没有最好,希望老大们更好的指正。
10 楼 achun 2008-07-17  
zbm2001 写道
嗯,应该是一个实时调用的getter访问,

表现上的怪异可能是有点,但如果作为arguments的属性,似乎也有不妥的地方。

现在的标准抛弃了它——这个还真不知道,csf178 能否详细点说明一下?

如果已不是标准,再讨论这个caller的价值就不大了。

还有,如果已不是标准,有什么好的代替方法获取这个caller呢……
比如像我在4#楼给出的示例。

我的标题都明确了不标准不兼容,纯属讨论的.所以价值问题不是基于浏览器和标准的,是基于用途的.
首先我认为,arguments这个运行期设施是很有价值的,但是把caller附在arguments.callee.caller这个位置不怎么好,
还是直接arguments.caller的好,因为arguments是运行期的,而arguments.callee.caller有二义性,可能和原属性冲突.
这一点是和csf178的观点是一致的.
不过从一些文章上看,(mozilla的)
引用

arguments.caller can no longer be used. You can use the non-standard caller property of a function object instead. See its description for details.

arguments.caller property is only available within the body of a function.

关于Function:caller的说明
引用

If the function f was invoked by the top level code, the value of f.caller is null, otherwise it's the function that called f

This property replaces deprecated arguments.caller.

貌似由于某种原因主动抛弃了arguments.caller这种用法.不明白.
9 楼 zbm2001 2008-07-17  
嗯,应该是一个实时调用的getter访问,

表现上的怪异可能是有点,但如果作为arguments的属性,似乎也有不妥的地方。

现在的标准抛弃了它——这个还真不知道,csf178 能否详细点说明一下?

如果已不是标准,再讨论这个caller的价值就不大了。

还有,如果已不是标准,有什么好的代替方法获取这个caller呢……
比如像我在4#楼给出的示例。
8 楼 csf178 2008-07-16  
caller并不是一个简单的属性 它的实现一般应该是一个getter 访问时沿着函数的调用栈去查函数的最后一次调用 否则函数嵌套的多次调用时caller将会出错
我想大概因为作为函数属性这种形式比较怪异(我倒觉得不如作为arguments的属性),现在的标准才抛弃了它。

所以说很难说delete对它会产生什么效果 况且没有标准规定谁也不知道caller是不是dont delete的
7 楼 zbm2001 2008-07-16  
你指的是你一楼的示例里仿冒了一个caller方法属性,

你的这个实际应用,可以用其他方法实现达到一致的效果啊,没必要非得和caller掺和在一块,
看不出有必要把“可以delete”上升到加入ECMA规范的基础方法。
6 楼 achun 2008-07-16  
zbm2001 写道
这是另外一个浏览器实现方法的细节问题了,注意下就是了

还有,不知道你要delete它干什么?

因为caller 仿冒了,如果可以delete的话,那么真正的caller就会恢复.
这样相当于无副作用的一次传入了两caller,
至于怎么用,有什么用是应用的问题,设计考虑的是模式,应用是千变万化的.可惜不标准,不兼容.
5 楼 zbm2001 2008-07-16  
这是另外一个浏览器实现方法的细节问题了,注意下就是了

还有,不知道你要delete它干什么?
4 楼 achun 2008-07-16  
zbm2001 写道
IE/FF/safari等几大浏览器引擎都支持,

就opera不支持,最新的9.51仍然是这样。

“看似多余的丑陋的怪异的方法”这个观点不太同意,特别是基于W3C事件模型的事件对象捕捉。若不是opera也有个window.event对象,稍微复杂点的DOM事件函数还真是有点麻烦。要不然,多层函数调用获取事件对象时,每层都得对事件对象传参。

delete arguments.callee.caller;
IE就不支持,FF支持,其他的没有测试.
这个方法是我自己想出来的,因为连IE都不支持,当然只能说是:看似多余的丑陋的怪异的方法了
3 楼 zbm2001 2008-07-16  
IE/FF/safari等几大浏览器引擎都支持,

就opera不支持,最新的9.51仍然是这样。

“看似多余的丑陋的怪异的方法”这个观点不太同意,特别是基于W3C事件模型的事件对象捕捉。若不是opera也有个window.event对象,稍微复杂点的DOM事件函数还真是有点麻烦。要不然,多层函数调用获取事件对象时,每层都得对事件对象传参。

caller方法可以不受多层函数调用的限制,比如捕捉事件对象,类似这样:

var caller=arguments.callee;
while(caller.caller){
  caller=caller.caller;
}
var event=caller.arguments[0];
2 楼 achun 2008-07-16  
csf178 写道
caller非标准 Opera不支持 没了

根据ECMA-262 Section 10.1.8的规定⋯⋯

那用了caller就会造成兼容性问题,官方在新版里有可能增加支持么?
貌似 ECMA-262-4 要增加,不过谁知道到哪年了
1 楼 csf178 2008-07-16  
caller非标准 Opera不支持 没了

相关推荐

    Firefox浏览器兼容JS脚本

    本文将围绕Firefox浏览器与Internet Explorer(简称IE)之间关于JavaScript脚本的兼容性差异进行详细探讨,并通过具体的示例来帮助开发者更好地理解和解决实际开发过程中遇到的问题。 #### 二、关键知识点详解 ###...

    浏览器兼容问题

    因此,为了实现跨浏览器的兼容性,我们需要使用如下代码来获取事件对象: ```javascript var newEvent = window.event || arguments.callee.caller.arguments[0]; ``` 此外,阻止事件的默认行为在IE和非IE浏览器中...

    JavaScript 操作键盘的Enter事件(键盘任何事件),兼容多浏览器.docx

    在实现 JavaScript 操作键盘的 Enter 事件时,需要考虑多浏览器的兼容性问题。不同的浏览器对键盘事件的处理方式不同,例如,IE 浏览器使用 window.event 对象,而 Mozilla 浏览器使用 event 对象。 为解决这个问题...

    手机ud-caller

    "手机ud-caller"是一款专为黑莓8900设计的应用程序,旨在提供便捷的通话功能和服务。ud-caller数据库的最新版本确保了用户在安装后无需再进行繁琐的数据库更新,从而节省时间和精力,提高了用户体验。这个应用可能...

    matlab开发-caller2base

    `test_caller2base.m`是测试文件,通常会包含一系列测试用例,用于验证`caller2base`功能的正确性和性能。编写测试用例是确保代码质量的重要步骤,通过模拟不同的使用场景,可以发现潜在的错误和改进点。 至于`...

    srt协议的caller模式的c语言源码

    - **调试和测试**:通过网络模拟工具或实际的SRT服务器测试源码的功能和性能,确保连接和数据传输的正确性。 通过理解和学习这些知识点,开发者可以更好地利用提供的C语言源码,进一步开发和优化SRT应用,提升实时...

    Devel-Caller-Perl-1.4.tar.gz

    在解压"Devel-Caller-Perl-1.4.tar.gz"之后,你会得到一个名为"Devel-Caller-Perl-1.4"的目录,里面通常包含源码、测试文件、文档和安装脚本等。开发者可以通过Perl的CPAN(Comprehensive Perl Archive Network)...

    event兼容调用(IE,Firefox,Chrome)

    在跨浏览器开发中,处理事件(event)的兼容性问题是一项常见的挑战。不同的浏览器对事件模型的支持程度不同,这导致了开发者在编写JavaScript代码时需要考虑多种情况,以确保代码在各种浏览器上都能正常运行。本文...

    Caller-Id-DTMF.rar_caller id_full

    此外,文件可能还会探讨两者之间的交互,比如如何在电话通信中同时传递呼叫者ID信息和DTMF信号,以及在安全性和隐私方面的问题。 总的来说,这个资料包对于理解电话系统的内部运作、增强通信安全意识,以及了解如何...

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

    这篇文章将深入探讨四个关键概念:caller、callee、call和apply,它们都是JavaScript函数操作的核心部分,对于理解和使用高级JavaScript编程至关重要。 首先,我们来了解`caller`和`callee`。在JavaScript的函数...

    理解JavaScript的caller callee call apply

    ### 理解JavaScript中的`caller`...综上所述,理解`caller`、`callee`、`call`、`apply`以及`arguments`对象在JavaScript编程中至关重要,它们不仅增强了函数的灵活性和复用性,还提供了深入分析和调试代码的强大工具。

    Caller ID 检测算法和源代码

    有针对 TI C5000的优化 检测 , 优化 , 源代码 Caller ID Detector.zip 102.96 KB, 下载次数: 15 , 下载积分: 资产 -2 信元, 下载支出 2 信元

    caller_id.rar_phone

    10. **测试**:确保电话号码显示功能的正确性需要进行功能测试、性能测试、兼容性测试以及用户体验测试。 11. **更新和维护**:随着新的操作系统版本和设备推出,应用需要持续更新以保持兼容性,同时,可能需要根据...

    T-ONE WEB CALLER-crx插件

    安装过程中,需要注意兼容性问题以及可能的安全风险,确保从官方渠道下载,并时刻保持插件更新以获得最新的功能和安全补丁。 总结来说,T-ONE WEB CALLER-crx插件是一款提升企业内部通信效率的工具,它通过PBX扩展...

    DTMF_CallerID.rar_DTMF C.id_dtmf caller

    5. **兼容性和互操作性**:讨论不同品牌和型号的电话设备如何确保在DTMF来电显示上的兼容性。 6. **测试与验证**:提供了一套测试方案,以确保设备符合国标要求,确保可靠性和一致性。 7. **安全与隐私**:可能...

    event对象获取方法总结在google浏览器下测试

    总的来说,理解并熟练运用这些Event对象的获取方法,有助于在Google浏览器以及其他浏览器中编写高效且兼容性良好的JavaScript代码。在实际开发中,应根据项目需求和目标用户群体的浏览器分布来选择最合适的获取策略...

    event对象的方法 兼容多浏览器

    在Web开发中,事件处理是不可或缺的一部分,而`event`对象是事件处理中的核心元素,它提供了关于事件的详细...在实际项目中,还可以考虑使用库或框架(如jQuery、React等)来自动处理这些兼容性问题,简化开发工作。

    JavaScript 操作键盘的Enter事件(键盘任何事件),兼容多浏览器

    知识点包括了键盘事件的捕捉、事件对象的兼容处理、以及特定浏览器的兼容性问题。 ### 键盘事件捕捉 在Web开发中,键盘事件主要通过以下几种方式触发: - `keydown`:在按键被按下时触发。 - `keypress`:在字符...

    火狐下event的使用

    通过上述介绍,我们可以看到,在处理跨浏览器的事件兼容性问题时,需要注意不同的浏览器可能对相同的事件模型有不同的实现方式。对于火狐浏览器而言,直接使用`event`可能存在问题,因此我们需要采取一些额外的措施...

Global site tag (gtag.js) - Google Analytics