在js里,每个函数都是function类的实例。

一下三种效果几乎相同的方法,都可以用sum来引用函数。

function sum(var a,var b){return a+b};//函数声明法
var sum=function(var a,var b){return a+b};//函数表达式法
var sum=new Function("a","b","return a+b"};//构造函数法

但是第三种方法会导致解析两次代码,第一次解析常规代码,第二次解析构造函数里的字符串,从而影响性能。

因为函数名只是引用(存储地址的变量),所以一个函数可以有多个名字。而且这些引用互相独立。

比如:

var newsum=sum;
alert(newsum(10,10));

因此,函数没有重载,同名的函数会直接覆盖。

函数声明与函数表达式

在解析代码时,解析器已经通过一个名为函数声明提升的过程,率先读取并将函数声明添加到执行环境中,因此,即使调用函数的语句写在声明函数的语句之前,也可以正常执行。

alert(sum(10,10));//20
function sum(a,b){return a+b};
但是,假如函数不是声明而是表达式,就不能这样做。
alert(sum(10,10));//20
var sum = function (a,b){return a+b};
函数作为另一个函数的返回值
function createCompareFuntion(var proname){
    return function(obj1,obj2){
        var v1=obj1[proname];
        var v2=obj2[proname];
        if(v1<v2){
             return -1;
        }
        else if(v1>v2){
             return 1;
        }
        else{
            return 0;}
     }
}
var data=[{name:"aaa",age:12},{name:"bbb",age:15}];
data.sort(createCompareFuntion("age");
alert(data[0]).name);//aaa


为什么data.sort(compare)不需要传入参数呢,我的理解是由于参数不需要自己指定,它进行了封装,把compare函数传进sort函数,sort函数里面还有自带的参数,所以会自己调用compare函数

函数内部属性

arguments

一个类数组对象,除了保存函数所有的参数以外,还有一些重要的属性。

callee属性

该属性是一个指针,指向拥有这个arguments对象的函数。

常用于递归算法。函数自己调用自己时,如果函数没有名字,就可以用arguments.callee(参数)来调用自己。

caller属性

是函数自带的属性。指向调用当前函数的函数。

function outer(){
inner()
}
function inner(){
alert(arguments.callee.caller);//返回outer的源代码,在严格模式下报错
}

length属性

参数个数

prototype属性

函数内部方法

改变函数内部this值的三种函数自带的方法(apply,call,bind)

在全局环境里写的函数,里面的this指向的是window。

为了改变函数内部的this值,调用函数自带的apply方法

例如

obj1={
num1:1,
num2:2
};
window.num1=3;//this指向window
window.num2=4;
function sum(a,b){
    return this.num1+this.num2+a+b;
}
function callSum1(a,b,c){
    return sum.apply(obj1,arguments);//改变sum内部的this值为obj1,同时传入数组执行sum函数
}
callSum1(8,9,1);//20(多余的参数会被忽略)

call和apply的区别是传入的参数必须逐个列举出来,即sum.call(obj1,a,b,c);

这样做最大的好处是对象不需要与方法有任何耦合关系,方法不需要被放在对象里也可以获得对象的环境。

bind() 

创建一个函数的实例,其this值会被绑定到参数上

window.color="red";
var o={color:"blue"};
function sayColor(){
    alert(this.color);
}
var newfun=sayColor.bind(o)
newfun();//blue

三个会返回函数代码的方法:toLocaleString(),toString(),valueOf()