• 函数的内部属性-读书笔记


    函数内部,有两个特殊的对象:arguments和this。

    一、arguments

    arguments的作用是保存传入函数中的所有参数,而且这个arguments有一个名叫callee的属性,这个属性是一个指针,指向拥有arguments对象的函数。

    举个递归算法---阶乘函数的例子:

    function factorial(num){
        if(num<=1){
            return 1;
        }else{
            return num*factorial(num-1)
        }  
    }    

    上面的代码,在函数有名字,而且名字以后也不会变的情况下,这样定义没有啥问题。不过,这样这个函数的执行与函数名紧紧耦合在一起了。所以为了消除这种紧密耦合,我们可以使用arguments.callee。

    function factorial(num){
        if(num<=1){
            return 1;
        }else{
            return num*arguments.callee(num-1)
        }  
    } 

    这样,无论引用函数时使用什么名字,都可以保证正常完成递归调用。举个例子:

    var trueFactorial = factorial;
    factorial = function(){
      return 0;  
    }
    console.log(trueFactorial(5));      //120
    console.log(factorial(5));          //0

    变量trueFactorial获得了factorial的值,实际上是在另一个位置上保存了一个函数的指针。然后我们又把一个返回0的函数赋值给factorial变量。如果像原来的factorial()不使用arguments.callee,那么调用trueFactorial()就会返回0。但是,在解除了耦合之后,trueFactorial()依然能够正常的计算阶乘。而再次被赋值的factorial(),只能按照重新赋给的值进行计算。

    严格模式下,不能通过脚本访问arguments.callee,可以使用命名函数表达式来达成相同的结果,栗如:

    var factorial = (function f(num){
        if (num <= 1){
            return 1;
        } else {
            return num * f(num-1);
        }
    });    

    以上代码创建了一个名为f()的命名函数表达式,然后将它赋值给变量factorial。即便把函数赋值给了另一个变量,函数的名字f依然有效。这种方式在严格模式和非严格模式下都行得通。

    二、this

    this引用的是函数执行的环境对象,当在网页的全局作用域中调用函数时,this对象引用的就是window。

    window.color = "red";
    var o = { color: "blue"};
    function sayColor(){
      console.log(this.color);  
    }
    
    sayColor();      // "red"
    
    o.sayColor = sayColor;
    o.sayColor();    // "blue"

    函数sayColor()在全局作用域中定义,并且引用了this对象。在这个函数调用之前,this的值并不确定,所以this可能在代码执行过程中引用不同的对象。

    当在全局作用域调用sayColor(),那么this引用的是全局对象window,换句话说就是,对this.color求值会转换成对window.color求值,所以结果就是“red”。

    当把这个函数赋值给对象o并调用o.sayColor()时,this引用的是对象o,因此对this.color求值会转换成对o.color求值,所以结果就是“blue”。

    注:函数的名字仅仅是一个包含指针的变量,所以在不同的环境下执行,全局的sayColor()函数与o.sayColor()指向的仍然是同一个函数。

    参考资料

    《javascript高级程序设计(第3版)》第5章 引用类型

  • 相关阅读:
    [转载]代码里的命名规则:错误的和正确的对比
    解决WINDOWS 8 应用下载错误
    为什么这儿TemplateBinding不起作用了—研究WPF Binding(一)
    WINDOWS 8 使用与配置汇总(不断更新)
    Mac 安装和配置Maven
    CentOS 8 安装 Sublime Text 3
    CentOS8 安装 Chrome浏览器
    CentOS 8 防火墙相关命令
    CentOS8 安装Nginx
    java.lang.NoClassDefFoundError: org/apache/commons/beanutils/BeanUtils
  • 原文地址:https://www.cnblogs.com/winteronlyme/p/6702461.html
Copyright © 2020-2023  润新知