先看call(或apply)的用处:
var first_object = {
num: 42
};
function multiply(mult) {
return this.num * mult;
}
multiply.apply(first_object, [5]); //等于 42*5
在上面的例子中,multiply是一个function,里面有this,所以,它必须“成为某个对象的方法才能执行”。这里的multiply函数中的this默认为全局的window对象:
function multiply(mult) {
return this.num * mult;
}
window.num = 100;
multiply(4); //等于 400
由于JavaScript是动态语言,一个对象的方法可以被变成另外的对象的方法,所以,该方法下的this会发生变化。
function multiply(mult) {
return this.num * mult;
}
var book = {
num : 33
};
book.total = multiply;
book.total(10);
换种写法,采用new关键字
function multiply(mult) {
return this.num * mult;
}
function Book(newNum) {
this.num = newNum;
}
var book = new Book(33);
book.total = multiply;
book.total(10);
再看看下面的写法,和平时写的类比较像了:
function Book(newNum) {
this.num = newNum;
this.total = function (mult) {
return this.num * mult;
}
}
var book = new Book(33);
book.total(10);
正因为this指针的不确定性,使得this所属函数定义的 和 实际执行的 上下文环境不同,从而计算出非预期的结果。
再看最初的代码示例,我们用js提供的call函数来解决this的问题。可以考虑给function函数原型增加一个bind方法------它只是封装了apply函数,返回值是一个function:
var first_object = {
num: 42
};
function multiply(mult) {
return this.num * mult;
}
Function.prototype.bind = function(obj) { //该行可换做 multiply.prototype.bind = function(obj) {
var method = this;
return function() {
return method.apply(obj, arguments);
};
}
var foo = multiply.bind(first_object);
foo(5);
(把bind方法建立在multiply的原型上也可,如注释所示)
总之,把正确的方法放在正确的对象里,才是bind方法的目的。请参看prototype.js关于bind方法的API:
http://www.prototypejs.org/api/function/bind
下面是prototype.js关于bind的源代码:
bind: function() {
if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this;
var __method = this, args = $A(arguments), object = args.shift();
return function() {
return __method.apply(object, args.concat($A(arguments)));
}
},
参考网址:
http://www.digital-web.com/articles/scope_in_javascript/
本文探讨了JavaScript中this指针的不确定性问题及其对函数执行上下文的影响,并介绍了如何使用bind方法来解决this指向问题。
224

被折叠的 条评论
为什么被折叠?



