保留对“this"的引用在 JavaScript 原型函数中 [英] Preserving a reference to "this" in JavaScript prototype functions
问题描述
我刚刚开始使用原型 JavaScript,我无法弄清楚如何在范围更改时从原型函数内部保留对主对象的 this
引用.让我来说明我的意思(我在这里使用 jQuery):
I'm just getting into using prototypal JavaScript and I'm having trouble figuring out how to preserve a this
reference to the main object from inside a prototype function when the scope changes. Let me illustrate what I mean (I'm using jQuery here):
MyClass = function() {
this.element = $('#element');
this.myValue = 'something';
// some more code
}
MyClass.prototype.myfunc = function() {
// at this point, "this" refers to the instance of MyClass
this.element.click(function() {
// at this point, "this" refers to the DOM element
// but what if I want to access the original "this.myValue"?
});
}
new MyClass();
我知道我可以通过在 myfunc
的开头这样做来保留对主对象的引用:
I know that I can preserve a reference to the main object by doing this at the beginning of myfunc
:
var myThis = this;
然后使用 myThis.myValue
访问主对象的属性.但是当我在 MyClass
上有一大堆原型函数时会发生什么?我是否必须在每个开头保存对 this
的引用?似乎应该有一种更清洁的方式.那么像这样的情况呢:
and then using myThis.myValue
to access the main object's property. But what happens when I have a whole bunch of prototype functions on MyClass
? Do I have to save the reference to this
at the beginning of each one? Seems like there should be a cleaner way. And what about a situation like this:
MyClass = function() {
this.elements $('.elements');
this.myValue = 'something';
this.elements.each(this.doSomething);
}
MyClass.prototype.doSomething = function() {
// operate on the element
}
new MyClass();
在那种情况下,我无法使用 var myThis = this;
创建对主对象的引用,因为即使 this
的原始值在 <的上下文中code>doSomething 是一个 jQuery
对象而不是 MyClass
对象.
In that case, I can't create a reference to the main object with var myThis = this;
because even the original value of this
within the context of doSomething
is a jQuery
object and not a MyClass
object.
有人建议我使用全局变量来保存对原始 this
的引用,但这对我来说似乎是一个非常糟糕的主意.我不想污染全局命名空间,这似乎会阻止我在不相互干扰的情况下实例化两个不同的 MyClass
对象.
It's been suggested to me to use a global variable to hold the reference to the original this
, but that seems like a really bad idea to me. I don't want to pollute the global namespace and that seems like it would prevent me from instantiating two different MyClass
objects without them interfering with each other.
有什么建议吗?有没有一种干净的方法来做我所追求的?还是我的整个设计模式有缺陷?
Any suggestions? Is there a clean way to do what I'm after? Or is my entire design pattern flawed?
推荐答案
为了保留上下文,bind
方法非常有用,它现在是最近发布的ECMAScript 5th Edition 规范,这个功能的实现很简单(只有8行):
For preserving the context, the bind
method is really useful, it's now part of the recently released ECMAScript 5th Edition Specification, the implementation of this function is simple (only 8 lines long):
// The .bind method from Prototype.js
if (!Function.prototype.bind) { // check if native implementation available
Function.prototype.bind = function(){
var fn = this, args = Array.prototype.slice.call(arguments),
object = args.shift();
return function(){
return fn.apply(object,
args.concat(Array.prototype.slice.call(arguments)));
};
};
}
你可以使用它,在你的例子中是这样的:
And you could use it, in your example like this:
MyClass.prototype.myfunc = function() {
this.element.click((function() {
// ...
}).bind(this));
};
另一个例子:
var obj = {
test: 'obj test',
fx: function() {
alert(this.test + '
' + Array.prototype.slice.call(arguments).join());
}
};
var test = "Global test";
var fx1 = obj.fx;
var fx2 = obj.fx.bind(obj, 1, 2, 3);
fx1(1,2);
fx2(4, 5);
在第二个例子中,我们可以观察到更多关于 bind
的行为.
In this second example we can observe more about the behavior of bind
.
它基本上生成了一个新函数,它将负责调用我们的函数,保留函数上下文(this
值),它被定义为bind的第一个参数代码>.
It basically generates a new function, that will be the responsible of calling our function, preserving the function context (this
value), that is defined as the first argument of bind
.
其余的参数只是简单地传递给我们的函数.
The rest of the arguments are simply passed to our function.
请注意,在此示例中,函数 fx1
是在没有任何对象上下文 (obj.method()
) 的情况下调用的,就像简单的函数调用,在这种类型的调用中,里面的this
关键字会指向全局对象,会提示全局测试".
Note in this example that the function fx1
, is invoked without any object context (obj.method()
), just as a simple function call, in this type of invokation, the this
keyword inside will refer to the Global object, it will alert "global test".
现在,fx2
是 bind
方法生成的新函数,它将调用我们的函数,保留上下文并正确传递参数,它会警告obj测试 1, 2, 3, 4, 5" 因为我们调用它并添加两个额外的参数,它已经绑定前三个.
Now, the fx2
is the new function that the bind
method generated, it will call our function preserving the context and correctly passing the arguments, it will alert "obj test 1, 2, 3, 4, 5" because we invoked it adding the two additionally arguments, it already had binded the first three.
这篇关于保留对“this"的引用在 JavaScript 原型函数中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!