JavaScript函数的特性与应用实践深入详解(5)

/**
 * 求阶乘(带尾递归的函数)
 *
 * JavaScript 当前没有对尾递归进行优化,所以如果递归过深会导致堆栈溢出
 * @param i
 * @param a
 * @returns {*} 返回自身调用的结果
 */
var factorial = function factorial(i, a) {
  a = a || 1;
  if (i < 2) {
    return a;
  }
  return factorial(i - 1, a * i);
};
console.log(factorial(4));

9 作用域

作用域控制着变量和参数的可见性以及生命周期,它减少了名称冲突,而且提供自动内存管理机制。

var foo = function () {
  var a = 3, b = 5;
  var bar = function () {
    var b = 7, c = 11;
    console.log("a:" + a + ";b:" + b + ";c:" + c);//a:3;b:7;c:11
    a += b + c;
    console.log("a:" + a + ";b:" + b + ";c:" + c);//a:21;b:7;c:11
  };
  console.log("a:" + a + ";b:" + b);//a:3;b:5
  bar();
  console.log("a:" + a + ";b:" + b);//a:21;b:5
};
foo();

JavaScript 支持函数作用域,但要注意一点,就是在一个函数内部的任何位置定义的变量,都这个函数的任何地方都是可见的!

**注意:**JavaScript 不支持块级作用域。所以最好的做法是在函数体的顶部,声明函数中可能会用到的所有变量。

10 闭包

作用域的好处是:内部函数可以访问定义它们外部函数的参数和变量(除了 this 和 arguments)。

注意:内部函数拥有比它的外部函数更长的生命周期。

var myObject = (function () {
  var value = 0;//只对 increment 与 getValue 可见
  return {
    increment: function (inc) {
      value += typeof inc === 'number' ? inc : 1;
    },
    getValue: function () {
      return value;
    }
  }
}());

通过一个函数的形式来初始化 myObject 对象,它会返回一个对象字面量。函数定义了一个 value 变量,这个变量对 increment 和 getValue 方法总是可见的,但它的函数作用域却使得这个变量对其他的代码来说是不可见的!

/**
 * quo 构造函数
 * @param status 私有属性
 * @returns {{get_status: Function}}
 */
var quo = function (status) {
  return {
    get_status: function () {//方法
      return status;
    }
  };
};
var myQuo = quo("amazed");
console.log(myQuo.get_status());//amazed

当我们调用 quo 时,它会返回一个包含 get_status 方法的新对象,它的引用保存在 myQuo 中。所以即使 quo 函数已经返回了,但 get_status 方法仍然享有访问 quo 对象的 status 属性的特权。get_status 方法访问的可是 status 属性本身,这就是闭包哦O(∩_∩)O~

再看一个例子:

/**
 * 设置一个 DOM 节点为黄色,然后渐变为白色
 * @param node
 */
var fade = function (node) {
  var level = 1;
  var step = function () {
    var hex = level.toString(16);//转换为 16 位字符
    node.style.backgroundColor = '#FFFF' + hex + hex;
    if (level < 15) {
      level += 1;
      setTimeout(step, 100);
    }
  };
  setTimeout(step, 100);
};
fade(document.body);


      

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/447.html