目前,我通过声明构造(常规函数)在javascript中创建对象,然后将方法添加到原型中
function Test(){
}
Test.prototype.test1 = function(){
var me = this;
}
但是,我希望避免在每个函数的顶部声明var me = this
。以下似乎有效,但似乎效率很低:
$(document).ready(function(){
var n = 0;
(function(){
function createTest(){
var me;
function Test(){
this.n = n;
this.testArr = [1, 2, 3, 4];
n++;
}
Test.prototype.test1 = function(){
me.test2();
};
Test.prototype.test2 = function(){
alert(me.n);
$.getJSON('test.php', {}, function(reply)
//want to be able to use 'me' here
me.newField = reply;
});
};
var t = new Test();
me = t;
return t;
}
window['createTest'] = createTest;
})();
var t = createTest();
t.test1();
var t2 = createTest();
t2.test1();
t.test1();
});
此代码输出预期的,但实际上它看起来效率低(每次调用createTest()时都会重新声明Test对象)?
Anyhoo,这看起来有点像hacky ......有没有一种完全不同的方式做到这一点更好?
编辑:我想这样做的真正原因是,像test2中那样的回调将引用正确的this
。
答案 0 :(得分:2)
您可以做的是将当前this
值绑定到function
并将副本存储在某处。 (为了提高效率。)
if (!Function.prototype.bind) {
// Most modern browsers will have this built-in but just in case.
Function.prototype.bind = function (obj) {
var slice = [].slice,
args = slice.call(arguments, 1),
self = this,
nop = function () { },
bound = function () {
return self.apply(this instanceof nop ? this : (obj || {}),
args.concat(slice.call(arguments)));
};
nop.prototype = self.prototype;
bound.prototype = new nop();
return bound;
};
}
function Test(n) {
this.n = n;
this.callback = (function () {
alert(this.n);
}).bind(this)
}
Test.prototype.test1 = function () {
this.test2();
}
Test.prototype.test2 = function () {
doSomething(this.callback);
}
function doSomething(callback) {
callback();
}
var t = new Test(2);
t.test1();
答案 1 :(得分:2)
我意识到你的问题没有用jQuery标记,但你在你的例子中使用它,所以我的解决方案也使用了jQuery。
我有时使用$.proxy
函数来避免回调上下文。 Look at this simple jsfiddle example。来源如下。
function Test(){
this.bind();
}
Test.prototype.bind = function(){
$('input').bind('change', $.proxy(this.change, this));
// you could use $.proxy on anonymous functions also (as in your $.getJSON example)
}
Test.prototype.change = function(event){
// currentField must be set from e.target
// because this is `Test` instance
console.log(this instanceof Test); // true
console.log(event.target == $('input')[0]); // true
this.currentField = event.target; // set new field
};
function createTest(){
return new Test();
}
$(function(){ // ready callback calls test factory
var t1 = createTest();
});
答案 2 :(得分:0)
大多数时候,我只是声明一个引用它的局部变量,无论我在回调中需要对它的引用:
function Foo() {
}
Foo.prototype.bar = function() {
var that=this;
setTimeout(function() {
that.something="This goes to the right object";
}, 5000);
}
或者,您可以像这样使用bind():
Function Foo() {
this.bar = this.bar.bind(this);
// ... repeated for each function ...
}
Foo.prototype.bar = function() {
}
这给你的是每次创建新的Foo实例时,方法都绑定到当前实例,因此你可以将它们用作setTimeout()等的回调函数。