List 3.5 Using the apply and call methods to supply the function context 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");
我们看到通过 apply()或者 call(),我们将 ninja1 或 ninja2 作为参数传入
到了函数 juggle()中,
并且让 ninja1 称为了函数上下文。
另外要注意的是 apply 和 call 的区别在于,后面的参数,一个是数组,
另一个是 argmuments list
这种用法在回调函数中会更加有用
函数上下文在回调函数中的应用(FORCING THE FUNCTION
CONTEXT IN CALLBACKS):
Listing 3.6 Building a for-each function to demonstrate setting an arbitrary function context 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]); } )
3.4 总结(Summary)在本章,我们学到:
1.基于对 JavaScript 是一门函数式语言的理解,你可以写出更
对位的代码。
2.函数是自然类型的对象(fist class objects),就象其他对象一
样,它可以:
1) 通过字面量创建 2) 赋予给一个变量 3) 作为参数传递 4) 作为另一个函数的返回值 5) 拥有变量和方法
3.函数不同于其他对象的一个超级能力就是它可以被调用
4.函数通过字面量来创建,可以没有函数名
5.函数的域的定义再 JavaScript 中相比起其他语言有些特别:
1)函数内部的变量的有效域是定义它的地方到函数结束处 2)内部函数再包裹它的函数内是处处有效的,甚至是定义这个内部函数的前面也有效
6.一个函数的参数列表和它实际的 argument 列表的长度可以
不同1)如果没有赋与的参数,那么这个参数就是 undefined 2)超出预设长度的 arguments 不会绑定到任何参数上
7.所有函数被调用的时候,都会隐性的传入两个 arguments
1)arguments: 真正传入的 arguments 集合 2)this: 函数上下文的载体
8.函数可以有多种调用方式,调用的方式决定了函数上下文的不
同