zoukankan      html  css  js  c++  java
  • js之Function,call apply

    函数内部属性
    在函数内部,有两个特殊的对象:arguments 和this。arguments 是一个类数组对象,包
    含着传入函数中的所有参数,主要用途是保存函数参数。但这个对象还有一个名叫callee 的
    属性,该属性是一个指针,指向拥有这个arguments 对象的函数。
    function box(num) {
       if (num <= 1) {
          return 1;
       } else {
          return num * box(num-1); //一个简单的的递归
       }
    }
    对于阶乘函数一般要用到递归算法,所以函数内部一定会调用自身;如果函数名不改变
    是没有问题的,但一旦改变函数名,内部的自身调用需要逐一修改。为了解决这个问题,我
    们可以使用arguments.callee 来代替。
    function box(num) {
       if (num <= 1) {
          return 1;
       } else {
          return num * arguments.callee(num-1);//使用callee 来执行自身
       }
    }

    函数属性和方法
    ECMAScript 中的函数是对象,因此函数也有属性和方法。每个函数都包含两个属性:
    length 和prototype。其中,length 属性表示函数希望接收的命名参数的个数。
    function box(name, age) {
      alert(name + age);
    }
    alert(box.length); //2
    PS:对于prototype 属性,它是保存所有实例方法的真正所在,也就是原型。这个属性,
    我们将在面向对象一章详细介绍。而prototype 下有两个方法:apply()和call(),每个函数都
    包含这两个非继承而来的方法。这两个方法的用途都在特定的作用域中调用函数,实际上等
    于设置函数体内this 对象的值。
    function box(num1, num2) {
      return num1 + num2; //原函数
    }
    function sayBox(num1, num2) {
      return box.apply(this, [num1, num2]); //this 表示作用域,这里是window
    } //[]表示box 所需要的参数
    function sayBox2(num1, num2) {
      return box.apply(this, arguments); //arguments 对象表示box 所需要的参数
    }
    alert(sayBox(10,10)); //20
    alert(sayBox2(10,10)); //20

    call()方法于apply()方法相同,他们的区别仅仅在于接收参数的方式不同。对于call()方
    法而言,第一个参数是作用域,没有变化,变化只是其余的参数都是直接传递给函数的。
    function box(num1, num2) {
      return num1 + num2;
    }
    function callBox(num1, num2) {
      return box.call(this, num1, num2); //和apply 区别在于后面的传参
    }
    alert(callBox(10,10));
    事实上,传递参数并不是apply()和call()方法真正的用武之地;它们经常使用的地方是
    能够扩展函数赖以运行的作用域。
    var color = '红色的'; //或者window.color = '红色的';也行
    var box = {
      color : '蓝色的'
    };
    function sayColor() {
      alert(this.color);
    }
    sayColor(); //作用域在window
    sayColor.call(this); //作用域在window
    sayColor.call(window); //作用域在window
    sayColor.call(box); //作用域在box,对象冒充
    这个例子是之前作用域理解的例子修改而成,我们可以发现当我们使用call(box)方法的
    时候,sayColor()方法的运行环境已经变成了box 对象里了。
    使用call()或者apply()来扩充作用域的最大好处,就是对象不需要与方法发生任何耦合
    关系(耦合,就是互相关联的意思,扩展和维护会发生连锁反应)。也就是说,box 对象和
    sayColor()方法之间不会有多余的关联操作,比如box.sayColor = sayColor;

  • 相关阅读:
    241. Different Ways to Add Parentheses java solutions
    89. Gray Code java solutions
    367. Valid Perfect Square java solutions
    46. Permutations java solutions
    116. Populating Next Right Pointers in Each Node java solutions
    153. Find Minimum in Rotated Sorted Array java solutions
    判断两颗树是否相同
    求二叉树叶子节点的个数
    求二叉树第k层的结点个数
    将二叉排序树转换成排序的双向链表
  • 原文地址:https://www.cnblogs.com/andydao/p/3068864.html
Copyright © 2011-2022 走看看