#JavaScript学习#第七章:函数表达式

第七章:函数表达式

Tips: 内容为知识梳理javascript


目录

  1. 递归java

  2. 闭包数组

  3. 模仿块级做用域bash

  4. 私有变量闭包


定义函数有两种方式:函数

  1. 函数声明
function name(arg0,arg1,arg2){
	//代码
}
复制代码
  • 函数名.name能够访问函数名
  • 函数声明会被提高,前几章讲过,即执行其余代码前会先读取函数声明
  1. 函数表达式
    var name =function(arg0,arg1,arg2){
    	//代码
    };
    复制代码
  • 这样建立的函数是匿名函数即没有名字
  • 这个不会被提高
  • 能够将函数做为值返回

1. 递归

  • 和java跟c语言递归没啥区别。。。
  • 用arguments.callee可替代当前函数,这是一个指向正在执行函数的指针,用于确保不管怎样调用函数都不会出问题
  • 严格模式下不能使用arguments.callee
  • 严格模式下,用命名函数表达式来达到相同效果
var factorial = (function f(num){    
 if (num <= 1){        
   return 1;     
   } else {       
     return num * f(num-1);    
      }
  });
复制代码

上面函数名为f,赋值给了factorial。ui

2. 闭包

  • 闭包定义:指有权访问另外一个函数做用域中变量的函数
  • 其余的都是关于做用域链的内容,没什么好讲的(以前讲过)
  • 过分使用闭包会致使内存占用过多
  1. 闭包与变量
  • 闭包只能取得包含函数变量的最后一个值
    function ceee(){
    	var sum=new Array();
    	for(i=0;i<10;i++){
    		sum[i]=function(){
    			return i;
    		};
    	}
    	retuen sum;
    }
    复制代码
    此函数返回的数组都是10,由于闭包做用域链保存着包含函数的活动对象,它们引用的都是同一个i,当包含函数返回后,i等于10,因此数组都为10
  1. 关于this对象
  • 匿名函数的执行环境具备全局性,它的this一般指向window,好比:
    var name="abc";
    var ob=function(){
    	name:"fff",
    	getname:function(){
    		return function(){
    			return this.name;	
    		};
    	}
    };
    复制代码
    上面代码的this指向window,由于对于最里面的函数的做用域链,它在搜索this时,逐层往上搜索,由于本身的活动对象中存在this,而这个this是指向全局的,因此不会再往上搜索包含函数的this(不知道这样说你理解没有,反正我是理解了),修改方法是把this先保存在一个变量中,再在闭包调用这个变量,此时的this就是指向包含函数
  1. 内存泄露
  • 若闭包中包含一个HTML元素,那么该元素就没法被销毁
  • 把变量设置为null就能够解除引用,确保正常回收内存

3. 模仿块级做用域

javascript无块级做用域概念,即在块语句中定义的变量其实也是存在于包含他的外部函数的做用域链中,而不是像java和c语言同样在块语句结束后就被销毁。this

  • javascript用匿名函数来模仿块级做用域,语法以下:
    (function(){
    	//这里是块级做用域
    })();
    复制代码
    匿名函数即函数表达式后面能够跟圆括号表示当即调用,而函数声明即有名函数后面不能够跟圆括号
  • 这样,在块级做用域内就能够拥有本身的私有变量而不怕与外部变量名字冲突

4. 私有变量

  • 在函数内定义的变量都是私有变量外部不能直接访问
  • 在函数内有权访问函数的私有变量和私有函数的方法叫特权方法
  • 有两种模式去定义特权方法
  • 第一种是在构造模式中定义特权方法
    function mobj(){
    	var num=1;//私有变量
    	this.meth = function(){
    		return num;
    	};//特权方法
    }
    复制代码
    这样就能够在外部经过访问meth这个函数属性来访问私有变量
  • 不过使用构造函数模式的缺点是每一个实例都会建立一样一组新方法,前面讲过,用静态私有变量解决这个问题

1. 静态私有变量

用原型模式和匿名函数将私有变量变为全部实例共享,具体以下spa

(function (){
   	var name="abd";//私有变量
   	mbu = function(){};
   	mbu.prototype.publicmetho =function(){
   		return name;
   	};//在原型对象中设置属性
   })();
复制代码

上面代码首先是建立一个私有做用域,而后定义一个私有变量,再不使用var定义一个全局变量mbu,再对mbu的原型对象添加属性publicmethoprototype

  • 这样就能够经过访问全局变量来访问私有变量
  • 不过因为是在原型对象中定义,因此全部实例对这个变量进行操做都会反映到其余实例上

2. 模块模式

为单例建立私有变量和特权方法,语法以下:

var single = function(){
		var pria =20;//私有变量
		return {
			publicee :10;
			publicmetho: function(){
				return pria;
			}//返回一个以字面量建立的对象
		};
	}();
复制代码

上面代码返回了一个以字面量建立的对象,这个对象能够访问私有变量

  • 这种模式在须要对单例进行初始化,同时又须要维护其私有变量时是很是有用的,这时就能够用模块模式

3. 加强的模块模式

加强模块模式即在返回对象前加入对其加强的代码,这种模式适合那些单例必须是某种类型的实例,同时还必须添加某些属性或方法对其加强的状况。

相关文章
相关标签/搜索