一、函数的定义
- 函数保留字function
- 函数名,可以被省略,可以用它的名字递归的调用自己
- 参数
- 函数主体,函数可以有return语句,也可以没有return语句。return语句可以停止函数的运行,并把表达式的值返给函数调用者。如果不包含return语句,函数只执行函数体中每条语句,然后返回undefined对函数调用者。
例:
function add(num1, num2) {
return num1 + num2;
}
//匿名函数
var add = function(num1, num2) {
return num1 + num2;
}
//递归调用
function factorial(x) {
if (x <= 1) {
return 1;
} else {
return x*factorial(x-1);
}
}
二、匿名函数、函数的调用
匿名函数就是没有名字的函数,也叫拉姆达函数。
//函数声明
function functionName(arg0, arg1, arg2) {
//do something
}
//函数表达式
var functionName = function(arg0, arg1, arg2) {
//do something
}
上面的两个例子在逻辑上等价,但是它们之间还是存在一些区别。函数声明与函数表达式的主要区别,就是前者会在代码执行以前加载到作用域中,而后者是代码执行到那一行时才会有定义。另一个重要的区别是,函数声明会会给函数指定一个名字,而函数表达式则是创建一个匿名函数,然后将这个匿名函数赋值给一个变量。
三、函数的调用
3.1 方法调用模式
当函数被保存为对象的一个属性时,我们称它为一个方法。当一个方法调用时,this被绑定到该对象。
var o = {
value: 0,
increment: function(inc) {
this.value += typeof inc === 'number' ? inc : 1;
}
};
o.increment();
console.log(o.value); //1
o.increment(2);
console.log(o.value); //3
o.increment(5);
console.log(o.value); //8
o.increment('test');
console.log(o.value); //9
方法可以用this去访问该对象,所以它能从对象中取值或修改该对象。通过this取得它们上下文的方法称为公用方法。
3.2 函数调用模式
var sum = add(2, 4); //sum为6
当函数以该模式调用时,this被绑定到全局对象。解决方法:给该方法定义一个变量并赋值为this,那为内部函数就可以通过该变量访问到this。
//函数调用模式
var add = function(num1, num2) {
return num1 + num2;
}
o.double = function() {
var _self = this;
var op = function() {
_self.value = add(_self.value, _self.value);
};
op();
}
o.double();
console.log(o.value); //18
3.3 构造函数调用模式
//创建构造函数
var Person = function(name) {
this.name = name;
}
Person.prototype.get_name = function() {
return this.name;
}
var driver = new Person('jack');
console.log(driver.get_name());
3.4 apply模式
apply方法构建一个参数数组并去调用函数。apply方法接收两个参数,第一个是绑定给this的值,第二个是参数数组。
var arr = [11, 12];
var sum = add.apply(null, arr);
console.log(sum); //23
var teacher = {
name: lucy
};
var name = Person.prototype.get_name.apply(teacher);
console.log(name); //lucy
四、this 的工作原理
JavaScript 有一套完全不同于其它语言的对 this 的处理机制。 在五种不同的情况下 ,this 指向的各不相同。
4.1 全局范围内
this;
当在全部范围内使用 this,它将会指向全局对象。
4.2 函数调用
foo();
这里 this 也会指向全局对象。
4.3 调用构造函数
new foo();
如果函数倾向于和 new 关键词一块使用,则我们称这个函数是 构造函数。 在函数内部,this 指向新创建的对象。
4.4 显式的设置 this
function foo(a, b, c) {}
var bar = {};
foo.apply(bar, [1, 2, 3]); // 数组将会被扩展,如下所示
foo.call(bar, 1, 2, 3); // 传递到foo的参数是:a = 1, b = 2, c = 3
当使用 Function.prototype 上的 call 或者 apply 方法时,函数内的 this 将会被 显式设置为函数调用的第一个参数。
因此函数调用的规则在上例中已经不适用了,在foo 函数内 this 被设置成了 bar。