zoukankan      html  css  js  c++  java
  • 函数的内部属性-读书笔记

    函数内部,有两个特殊的对象: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章 引用类型

  • 相关阅读:
    django实现github第三方本地登录
    django扩展User模型(model),profile
    WSGI
    Linux查看配置文件中未被注释的有效配置行
    virsh 命令
    qemu-img命令
    python logging
    oslo.messaging
    集成kafka的身份认证(SASL/PLAIN)到kubernets环境中
    Helm基础知识
  • 原文地址:https://www.cnblogs.com/winteronlyme/p/6702461.html
Copyright © 2011-2022 走看看