一.函数声明有3种方法:
1.function命令 函数的声明
function getName(name){
console.log(name);
return name;
}
2.函数表达式
var getName = function(name){ console.log(name); return name; } var getName = function foo(name){ console.log(foo); console.log(name); return name; } 返回结果: function foo(name){ console.log(foo); console.log(name); return name; } 张丹
3.Function 构造函数
你可以传递任意数量的参数给Function构造函数,只有最后一个参数会被当作函数体,如果只有一个参数,该参数就是函数体
var add = new Function('x','y','return x+y'); add(5,6); 返回结果:11 var jian = new Function('a','b','c','return a+b-c'); jian(12,9,8); 返回结果:13
二.函数的重复声明
如果同一个函数被多次声明,后面的声明就会覆盖前面的声明
js引擎遇到return 语句,就直接返回return 后面的那个表达式的值,后面即使还有语句,也不会得到执行。也就是说,return 语句所带的那个表达式,就是函数的返回值
三.递归
函数可以调用自身,这就是递归。
function fib(num) { if (num === 0) return 0; if (num === 1) return 1; return fib(num - 2) + fib(num - 1); } fib(8); 返回结果:21
函数与其他数据类型一样,凡是可以使用值得地方,就可以使用函数
四.不能在条件语句中声明函数
五。函数的属性和方法
1.name属性返回紧跟在function 关键字之后的那个函数名
2.length属性
函数的length属性返回函数预期传入的参数个数,而不管调用时传入的参数的个数
function f(a,b,c){ console.log(a); } f(20); 返回结果:20 f.length 返回结果:3
3.toString();
函数的toString方法返回函数的源码,包括注释
4.函数内部的变量提升
与全局作用域一样,函数作用域内部也会产生‘变量提升’现象。var 命令声明的变量,不管在什么位置,变量声明都会被提升到函数体的头部
5.函数本身的作用域
函数本身的作用域,就是其声明时所在的作用域,与其运行时所在的作用域无关
函数执行时所在的作用域,是定义时的作用域,而不是调用时的作用域。实例如下:
var a = 1; var x= function(){ console.log(a); } function f(){ var a = 3; x(); } f(); 返回结果:1 function foo() { var x = 1; function bar() { console.log(x); } return bar; } bar(); 返回结果:Uncaught ReferenceError: bar is not defined
6.参数
函数无法省略靠前的参数,而保留靠后的参数。如果一定要省略靠前的参数,只有显式传入undefined
如果函数参数是复合类型的值(数组、对象、其他函数),传递方式是传址传递(pass by reference)。也就是说,传入函数的原始值的地址,因此在函数内部修改参数,将会影响到原始值。
var o={p:1}; function f(o){ o.p=8; console.log(o); } f(o); o 返回结果:Object {p: 8}
7.同名参数
如果有同名参数,则取最后出现的那个值, 即使后面的没有值或被省略,也是以其为准
8.arguments 对象
arguments对象包含了函数运行时的所有参数,arguments[0]就是第一个参数shi,arguments[1]就是第二个参数,以此类推。这个对象只有在函数体内部,才可以使用。
正常模式下,arguments对象可以在运行时修改。
可以通过
apply
方法,把
arguments
作为参数传进去,这样就可以让
arguments
使用数组方法了
function foo(a,b,c){ var ss=Array.prototype.concat.apply([1,2,3],arguments); console.log(ss); } foo(8,9,6); 返回结果:[1, 2, 3, 8, 9, 6]
callee
arguments
对象带有一个
callee
属性,返回它所对应的原函数。
function foo(a,b,c){ console.log(arguments.callee); } foo() 输出结果: foo(a,b,c){ console.log(arguments.callee); }
闭包的另一个用处,是封装对象的私有属性和私有方法
function Person(name) { var _age; function setAge(n) { _age = n; } function getAge() { return _age; } return { name: name, getAge: getAge, setAge: setAge };} var p1 = Person('张三');p1.setAge(25);p1.getAge() // 25