JavaScript中的函数实际上是对象,每个函数都是Function类型的实例,而且都与其他引用类型一样具有属性和方法。由于函数是对象,因此函数名实际上只是指向函数对象的指针,保存函数在堆内存中的地址值。
1、定义函数的三种方式:
1.1、函数声明方式
1 function sum(num1, num2){ 2 return num1 + num2; 3 }
1.2、函数表达式
1 var sum = function(num1, num2){ 2 return num1 + num2; 3 }
1.3、使用Function构造函数,依次传入命名参数、函数体。这种方式不推荐使用,但这种方式便于我们理解函数名是指针,函数是对象。
1 var sum = new Function("sum1", "sum2", "return sum1 + sum2"); //不推荐
2、函数是对象,函数名是指针
下面这两行代码如果你弄不懂有什么区别的话,就说明你对函数是对象,函数名是指针还不理解。第一行代码是把sum指向的function对象的地址值赋给anothersum,只是个赋值操作,sum函数并没有执行。关于这里,anothersum和sum对象是保存在栈内存中的,而function对象保存在堆内存中,anothersum和sum存的是function对象在堆内存中的地址值。这里第二行代码是执行sum函数,并把返回值赋值给another。由第二种函数的定义方式比较好区分它们。
1 var anothersum = sum; 2 var anothersum = sum();
3、为什么没有重载?
将上面的两个方法转换成下面两个方法的写法,就能很好地理解为什么没有重载了,因为函数名只是个指向函数对象的指针,当定义第二个同名函数的时候,add指向了新的函数对象。
1 function add(num){ 2 return num + 100; 3 } 4 function add(num){ 5 return num + 200; 6 } 7 8 var add = function(num){ 9 return num + 100; 10 } 11 12 add = function(num){ 13 return num + 200; 14 }; 15 16 alert(add(50)); //250
4、函数声明与函数表达式的区别
这两种定义函数的方式的区别在于解析器在向执行环境中加载数据的时候,解析器会率先读取函数声明,并使其在执行任何代码前有效,而函数表达式只有在解析器执行到它所在的代码行时才会执行。除了这个区别外这两种定义函数的方式是等价的。看下面这个例子
1 alert(sum(10, 20)); //输出30 2 function sum(num1, num2){ 3 return num1 + num2; 4 } 5 6 alert(sum(10, 20)); //报错,sum is not a function,很明显函数表达式还没有被解析器读取到 7 var sum = function(num1, num2){ 8 return num1 + num2; 9 }
5、作为值、参数的函数,另外深入了解sort方法的比较器函数规则,按照数组元素的先后顺序进行比较,如果返回的是正数,则证明object1比object2大,负数相反,0相等,跟Java中Comparator接口的compare方法效果一样。
1 function compare(propertyName){ 2 return function(object1, object2){ //函数作为值返回 3 value1 = object1[propertyName]; 4 value2 = object2[propertyName]; 5 console.log(value1 + " " + value2); 6 if(value1 > value2){ 7 return 1; 8 }else if(value1 < value2){ 9 return -1; 10 }else{ 11 return 0; 12 } 13 } 14 } 15 16 var data = [{name:"zhangsan", age:23},{name:"lisi", age:25}]; 17 var newData = data.sort(compare("name")); //把函数当做参数 18 console.log(newData[0].name); //lisi
这里把compare函数作为参数传递给了数组的sort函数,在compare函数的内部把函数作为值返回,compare函数可以根据你传入的对象属性进行排序。
因为函数也是对象,所以它也有属性和方法,关于函数的属性和方法这里不做介绍,有个比较重要的属性prototype,以后再学习。