JavaScript极简入门教程(二):对象和函数(2)
函数是对象,你可以像使用对象一样使用函数,也就是说,函数可以保存在变量、数组中,可以作为参数传递给函数,函数内部可以定义函数。附带提及一下,函数有两个被隐藏的属性:
1.函数的上下文
2.函数的代码
函数的创建如下:
var f = function add(a, b) {
return a + b;
}
console.log(f); // 输出 [Function: add]
关键字 function 后的函数名是可选的,我们制定函数名主要出于几个目的:
1.为了递归调用
2.被调试器、开发工具等用来标识函数
很多时候我们并不需要函数名,没有函数名的函数被叫做匿名函数。有括号包裹的为参数列表。JavaScript 不要求实参和形参匹配,例如:
var add = function(a, b) {
return a + b;
}
add(1, 2, 3); // 实参和形参不匹配
如果实参过多,那么多余的实参会被忽略,如果实参过少,那么未被赋值的形参的值为 undefined。函数一定有一个返回值,如果没有通过 return 语句指定返回值,那么函数返回值为 undefined。
一个函数和其访问的外部变量组成一个闭包。这是 JavaScript 的关键魅力所在。
函数调用
每个函数被调用时,会接收到两个额外的参数:
1.this
2.arguments
this 的值和具体调用的模式有关,在 JavaScript 中有四种调用模式:
1.方法调用模式。对象的属性如果是函数,则称其为方法。如果一个方法通过 o.m(args) 被调用,this 为对象 o(由此可见,在调用时,this 和 o 才进行绑定),例如:
var obj = {
value: 0,
increment: function(v) {
this.value += (typeof v === 'number' ? v : 1);
}
};
obj.increment(); // this === obj
2.函数调用模式。如果一个函数不是一个对象的属性,那么它将作为一个函数被调用,这时候 this 被绑定到全局对象上,例如:
message = 'Hello World';
var p = function() {
console.log(this.message);
}
p(); // 输出 'Hello World'
这种行为有时候让人疑惑,看一个例子:
obj = {
value: 0,
increment: function() {
var helper = function() {
// 对全局对象中的 value 加 1
this.value += 1;
}
// helper 被作为一个函数来调用
// 因此 this 为全局对象
helper();
}
};
obj.increment(); // obj.value === 0
我们期望的结果应该是:
obj = {
value: 0,
increment: function() {
var that = this;
var helper = function() {
that.value += 1;
}
helper();
}
};
obj.increment(); // obj.value === 1
3.构造函数调用模式。意图使用 new 前缀的函数被叫做构造函数,例如: