JavaScript Function类型 小抄


Function类型是ECMAScript中最有意思的就是函数,函数实际上是对象,每个函数时function对象的实例,而且都与其他类型一样具有属性和方法。函数是对象,所以函数名实际上是一个指向函数对象的指针。

  • 声明

函数声明的语法

function sum(sum1, sum2){
return sum1+sum2;
}
用函数表达式定义:
var sum = function(sum1, sum2){
return sum1+sum2;
}
也可以用构造函数的方式来定义:

var sum = new Function("sum1", "sum2","return sum2 + sum1");//不推荐


由于函数名仅仅是指向函数的指针,因此函数名与包含对象指针的其他变量没有什么不同,它可以被复制,或者值为空 不会影响到函数对象本身。
ECMAScript中函数没有重载的概念,将函数名理解为指针。
所以重写函数只会覆盖原有的,不会重载,因为函数名本身就是一个变量,仅仅给这个指针变量赋了一个新值。


函数声明和函数表达式解析器在工作的时候会将函数声明提升,首先添加到执行环境中,而函数表达式只能在执行到的时候才会被真正的解释。

  • 作为值的函数

ECMAScript的函数名本身就是变量,所以函数也可以作为值来使用。不仅可以像传递参数一样将一个函数传递给另一个函数,而且可以将一个函数作为另一个函数的返回结果。
/* 创建比较某个的属性的方法 */
		function createComparFun(propetrtyName){
			return function(object1, object2){
				var value1 = object1[propetrtyName];
				var value2 = object2[propetrtyName];
				//第一个参数应该位于第二个参数之前,则返回一个负数
				if(value1 < value2){
					return -1;
				}else if(value1 > value2){
					return 1;
				}else{
					return 0;
				}
			}
		}

		var data = [{name:"zachary",age: 28},{name:"Nicholas",age: 29}];
		
		data.sort(createComparFun("name"));
		alert(data[0].name);

		data.sort(createComparFun("age"));
		alert(data[0].name);

  • 函数内部属性

函数内部有两个特殊的对象,arguments和this。 arguments是一个类数组对象,包含从函数传入的所有参数,虽然他的作用是保存参数,但是它还有个名叫callee的属性,该属性是一个指针,指向拥有这个argumants对象的函数。

function factorial(num){
			if(num <= 1){
				return 1;
			}else{
				return num * factorial(num - 1);
			}
		}

这样的调用在函数有名字并且函数名字不会变的情况下没有问题,但是这个函数的执行与函数名紧紧的耦合在一起,函数名只是个变量可能会改变,为了消除这种紧紧耦合的情况,可以使用下面的 arguments.callee.
function factorial(num){
			if(num <= 1){
				return 1;
			}else{
				return num * arguments.callee(num - 1);
			}
		}

这样无论引用函数使用的是什么名字都可以完成正常的递归调用。


this对象其行为与java和C#的this大致类似,换句话说this引用的是函数据以执行的环境对象,或者也可以说是this的值。

window.color = "red";
	var o = {color: "bule"};
	 function sayColor(){
	 	return this.color;
	 }
	 o.sayColor = sayColor;
	 //alert(sayColor()); //全局调用,this引用全局对象window
	//alert(o.sayColor());//引用对象是o 转化成为求o.color的值

函数名仅仅是个指针变量而已,即使在不同的环境执行,两个sayColor指向的是同一个函数。


函数对象的另一个属性,caller 这个属性保存调用当前函数的函数的引用,如果在全局作用域中调用当前函数,它的值是null.
function outer(){
		inner();
	}
	function inner(){
		alert(inner.caller);//argnments.callee.caller
	}
	outer(); //因为outer调用了inner所以inner.caller就指向了outer
	}

alert出来的outer函数的源代码


  • 函数的属性和方法

每个函数包含两个属性:length 和 prototype.

length表示函数希望接受的命名参数的个数;ECMAScript核心所定义的全部属性,prptptype最耐人寻味,对于ECMAScript的引用而言,prototype是保存他们所有实例方法的真正所在, 换句话正如toString()和valueOf()的方法正是保存在prototype下,只不过通过各自对象的实例访问罢了。

prototype属性是不能枚举的,所以用for in无法发现。
每个函数都有两个包含非继承而来的方法, apply()和call()。 两个函数都是用作在特定的作用域中调用函数,实际上等于设置函数体内this的值。
apply()函数接受两个参数,一个是作用域,另一个是参数数组,他和call的不同之处在于call()接受的第二个参数是单个的参数,必须将参数一一列举出来;这两个函数并没有什么本质上的差别,至于使用哪一个完全取决于使用哪一个比较方便。

function sum(num1, num2){
		return num1 + num2;
	}
	function callSum(number1, number2){ 
		return sum.apply(this, arguments);//apply接受两个参数,运行函数的作用域,参数数组
	}
	alert(callSum(100,99));  //199
	
	function callAgain(num1, num2){
		return sum.call(this, num1, num2);
	}
	alert(callAgain(800,200)); //运行函数的作用域 参数逐个列出来


apply()和call()真正的用武之地是能够扩充函数赖以运行的作用域。

window.color = "red";
	var o = {color : "bule"}; 
	function sayColor(){
		alert(this.color)
	}
	sayColor(); //red
	sayColor.call(this); //red
	sayColor.call(o); //bule
用call()或者apply()来扩充作用域的最大好处是对象不需要与方法有任何的耦合关系,之前的函数重载先需要将函数放到对象会中,再通过对象调用,在这里的重写的例子中就不需要这么麻烦了,直接用call或者apply来改变函数执行的作用域。

ECMAScript中还定义了bind的方法,this的值会被绑定到传给bind()函数的值

var TheSayColor = sayColor.bind(o); //o的值被绑定传给TheSayColor的this 
	TheSayColor();




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值