JS-第七章

1.下面来个递归:

function factorial(num){

  if(num<= 1){

  return 1;

}else{

  return num*factorial(num-1);

}

这是个经典的递归阶乘函数,虽然这个函数表面上看起来没什么问题,但是下面代码可能导致它出错

var anotherFatorial =factorial;//指向函数的引用

factorial =null;

alert(anotherFatorial(4));//出错!!!调用它会在else里边用到factorial如果改成arguments.callee就可以解决这个问题啦。

2.闭包的深刻理解原理(涉及到第四章的作用域链条,176-180页详细介绍为何内部的匿名函数可以访问调用它的那个函数作用域的内容):

简述:当a函数返回一个匿名函数b的时候,在b被a返回后,它的作用域链被初始化为包含a函数的活动对象(在每个函数被调用时,其活动对象都会取得this和arguments这两个特殊变量)和全局变量对象(可以看179页的图)。这样,匿名函数就可以访问在a中定义的所有变量。更为重要的是,a函数在执行完毕后,其活动对象不会被销毁,因为匿名函数b的作用域链仍然在引用这个活动对象。换句话说,就是当a函数返回后,其执行环境的作用域链会被销毁,但它的活动对象仍然会留在内存中;直到匿名函数被销毁后,a函数的活动对象才会被销毁。

(**由于闭包会携带包含它的函数的作用域,因此会比其他函数占用更多的内存。过度使用闭包可能会导致内存占用过多,建议只有在绝对必要时在考虑使用闭包)

181页:例子来深刻理解闭包

3.解释下如下函数,它是一个函数表达式,它是个匿名函数,在多人开发中可以定义它来模仿块作用域(通常称为私有作用域),它的作用域被用在全局作用域之外,从而限制向全局作用域中添加过多的变量和函数,做多人开发中为了避免过多的全局变量和函数的命名冲突。而通过创建私有作用域,每个开发人员既可以有自己的变量,又不比担心搞乱全局作用域。

(function(){

//这里是块级作用域

})()//这个圆括号可以让匿名函数立即执行

例子1:

(function(){

   var now =new Date();

 if(now.getMonth() == 0&&now.getDate()==1){

   alert("Happy new year!");

}

})()//此段代码放入全局作用域中,其中的变量now是匿名函数中的局部变量,我们不必在全局作用域去创建它

例子2:

function one(count){

 (fucntion(){

  for(var i=0;i<count;i++){

    alert(i);

  } 

})();

 alert(i);//会导致错误   因为在匿名函数中定义的任何变量都会在执行结束的时候销毁,而在私有作用域中可以访问count,是因为匿名函数是一个闭包,它能够访问包含作用域中的            //所有变量

}

4.js中没有私有成员的概念,所有的对象属性都是公有的,倒是有私有变量的概念。因此可以利用闭包来定义特权方法的方式隐藏那些不应该直接被修改的数据。187页

5.上述缺点是必须使用构造函数模式达到了这个目的,使之缺点就是针对每个实例都会创建同样一组新方法,而使用静态私有变量来实现特权方法就可以避免这个问题。

(详细讲解静态私有变量 188页开始)

6.模块模式:道格拉斯所说的模块模式(module pattern)则是为单例创建私有变量和特权方法。所谓单例(singleton)指的就是只有一个实例的对象,按照惯例,js是以对象字面量的方式来创建单例对象的。(189页)

原文地址:https://www.cnblogs.com/Billzhizhi/p/6005378.html