javascript 为对象绑定方法和作用域

在 JavaScript 中,函数通常运行在一个特定的上下文中(通常称为“作用域[scope]”)。在函数内部, this 关键字是指向那个作用域的引用。实际上,每个函数都是对象的属性——全局函数是 window 对象的属性——运行时函数的作用域即为函数被调用时函数所属的对象, 更严格的说法是保存了对函数的引用的对象:

window.name = "the window object";
function scopeTest() {
return this.name
}
// 在全局作用域内调用这个函数:
scopeTest()
// -> "the window object"
var foo = {
name: "the foo object!",
otherScopeTest: function() {
return this.name
}
}
foo.otherScopeTest()
// -> "the foo object!"

因为动态语言的特性,我们不能确保函数总是被同一种类型的对象调用,如 otherScoptTest() 也可以被 foo 之外的对象调用。这时,函数的 this 引用也会指向其它的对象,例如 window 对象:

// ... 继续上面的样例 
// 注意,我们不是调用这个函数,而是简单引用它
window.test = foo.otherScopeTest
// 现在实际调用这个函数
test()
// -> "the window object"

最后那个调用证明了同样的函数具有不同的行为,它依赖于运行时的作用域。

当你在代码中将函数的引用赋给另外一个对象时,通常会希望函数运行在一个固定的作用域中。在 Prototype 中, 只要在函数上调用 bind 方法,将 this 关键字绑定到你所指定的对象, 就可以确保函数运行在期望的作用域中。如果需要的话,你也可以保存返回的函数,以重复使用它。


样例

下面的代码是关于上述概念的一个简单证明:

var obj = { 
name: 'A nice demo',
fx: function() {
alert(this.name);
}
};

window.name = 'I am such a beautiful window!';
function runFx(f) {
f();
}
var fx2 = obj.fx.bind(obj);
runFx(obj.fx);
runFx(fx2);
目前,仅有少数人知道:bind 也可以用来为最终的参数列表预设参数值:
var obj = { 
name: 'A nice demo',
fx: function() {
alert(this.name + '\n' + $A(arguments).join(', '));
}
};

var fx2 = obj.fx.bind(obj, 1, 2, 3);
fx2(4, 5);
// 显示相应的 name 值,及 "1, 2, 3, 4, 5"
posted @ 2011-04-08 10:19  Tory  阅读(199)  评论(0编辑  收藏  举报