我想代理'代理' (不确定这个术语是否完全是)一个函数内的函数,以便于调用。
给出以下代码
function Soldier() {
this.el = $("<div></div>").addClass('soldier');
this.pos = this.el.position; // $(".soldier").position(), or so I thought
}
在控制台中:
s = new Soldier();
$("#gamemap").append(s.el); // Add the soldier to the game field
s.pos === s.el.position // this returns true
s.el.position() // Returns Object {top: 0, left: 0}
s.pos() // Returns 'undefined'
在这种情况下我做错了什么,是否有一种简单的方法来实现我的目标(s.pos()
返回s.el.position()
的结果)?
我想过s.pos = function() { return s.el.position(); }
,但看起来有点难看而且不合适。此外,我还想添加更多类似的功能,并且即使加载,库也会变得非常大。
答案 0 :(得分:3)
当您呼叫s.pos()
时,其this
上下文将丢失。
您可以使用call()
:
s.pos.call(s); // same as s.pos()
s.pos.call(s.el); // same as s.el.position()
这段代码实际上还可以:
s.pos = function() { return s.el.position(); }
另一种方法是使用bind()
:
s.pos = s.el.position.bind(el);
您可以使用原型,这样就不会为每个对象单独创建函数:
Soldier.prototype.pos = function(){ return this.el.position(); }
答案 1 :(得分:1)
我建议使用原型:
Soldier.prototype.pos = function() { return this.el.position(); };
根本不丑陋,实际上非常高效。
如果要在构造函数中直接分配它,您需要注意s.pos()
调用的this
context是错误的。因此,您需要bind
:
…
this.pos = this.el.position.bind(this.el);
答案 2 :(得分:1)
这是因为position
方法的执行上下文已经改变。如果将方法绑定到元素上下文中,它将起作用。
function Soldier() {
this.el = $("<div></div>").addClass('soldier');
this.pos = this.el.position.bind(this.el);
}
var s = new Soldier();
$("#gamemap").append(s.el);
console.log(s.pos());