在函数内部,有两个特殊的对象:arguments 和 this。其中,arguments 在第 3 章曾经介绍过, 它是一个类数组对象,包含着传入函数中的所有参数。虽然 arguments 的主要用途是保存函数参数, 但这个对象还有一个名叫 callee 的属性,该属性是一个指针,指向拥有这个 arguments 对象的函数。 请看下面这个非常经典的阶乘函数。

function factorial(num){

   if (num <=1) {

     return 1;

  } else {

     return num * factorial(num-1)

   }

}

定义阶乘函数一般都要用到递归算法;如上面的代码所示,在函数有名字,而且名字以后也不会变 的情况下,这样定义没有问题。但问题是这个函数的执行与函数名 factorial 紧紧耦合在了一起。为 了消除这种紧密耦合的现象,可以像下面这样使用 arguments.callee。

function factorial(num){

  if (num <=1) {

    return 1;

   } else {

     return num * arguments.callee(num-1)

  }

}

在这个重写后的 factorial()函数的函数体内,没有再引用函数名 factorial。这样,无论引用 函数时使用的是什么名字,都可以保证正常完成递归调用。

例如: var trueFactorial = factorial;

factorial = function(){

   return 0;

};

alert(trueFactorial(5)); //120

alert(factorial(5)); //0

在此,变量 trueFactorial 获得了 factorial 的值,实际上是在另一个位置上保存了一个函数 的指针。然后,我们又将一个简单地返回 0 的函数赋值给 factorial 变量。如果像原来的 factorial() 那样不使用 arguments.callee,调用 trueFactorial()就会返回 0。可是,在解除了函数体内的代 码与函数名的耦合状态之后,trueFactorial()仍然能够正常地计算阶乘;至于 factorial(),它现 在只是一个返回 0 的函数。

ECMAScript 5 也规范化了另一个函数对象的属性:caller。除了 Opera 的早期版本不支持,其他 浏览器都支持这个 ECMAScript 3 并没有定义的属性。这个属性中保存着调用当前函数的函数的引用, 如果是在全局作用域中调用当前函数,它的值为 null。

例如: function outer(){

   inner();

}

function inner(){

  alert(inner.caller);

}

outer();

以上代码会导致警告框中显示 outer()函数的源代码。因为 outer()调用了 inter(),所以 inner.caller 就指向 outer()。为了实现更松散的耦合,也可以通过 arguments.callee.caller 来访问相同的信息。

function outer(){

  inner();

}

function inner(){

  alert(arguments.callee.caller);

}

outer();

IE、Firefox、Chrome 和 Safari 的所有版本以及 Opera 9.6 都支持 caller 属性。 当函数在严格模式下运行时,访问 arguments.callee 会导致错误。ECMAScript 5 还定义了 arguments.caller 属性,但在严格模式下访问它也会导致错误,而在非严格模式下这个属性始终是 undefined。定义这个属性是为了分清 arguments.caller 和函数的 caller 属性。以上变化都是为 了加强这门语言的安全性,这样第三方代码就不能在相同的环境里窥视其他代码了。 严格模式还有一个限制:不能为函数的 caller 属性赋值,否则会导致错误。

转载于:https://www.cnblogs.com/fanting/p/9355545.html

5.5.4 函数内部属性相关推荐

  1. js函数的内部属性---arguments,callee,caller

    在接下来的几篇文章中,我大家谈谈函数的内部属性,arguments,callee,caller (1)arguments,是一个类数组对象,其中包含了传入函数的所有参数,主要用途是,保存函数的参数: ...

  2. vue的methods属性的方法中出现回调函数,在回调函数内部获取data中的数据

    在vue中,可能会遇到在methods属性中书写的方法中出现回调函数的情况,如以下代码: data(){return{gemometry: ""} } methods: {draw ...

  3. 关于Java函数传参以及参数在函数内部改变的问题——JAVA值传递与引用最浅显的说明!...

    看了很多关于阐述JAVA传参到底是值传递还是引用的问题,有些说得很肤浅让人感觉似懂非懂的感觉,但是好像又能解决一些问题,然后就止步了.还有一些则是,讲得很深奥,看着好像很有道理的样子,但是其实还是没怎 ...

  4. Spark RDD概念学习系列之RDD的重要内部属性(十五)

    RDD的重要内部属性 通过 RDD 的内部属性,用户可以获取相应的元数据信息.通过这些信息可以支持更复杂的算法或优化. 1)分区列表:通过分区列表可以找到一个 RDD 中包含的所有分区及其所在地址. ...

  5. 面向对象--内部属性类型

    js中的对象有一些内部才用的特性,这些特性是为了实现javascript引擎用的,因此在javascript中不能直接访问它们. 有两种属性:数据属性 && 访问器属性 数据属性 [[ ...

  6. JavaScript程序开发(十五)—函数的属性和方法

    在函数内部,有两个特殊的对象-arguments和this.arguments主要是保存函数的参数,但是这个对象还有一个叫callee的属性,该属性是一个指针,指向拥有这个arguments对象的函数 ...

  7. c语言之函数存储属性,C语言:链接属性与存储类型

    一. 链接属性 C语言中链接属性决定如何处理在不同文件中出现的标示符.标示符的作用域与它的链接属性有关,但这两个属性并不相同. 链接属性有3种: external(外部),internal(内部) 和 ...

  8. javasrcipt的作用域和闭包(二)续篇之:函数内部提升机制与Variable Object

    一个先有鸡还是先有蛋的问题,先看一段代码: a = 2; var a; console.log(a); 通常我们都说JavaScript代码是由上到下一行一行执行,但实际这段代码输出的结果是2.但这段 ...

  9. C++57个入门知识点_40 常成员函数(用于定义不可修改类内部成员变量的函数,一般用来修饰Get函数;常成员函数this指针:const T* const;常成员函数内部变量修改方法:强转/关键字)

    前面我们已经学习了C++中重要的知识点,特别是虚函数可能会有些懵逼,但是需要我们在实践中不断的理解和尝试,写代码是进步最快的方式,接下来将会介绍一些简单但很重要的知识点,本篇介绍常成员函数. 总结: ...

最新文章

  1. 长短视频之争,长视频平台和短视频源码谁主沉浮?
  2. struts2_对Map进行双层迭代
  3. Django MEDIA_URL 路径正确仍然不显示照片
  4. sklearn pipeline_sklearn基础
  5. css索引_CSS中的Z索引:它是什么以及它做什么
  6. java并发编程之原子性、可见性、有序性
  7. 读书笔记之101个脚本之No.8
  8. Python之math库
  9. WEB小知识学习集锦
  10. java修改request的paramMap
  11. TestReport目录
  12. 系统集成j2cache
  13. 计算机中加密文件找不见,打开或解密闪电加密文件夹找不到加密数据怎么办
  14. 第二集 第一魂环 第十五章
  15. python绘制地图地图cartopy_python Cartopy的基础使用详解
  16. CMock使用手册翻译
  17. Android开发之仿360手机卫士悬浮窗效果
  18. 俄罗斯方块游戏开发教程7:消除判断和处理
  19. Unicode特殊字符编码
  20. 网页的linke rel=icon详解 favicon深究

热门文章

  1. D - 小晴天老师系列——晴天的后花园
  2. 牛顿求平方根法(输入是double,输出也是double)
  3. C#调用浏览器的原理及实现浅析
  4. Vue HTML:在Vue上写Html遇到的一些问题,html的首行缩进,html的行间距,element UI的回到顶部不显示
  5. Ubuntu安装Rstudio
  6. hive查询where join_Hive系列(4):常用函数where,join
  7. Opencv定义感兴趣区域
  8. CPD和DESCR文件查看
  9. DrawText函数
  10. mac mysql log_mac如何开启mysql bin-log