《Javascript高级程序设计》第七章.函数表达式学习总结

定义函数的两种方式

  1. 函数声明
function Myfunc(){
//your code
}

函数声明提升:在执行代码时会先读取函数声明,可以把函数调用写在函数声明前面,不会报错。

//先调用函数声明,故不会报错
Myfunc();
function Myfunc(){
//your code
}
  1. 函数表达式
var MyFunc = function(){
//your code
}

这种方法创建的函数是匿名函数,使用时必须先创建函数,再调用,即调用函数必须放在创建函数后面。

Tips:在把函数当成值来使用时,使用匿名函数。

递归

一个函数通过名字调用他自身。
arguments.callee()指向正在执行函数的指针,或者使用命名函数。

//使用命名函数解决问题
	var factorial2 = (function f(num){
		if(num <= 1){
			return 1;
		} else {
			return num * f(num-1);
		}
	});
	//以上定义了一个f的命名函数表达式
	var anthorfactorial=factorial2;
	factorial2 = null;
	console.log(anthorfactorial(6));

命名函数:函数如果有名字,就是命名函数
匿名函数:如果函数没有名字就是匿名函数
自调用函数:自己调用自己的函数

(function(){console.log("这是函数的自调用");}) ();

闭包

闭包是指有权访问另一函数作用域中变量的函数,即在另一函数内部定义的函数。
闭包的缺点:占用内存,容易造成内存泄漏。

作用域链

一个函数具有一个作用域,在他内部的函数具有自己的作用域,同时也可以访问外部函数的作用域,就构成了作用域链。
作用域链产生了一个副作用:闭包只能取得包含函数中任意变量的最后一个值。

闭包与变量

//获取的是最后一个值
		function createFunction(){
			var result = new Array();
			for(var i=0;i<10;i++){
				result[i]=function(){
					return i;
				};
			}
			return result;
		}
		var funcs = createFunction();
            
        //every function outputs 10
        for (var i=0; i < funcs.length; i++){
            document.write(funcs[i]() + "<br />"); //10,10,10...
        }
//加入了一个新的匿名变量,使输出的值是对应的编号
		function createFunction1(){
			var result = new Array();
			for(var i=0;i<10;i++){
				result[i]=function(num){
					return function(){
						return num;
					};
				}(i); //函数自调用
			}
			return result;
		}
		var funcs1 = createFunction1();
            
        //every function outputs it's num
        for (var i=0; i < funcs1.length; i++){
            document.write(funcs1[i]() + "<br />");
        }

关于this对象

this是指包含它的函数作为方法被调用时所属的对象,this对象是在运行时基于函数的执行环境绑定。

匿名函数具有全局性,所以匿名函数的this对象通常是window

改变this的函数:

  • call(对象,参数1,参数2…)
  • apply(对象,[参数1,参数2…])
  • bind(对象,参数1,参数2…)() //返回的是一个函数所以要加括号调用

内存泄漏

在闭包的作用域链里保存着一个html元素的话,会导致该元素无法被销毁。

模仿块级作用域

avascript中没有块级作用域的概念,在函数中定义的变量在整个函数中都可以随处访问。

(function(){ 
	//模仿块级作用域 
})();

私有变量

任何在函数中定义的变量都是私有变量,因为不能在函数外部访问这个变量。

Tips:构造函数的缺点:针对每一个实例都会创建同样一组新方法。
原型的缺点:所有变量和函数都是共享的,实例没有私有的对象。

function Myobject(){
			//私有变量和私有函数
			var privateVariable = 10;
			function privateFunction(){
				return false;
			}
			//特权方法
			//用一个闭包,来获取外部函数的变量和方法
			this.publicMethod = function(){
				console.log(++privateVariable);
				return privateFunction();
			};
		}
		var obj=new Myobject();
		//使用特权方法来调用私有函数和私有变量
		console.log(obj.publicMethod());
		//不能在外部调用私有函数

静态私有变量

使用原型方法,并把私有变量放在一个块级里,所有实例都没有私有变量,变量是实例共享的。

(function(){
			var name = "";
			Person = function(value){
				name=value;
			};
			Person.prototype.getName = function(){
				return name;
			};
			Person.prototype.setName = function(value){
				name = value;
			};
		})();
		var per1 = new Person("Nicholas");
		console.log("per1: "+per1.getName());
		per1.setName("Amy");
		console.log("per1: "+per1.getName());
		//每个实例没有自己的变量,所有变量都是可共享的。
		var per2 = new Person("Greg");
		console.log("per2: "+per2.getName());
		console.log("per1: "+per1.getName());

模块模式

是为单例创建私有变量和特权方法的。
单例:是以对象字面量的方式来创建单例对象的。

function BaseComponents(){

		}
		function otherComponents(){

		}
		var application = function(){
			//私有变量和函数
			var components = new Array();
			components.push(new BaseComponents());
			//公共
			return {
				getComponent : function(){
					return components.length;
				},
				registerComponents : function(component){
					if(typeof component == "object"){
						components.push(component);
					}
				}
			};
		}();

		application.registerComponents(new otherComponents());
		console.log(application.getComponent());	//2

增强的模块模式

在返回对象之前加入对其增强的代码,这种增强模式适合那些单例必须是某种类型的实例,以及必须添加某些属性和方法对其加以增强。

function BaseComponents(){

		}
		function otherComponents(){

		}
		var application = function(){
			//私有变量和函数
			var components = new Array();
			//初始化
			components.push(new BaseComponents());
			//创建一个application的局部副本
			var app = new BaseComponents();

			//公共接口
			app.getComponent = function(){
				return components.length;
			};
			app.registerComponents = function(component){
				if(typeof component == "object"){
					components.push(component);
				}
			};
			//返回这个副本
			return app;
		}();

		application.registerComponents(new otherComponents());
		application.registerComponents(new BaseComponents());
		console.log(application.getComponent());	//3
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值