原文:http://yehudakatz.com/2011/08/11/understanding-javascript-function-invocation-and-this/
==============================================
(1)Function的call的原型
function hello(thing) { console.log(this + " says hello " + thing); } hello.call("Yehuda", "world") //=> Yehuda says hello world
call的第一个参数就是this是谁,后面是function的参数, 所以hello里面,this是指“yehuda”。
(2)简单的Function调用
通常都不使用call,而是这样:
function hello(thing) { console.log("Hello " + thing); } // this: hello("world") // desugars to: hello.call(window, "world");
这种简略的调用时,实际第一个参数是window,所以function里this就是当前window。
(3)成员function
var person = { name: "Brendan Eich", hello: function(thing) { console.log(this + " says hello " + thing); } } // this: person.hello("world") // desugars to this: person.hello.call(person, "world");
call的第一个参数传递的是person这个对象,所以funcion里this是指它所属的person对象。
再看一个例子:
function hello(thing) { console.log(this + " says hello " + thing); } person = { name: "Brendan Eich" } person.hello = hello; person.hello("world") // still desugars to person.hello.call(person, "world") hello("world") // "[object DOMWindow]world"
这个例子是说,this不是固定的,是调用时动态决定的。你调用的方式不同,this可能不同。
(4)使用Function.prototype.bind
有时候,让this保持一个固定值,会比较方便。
历史上,一般会这么写,
var person = { name: "Brendan Eich", hello: function(thing) { console.log(this.name + " says hello " + thing); } } var boundHello = function(thing) { return person.hello.call(person, thing); } boundHello("world");
虽然调用boundHello仍然相当于boundHello.call(window, "world"), 但是咱们在里面传递是person对象作为this。
咱们可以稍稍修改一下这个小戏法:
var bind = function(func, thisValue) { return function() { return func.apply(thisValue, arguments); } } var boundHello = bind(person.hello, person); boundHello("world") // "Brendan Eich says hello world"
有点不一样哈,arguments是一个类似于数组的对象,它持有所有function的参数, apply类似于call方法,只是它的参数是数组这种类型的,而不是一个一个列出来。
bind太常用了,所以ES5(啥东西?)介绍了Function的bind方法,它也实现了这个动作。
var boundHello = person.hello.bind(person); boundHello("world") // "Brendan Eich says hello world"
这个东东在你把function作为callback时,非常有用。如:
var person = { name: "Alex Russell", hello: function() { console.log(this.name + " says hello world"); } } $("#some-div").click(person.hello.bind(person)); // when the div is clicked, "Alex Russell says hello world" is printed
this.name可以直接取到自己的name属性,非常方便。
(5)jQuery 在jQuery里使用了大量的回调,它使用call方法,将第一个参数传递为(设置回调的那个element),这非常有用。
|