JavaScript学习笔记(Function类型)

ECMAScript中,函数就是对象,每个函数都是function类型的实例,并且具有属性和方法。为了理解这一概念,可从函数的定义方式入手。

function sum(num1, num2){
	return num1 + num2;
}

var sum = function(num1, num2){
	return num1 + num2;
}

var sum = new Function("num1","num2","return num1 + num2");  //不推荐使用

以上的三种方式都可以定义函数,前两种方式是常用的定义方式,第三种不推荐使用。但从第三种定义方式可看出,函数名就是一个引用类型的指针变量,函数就是一个对象。

既然函数名只是函数对象的指针,所以,一个函数可以有多个同时指向它的指针,即多个函数名。

 

function sum(num1, num2){
	return num1 + num2;
}
alert(sum(10,10));  //20

var anotherSum = sum;
alert(anotherSum(10,10));  //20

sum = null;
alert(anotherSum(10,10));  //20

1. 没有重载

ECMAScript中不存在函数重载,只会覆盖

var addSomeNumber = function(num){
	return num + 100;
};

addSomeNumber = function(num){
	return num + 200;
};

var result = addSomeNumber(100);  //300

既然函数名是指针,在重新赋值后自然重新指向新的内存空间

 

2. 函数声明和函数表达式

在之前所说的函数的三种定义方式中,以function开头的定义方式会被解析器最先初始化,以var开头的定义方式则不会

alert(sum(10,10));
function sum(num1, num2){
	return num1 + num2;
}
// 可以正常运行
alert(sum(10,10));
var sum = function(num1, num2){
	return num1 + num2;
}
// 运行期间产生报错

3. 作为值的函数

因为函数名本身就是变量,所以也可以作为值来使用,可以作为参数传递给另一个函数,也可以作为另一个函数的返回结果。

function callSomeFunction(someFunction, someArgument){
	return someFunction(someArgument);
}

function add10(num){
	return num + 10;
}

var result1 = callSomeFunction(add10,10);
alert(result1);  //20

function getGreeting(name){
	return "hello, " + name;
}

var result2 = callSomeFunction(getGreeting, "word");
alert(result2); //"hello, word"

以下代码根据函数可作为另一个函数的返回结果的特性,灵活地实现了对数组的自定义排序

function createComparisonFunction(propertyName){
	return function(object1, object2){
		var value1 = object1[propertyName];
		var value2 = object2[propertyName];
		
		if(value1 < value2){
			return -1;
		}else if(value1 > value2){
			return 1;
		}else{
			return 0;
		}
	}
}

var data = [{name:"zhangsan",age:28}, {name:"lisi", age:29}];

data.sort(createComparisonFunction("name"));
alert(data[0].name);  //lisi

data.sort(createComparisonFunction("age"));
alert(data[0].name);  //zhangsan

4. 内部属性arguments

arguments是函数对象中的一个属性,是一个类数组对象,包含着传入函数中的所有参数。

arguments有一个callee方法,可以调用拥有其arguments的函数,常用于做递归

function factorial(num){
	if(num <= 1){
		return 1;
	}else {
		return num * arguments.callee(num - 1);
	}
	//实现了求num的阶乘
}

alert(factorial(5));  //120

ECMAScript 5 规范了另一个函数对象的属性:caller,除了Opera早期版本,其他的浏览器都支持。这个属性中保存着调用当前函数的函数的引用,如果在全局作用域中调用当前函数,它的值为null

function outer(){
	inner();
}

function inner(){
	alert(arguments.callee.caller);
}

outer(); //outer函数的代码
inner(); //null

 

5. 内部属性this

this也是函数对象中的一个属性,引用的是函数的执行环境对象,设置类的属性和方法时需要通过this关来引用

window.color = "red";

function Circle(color){
	this.color = color;
}

function sayColor(){
	alert(this.color);
}

sayColor();  //"red"

var o = new Circle("blue");
o.sayColor = sayColor;
o.sayColor();  //"blue";

6. 函数属性prototype和length

函数的prototype属性是指向其原型的引用,JavaScript通过prototype属性实现了许多面向对象的功能

length是函数希望接收的参数个数

function sayName(name){
	alert(name);
}

function sum(num1,num2){
	return num1 + num2;
}
function sayHi(){
	alert("hi");
}

alert(sayName.length);  //1
alert(sum.length);  //2
alert(sayHi.length);  //0

7. 函数方法call、apply和bind

call()方法和apply()方法的作用相同,区别在于接收的参数不同

function sum(num1, num2){
	return num1 + num2;
}

function callSum(num1, num2){
	return sum.call(this,num1,num2);
}

function applySum(num1, num2){
	return sum.apply(this,[num1,num2]);
}
alert(callSum(10,10));  //20
alert(applySum(20,20));  //40

更重要的是,call()方法和apply()方法可以扩充函数的作用域,与prototype组合使用可以实现继承

window.color = "red";
var o = {color: "blue"};

function sayColor(){
	alert(this.color);
}

sayColor();

sayColor.call(this);  //red
sayColor.call(window); //red
sayColor.call(o);  //blue

ECMAScript 5 定义了一个方法:bind(),这个方法会创建一个函数实例,其this值会被绑定到穿个bind()函数的值

支持的浏览器:IE9+、Firefox 4+、Safari 5.1+、Opera 12+和Chrome

window.color = "red";
var o = {color: "blue"};

function sayColor(){
	alert(this.color);
}

var objectSayColor = sayColor.bind(o);
objectSayColor();  //blue

 

 

参考文献:    JavaScript高级程序设计(第3版)

转载于:https://my.oschina.net/u/3260543/blog/1533758

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值