函数与Function的关系:每个函数都是Funtion类型的实例,而且都与其他引用类型一样具有属性和方法。由于函数是对象,因此函数名实际上也是一个指向函数对象的指针,不会与某个函数绑定。
1.函数声明
以关键字function开始,后面跟随函数名称标识符、一对圆括号(包含有0个或多个用逗号隔开的函数参数名称)和一对花括号(包含0条或多条JS语句,构成函数体)。解析器在向执行环境中加载数据时,在代码执行前就被解析器加载到作用域中,这个特性可以让我们在函数定义之前就调用该函数。
console.log(sum(10,10)); //20
function sum (num1,num2){
return num1+num2
}
2.函数表达式
与函数声明一样,函数表达式也用到了关键字function。声明一个变量,采用变量赋值的方式,将一个匿名函数赋给这个变量。用这种方式定义函数时,没有必要声明函数名,因为通过声明的变量即可引用函数。值得注意的一点,根据变量赋值语句的语法规则,需要在赋值结束后在末尾加上分号(;),因此在用函数表达式定义函数时候,要记得在末尾加上分号。注意,与函数声明不同的是,函数表达式必须等到解析器解析到代码段之后才能进行调用,否则会报错。
console.log(sum(10,10)); //Uncaught TypeError: sum is not a function
var sum= function (num1,num2) {
return num1+num2
};
3.Function()构造函数
Function()构造函数可以传入任意数量的字符串实参,最后一个实参所表示的文本是函数体,可以包含任意数量的JS 语句。如果构造的函数不包含任何参数,则只需要传入一个函数体即可,与前两者方式不同的是,Function()构造函数允许JavaScript在运行时动态地创建并翻译函数。每次调用Function()构造函数都会解析函数体,并创建新的函数对象。因而,在循环或多次调用的函数中执行这个构造函数,执行效率会受影响。
var sum = new Function("x","y","return x+y");
如果声明了两个同名函数,则后面的函数会覆盖前面的函数。
在函数的内部,有两个特殊的对象:arguments和this
1.arguments是一个类数组对象,包含着传入函数的所有参数。它有一个callee属性,该属性是一个指针,指向拥有这个arguments对象的函数,常用于阶乘函数。
function factorial (num) {
if(num<=1){
return 1;
}else{
return num * arguments.callee(num-1);
}
}
2.this引用的是函数执行的环境对象。当在网页的全局作用域中调用函数时,this对象引用的就是window
window.color="red";
var o={color:"blue"};
function sayColor(){
alert(this.color);
}
sayColor(); //red
o.sayColor=sayColor;
o.sayColor(); //blue
ECMAScript5也规范化了另一个函数对象的属性:caller。这个属性保存着调用当前函数的函数的引用,如果是在全局作用域中调用当前函数,它的值就为null。
function outer() {
inner();
}
function inner(){
alert(arguments.callee.caller);
}
outer();
执行以上代码将输出outer()函数的源代码
函数也是对象,因此函数也有属性和方法。
每个函数包含两个属性:length 和 prototype。
每个函数包含两个非继承而来的方法:apply( )和call( )。
都是在特定的作用域里调用函数,相当于是设置函数体内的this对象的值。
function sum (num1,num2){
return this.a+this.b+num1+num2;
}
var s={
a:1,
b:2
};
console.log(sum.apply(s,[3,4])); //10
console.log(sum.call(s,3,4)); //10
1.调用方式(匿名函数立即执行)
(function () {
})();
var f = (function () {
})();
//这样写小括号可以不要,如下
var f = function () {
}();
2.模仿块级作用域
(function () {
//这里是块级作用域
})();
因篇幅问题不能全部显示,请点此查看更多更全内容