函数
概述
函数表达式的最后有一个圆括号,表示这个函数被调用
圆括号中任何被传入的变量,都会被翻译成一个列表,作为函数参数来使用
如果调用时候传入的参数数目多于函数定义的变量个数,多出来的变量不会赋值到函数定义时候的有名字的参数上
如果函数定义的参数数目多于传入的变量,多出来的变量则会是undefined
每个函数在被调用的时候,隐性的传入两个参数:arguments 和 this
argments 参数,即函数调用的时候传入函数的变量集合
这个集合具有 length 属性,表示集合内变量的个数
并且集合中的变量可以根据下标索引被引用this参数,这个对象隐性的与函数的调用发生关系,我们叫做函数上下文(function context)
函数调用
- 作为函数直接被调用
- 作为方法,被连接在对象上,被对象调用
- 作为构造器,在构造的过程中一个新的对象被创建出来
- 使用apply()或call()方法
1.函数调用模式
这种调用模式的触发是由于函数后面加上()
当我们用这种模式来调用函数的时候,函数的上下文是全局的上下文,即window对象
2.方法调用模式
一个函数是一个对象的属性,当这个函数被调用时候,这个函数就视为这个对象的一个方法
当这个函数作为一个对象的方法被调用的时候,这个对象就成为了这个函数的上下文(function context),并且通过 this 作为载体存在于函数之中。
var o = {};
o.whatever = function(){};
o.whatever();
3.构造器调用模式
将一个函数作为构造器来调用会发生以下几步:
1. 一个新的空对象被创建出来
2. 这个对象被传递给这个构造器作为 this 参数,也就是说这个对象是这个构造器函数的上下文
3. 如果没有显性的 return 语句,这个新的对象则会被隐式的 return,并成为这个构造器的值
由于构造函数的代码和调用模式和其他函数不同,所以一般不会用 new之外的方式来调用一个构造函数
一般小写字母开头的函数名字就是普通函数
大写字母开头的既是构造函数
4.使用apply()和call()调用
apply():
第一个参数:用于作为函数上下文的对象;
第二个参数:一个参数数组
call():
参数为方法的参数数组(用多参数的形式传递,而不是一个数组)
function juggle(){
var result = 0;
for (var n = 0; n < arguments.length; n++){
result += arguments[n];
}
this.result = result;
}
var ninja1 = {};
var ninja2 = {};
juggle.apply(ninja1, [1,2,3,4]);
juggle.call(ninja2, 5, 6, 7, 8);
assert(ninja1.result === 10, "juggled via apply");
assert(ninja2.result === 26, "juggled via call");
函数上下文在回调函数中的应用:
function forEach(list, callback){
for (var n = 0; n < list.length; n++){
callback.call(list[n], n);
}
}
var list = ['shuriken', 'katana', 'nunchucks'];
forEach(
list,
function(index){
console.log(index);
console.log(this);
assert(this == list[index], "Got the expected value of "+
list[index]);
}
)
匿名函数
常用于回调
window.onload= function(){ assert(true,'power!');};
var ninja = {
shout: function(){ assert(true, "Ninja");}
}
ninja.shout(); setTimeout(function(){ assert(true, 'Forever!')}, 500)
其他
var abc=function sdf{
sdf();
}
sdf无法在外部被调用,只能在方法内部被调用