Function类型知识点索引
- 函数没有重载
- 函数声明与函数表达式
- 作为值的函数
- 函数内部属性
1、arguments
2、arguments.callee
3、apply()、call()
4、this - 函数属性和方法
1、length
2、prototype
使用不带园括号的函数名是访问函数指针,而非调用函数
函数表达式
var sum=function(num1,num2){
return num1+num2;
}
函数声明
function sum(num1,num2){
return num1+num2;
}
一、没有重载
如果同时声明两个同名函数,结果只会执行后面一个函数,也就是后面的函数覆盖了前面的函数
function addSomeNumber(num){
return num+100;
}
function addSomeNumber(num){//结果只执行此函数
return num+200;
}
二、函数声明与函数表达式
解析器在想执行环境中加载数据时,对函数声明和函数表达式并非一视同仁。解析器会率先读取函数声明,并使其在执行任何代码之前可用。至于函数表达式,则必须等到解析器执行到它所在代码行才会真正被解释执行。
这里就引出了一个概念函数声明提升
:对代码求值的时,JavaScript引擎在第一遍声明函数并将它们放到源代码树顶部。所以,即使声明函数的代码在调用它的代码之后,JavaScript引擎也能把函数声明提升到顶部
//函数调用在函数声明前面,能正确执行
alert(sun(10,10));
function addSomeNumber(num){
return num+100;
}
```
但如果向下面一样把**函数声明**改成**函数表达式**,执行就会出错误
```js
alert(sun(10,10));
var addSomeNumber=function(num){
return num+100;
}
三、做为值的函数
函数名本身就是一个变量,所以函数也可以做为值来使用。也就是说,不仅可以向传递参数一样把一个函数传递给另外一个函数,而且可以将一个函数做为另一个函数的结果返回
//共用函数
function callSomeFunction(someFunction,someArgument){
return someFunction(someArgument);
}
//做为参数传递的函数
function add10(num){
return num+10;
}
//实例化1
var result1=callSomeFunction(add10,10);
alert(result1);//弹出20
//实例化2
function getGreeting(name){
return 'Hellow'+name;
}
var result2=callSomeFunction(getGreeting,'Nicholas');
alert(result1);//弹出'Hellow Nicholas'
可以从一个函数中返回另一个函数,这是一个非常有用的技术叫闭包。假设:有一个对象数组,我们需要根据摸个对象属性对数组进行排序(主要用到sort
方法)
var data = [{name: "Zachary", age: 28}, {name: "Nicholas", age: 29}];
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;
}
};
}
data.sort(createComparisonFunction("name"));
alert(data[0].name); //Nicholas
data.sort(createComparisonFunction("age"));
alert(data[0].name); //Zachary
四、函数内部属性
函数内部有两个特殊对象:arguments和this
- arguments主要用来保存参数是一个伪数组
- arguments还有一个名叫callee的属性,该属性有一个指针,指向拥有这个arguments对象的函数,最经典的列子用于阶乘
function factorial(num){
if(num<=1){
return 1;
}else{
return num*arguments.callee(num-1);
}
}
五、函数属性和方法
每个函数都包含两个属性
- length
- 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
至于prototype将在后面向对象中详细介绍。每个函数还包括非继承而来的方法:apply(this,argument)
,call(this,param1,param2)
两个方法的效果都一样,只是在传参的方式上不一样apply(this,argument)
,第二个参数传入一个数组,用于不知参数个数的情况下。call(this,param1,param2)
,则是一次将参数传入,用于已知参数个数的情况下。
事实上传递参数并非这两个方法的真正用武之地,他们真正强大的地方是能够扩充函数赖以运行的作用域
window.color = "red";
var o = { color: "blue" };
function sayColor(){
alert(this.color);
}
sayColor(); //red
sayColor.call(this); //red
sayColor.call(window); //red
sayColor.call(o); //blue
ECMAscript5还定义了一个方法`bind()
这个方法还创建了一个函数的实例,其this会被绑定到传给bind()
函数的值
window.color = "red";
var o = { color: "blue" };
function sayColor(){
alert(this.color);
}
var objectSayColor = sayColor.bind(o);
objectSayColor(); //blue