1. Function类型:函数是对象,是Function类型的实例,有属性和方法。函数是对象,函数名是指向函数对象的指针。
2. 定义函数的方法:
① 函数声明语法定义:
function sum(num1, num2){
return num1+num2;
}
② 函数表达式定义:
var sum = function (num1, num2){ //sum变量中存的是指向函数对象的指针
return num1+num2;
};
③ 使用Function构造函数定义(最后一个参数是函数体。前面的任意数量的参数):不推荐
var sum = new Function("num1", "num2", "return num1+num2");
3. 因为js中函数的名字是存的指向函数对象的指针,所以js的函数没有重载。
4. 函数声明语法定义函数与函数表达式定义函数的区别:
解析器会先解析函数声明语法定义的函数,所以可以保证该函数可以在执行任何代码之前可以使用。(函数声明提升过程。js引擎在第一遍会声明函数并将他们放在源代码树的顶部)
alert(sum(10,10)); //20
function sum(num1, num2){
return num1 + num2;
}
而对于函数表达式定义函数,解析器直到执行到他所在的代码行,才会被真正解析执行。
alert(sum(10,10)); //出错
var sum = function (num1, num2){
return num1 + num2;
};
5. 函数内部属性:
① arguments对象:类数组对象,包含着传入函数中所有的参数。(该对象有一个callee属性,该属性是一个指针,指向拥有这个arguments对象的函数)
function factorial(num){
if (num <=1) {
return 1;
} else {
//这里本来是 return num*factorial(num-1);----但是这样这个函数的执行就和函数名紧紧耦合在一起
return num * arguments.callee(num-1);----解救办法,使用arguments的callee属性
}
}
}
② this对象:函数据以执行的环境对象(在全局作用域中调用函数时,this对象引用的就是window)
window.color = "red";
var o = { color: "blue" };
function sayColor(){
alert(this.color); //是在全局作用域中执行该函数,所以this是window
}
sayColor(); //"red"
o.sayColor = sayColor;
o.sayColor(); //"blue
③ caller属性:该属性中保存着调用当前函数的函数的引用。在全局作用域中调用当前函数,caller的值为null
function outer(){
inner();
}
function inner(){
alert(inner.caller); //这里松散耦合可以改为,arguments.callee.caller
}
outer(); //outer函数的代码
6. 函数属性和方法:
① 属性:length,prototype
length:表示函数希望接收的命名参数的个数
prototype(原型):保存函数对象的所有实例所在(比如toString(),valueOf()方法)
② 方法:apply(),call()----作用是在特定的作用域中调用函数,即设置被调用函数this的值。bind()---作用是创建一个函数对象。
apply():传入两个参数,一个是规定该运行函数的作用域,另一个是Array实例或者是argument对象
function sum(num1, num2){
return num1 + num2;
}
function callSum1(num1, num2){
return sum.apply(this, arguments); // 传入 arguments 对象
}
function callSum2(num1, num2){
return sum.apply(this, [num1, num2]); // 传入数组
}
alert(callSum1(10,10)); //20,未指定作用域时,this指的是全局作用域即window对象(严格模式下不会转型)
alert(callSum2(10,10));//20
call():第一个参数规定该运行函数的作用域,后面则是传入的参数(这里的参数要一一列出来)
function sum(num1, num2){
return num1 + num2;
}
function callSum(num1, num2){
return sum.call(this, num1, num2);
}。
alert(callSum(10,10)); //20
注意:这两个函数最大的作用是扩大作用域。好处是对象不需要和方法有任何的耦合关系。
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,这里o就是this,所以实际上是o.color
如果不使用call,就需要如下做法:
var o = { color: "blue" };
function sayColor(){
alert(this.color);
}
sayColor(); //"red"
o.sayColor = sayColor; //给o对象添加sayColor方法
o.sayColor(); //"blue" //再调用
bind():创建一个函数的实例,该bind函数的参数设置了this。
window.color = "red";
var o = {color: "blue"};
function sayColor(){
alert(this.color);
}
var objectSayColor = sayColor.bind(o); //这里创建了objectSayColor函数的实例,o即为this.color里面的this
objectSayColor(); //blue
7. 函数继承的toString()、toLocaleString()、valueOf()都返回函数的代码