定义函数的几种方式:
一函数声明,显示定义函数
function fn(x){
return x+1;
}
二函数表达式
var fn = function(x){ return x+1}
三使用 Function() 构造函数定义
var f = Function(x){ return x+1}
四函数声明和函数表达式的区别:
解释器会率先读取函数声明,并使其在执行之前可以访问,而使用表达式则必须等到解析器执行到它所在的代码行,才会真正被解释执行,函数声明会正常执行
alert (sum (10 ,10));
function sum(a ,b){
return a+b;
}
下述代码会报错:
alert (typeof sum);
alert(sum(10 , 10));
var sum = function (a ,b){
return a+b;
}
//↑报错,原因在于函数位于一个初始化语句中,不是一个函数声明,不会被提前,而只会把var sum提前,用typeof操作符显示sum是undefined,所以报错
五函数的内部属性:函数内部,有两个特殊的对象,arguments和this
1.arguments是个类数组对象,包含着传入函数的所有参数,有一个叫callee的属性,属性值是一个指针,指向拥有这个arguments对象的函数本身
function foo (){
var a =arguments.callee;
return a.toString();
}
foo();
/*
返回结果:
"function sum(){
var a =arguments.callee;
return a.toString();
}" */
2. this:简单来说,this指的就是函数执行的环境对象,在哪个对象中执行,this就指哪个对象
3.3. ES5规范了函数的另一个属性:caller,这个函数属性指的是调用当前函数的函数
function inner(){
console.log(inner.caller);
}
function outer(){
inner();
}
outer();
//返回:function outer(){inner();}
4. length属性:表示函数希望接受的参数个数
function add(a ,b ,c){
return a+b+c;
}
add.length; //3
5. prototype属性是一个对象,是通过调用构造函数而创建的一个对象,包含可以由特定类型的所有实例共享的属性和方法
6. 函数的两个方法:call()和apply(),作用都是在特定的作用域中调用函数,实际上就是设置函数内部的this值
1). call():与apply()方法类似,区别在接收参数的方式不同,参数必须逐个列出来。
2). apply():接收两个参数,一个是函数运行的作用域,另一个是参数数组,可以是数组,也可以是arguments这个类数组对象
function sum(a , b){
return a+b;
}
function callSum(a , b){
return sum.apply(this , arguments);
}//第二个参数是一个类数组对象arguments
function callSum1(a , b){
return sum.apply(this, [a , b]);
} //第二个参数是一个数组
console.log(callSum(2 , 3)); //5
console.log(callSum1(3 ,5)); //8
3.) 传递参数并调用函数并非call()和apply()的用武之地,二者真正强大的地方是扩充函数运行的作用域
var color = 'red';
var obj = {
color :'blue'
}
function foo(){
console.log(this.color);
}
foo(); //'red'
foo.call(this);//'red'
foo.call(obj); //'blue'
//最后一次调用foo()函数的执行环境变了,其中的this指向了obj对象,所以是'blue'