preventing无限循环利用骨干风格的原型继承时 [英] Preventing infinite recursion when using Backbone-style prototypal inheritance

查看:151
本文介绍了preventing无限循环利用骨干风格的原型继承时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的是改编自一个骨干扩展功能(相同的除了一些改变以符合我的雇主的命名约定)来实现原型继承。建立结构如下(下大大简化)后,我得到一个无限循环。

I'm using an extend function adapted from Backbone (identical apart from a few changes to comply with my employer's naming conventions) to implement prototypal inheritance. After setting up the following structure (much simplified below) I get an infinite loop.

Graph = function () {};
Graph.extend = myExtendFunction;
Graph.prototype = {
   generateScale: function () {
       //do stuff
   }
}
 // base class defined elsewhere
UsageGraph = Graph.extend({
   generateScale: function () {
       this.constructor._super.generateScale.call(this); // run the parent's method
       //do additional stuff
   }
})

ExcessiveUsageGraph = Graph.extend({
   // some methods, not including generateScale, which is inherited directly from Usage Graph
})

var EUG = new ExcessiveUsageGraph();
EUG.generateScale(); // infinite loop

循环正在发生的事情,因为 ExcessiveUsageGraph 上升原型链 UsageGraph 来运行的方法,但这个仍设置为 ExcessiveUsageGraph 所以,当我使用 this.constructor._super 来运行它也更进了一步链条 UsageGraph ,并再次调用同样的方法父类的方法。

The loop is happening because ExcessiveUsageGraph goes up the prototype chain to UsageGraph to run the method, but this is still set to an instance of ExcessiveUsageGraph so when I use this.constructor._super to run the parent method it also goes one step up the chain to UsageGraph and calls the same method again.

我怎么能引用父方法从骨干风格的原型内避免这种循环。我也想尽量避免通过名称引用父类。

How can I reference parent methods from within a Backbone-style prototype and avoid this kind of loop. I also want to avoid referring to parent classes by name if possible.

修改这里有一个小提琴表明这种情况发生在骨干

推荐答案

你到JavaScript的这个和原型继承的限制之一运行,正视因为你'重新尝试创建一种语言的一类,如继承方案,它不直接支持它。

You're running in to one of the limitations of JavaScript's this and prototypal inheritance, squarely because you're attempting to create a class-like inheritance scheme in a language that doesn't directly support it.

即使骨干,您通常使用的超级望而却步直接,因为你已经列出,并限制了。

Even with Backbone, you are generally discouraged from using "super" directly because of the limitations that you've outlined, and more.

常见的解决方法是直接调用您的原型对象,而不是试图通过使用一个超级参考掩盖它。

The common solution is to call your prototype object directly, instead of trying to mask it through the use of a "super" reference.


UsageGraph = Graph.extend({
   generateScale: function () {
       Graph.prototype.generateScale.call(this); // run the parent's method
       //do additional stuff
   }
})

在工作的jsfiddle: http://jsfiddle.net/derickbailey/vjvHP/4/

In a working JSFiddle: http://jsfiddle.net/derickbailey/vjvHP/4/

这部作品的原因是在JavaScript中本的事情。当你调用一个函数时,this关键字是基于你如何调用该函数,而不是在这里被定义的函数集。

The reason this works has to do with "this" in JavaScript. When you call a function, the "this" keyword is set based on how you call the function, not where the function is defined.

在调用generateScale的方法在此code的情况下,它调用generateScale功能,设置的上下文的点表示法。换句话说,因为code读 prototype.generateScale ,函数调用(以下简称本关键字)的情况下被设置为原型对象,这恰好是构造函数的原型。

In the case of calling the "generateScale" method in this code, it's the dot-notation of invoking the generateScale function that sets the context. In other words, because the code reads prototype.generateScale, the context of the function call (the "this" keyword) is set to the prototype object, which happens to be the prototype of the Graph constructor function.

由于 Graph.prototype 现在呼叫到 generateScale 的背景下,该功能将与运行背景和行为,你期待。

Since the Graph.prototype is now the context of the call to generateScale, that function will run with the context and behavior that you are expecting.

相反,如果你的呼吁, this.constructor._super.generateScale ,允许你的JavaScript歪斜的背景下,你没有因为期望的方式在在启动这个关键字。

Conversely, when you made the call to this.constructor._super.generateScale, you allowed JavaScript to skew the context in a manner that you didn't expect because of the this keyword at the start.

这是你的层次结构的第三层是造成这一问题与本。你打电话 EUG.generateScale ,其中明确制定这个 EUG 实例。为 generateScale 方法的原型查找到达回原型来调用该方法,因为该方法未找到在 EUG 实例直接。

It's the 3rd level of your hierarchy that's causing the problem with "this". You're calling EUG.generateScale, which is explicitly setting this to the EUG instance. The prototypal lookup for the generateScale method reaches back to the Graph prototype to call the method, because the method is not found on the EUG instance directly.

这个已设置为 EUG 实例和JavaScript的原型查找方面这个。所以,当UsageGraph原型 generateScale 被称为这个设置为 EUG 实例。因此,调用 this.constructor .__超级__ 将被从 EUG 实例评估,是要找到UsageGraph作为原型的__ __超级的值,这意味着你要再次调用同一个对象的同一个方法,用同样的背景。因此,一个无限循环。

But this has already been set to the EUG instance, and JavaScript's prototypal lookup respects this. So, when the UsageGraph prototype generateScale is called, this is set to the EUG instance. Therefore, calling this.constructor.__super__ is going to be evaluated from the EUG instance and is going to find the UsageGraph prototype as the value of __super__, which means you're going to call the same method on the same object, with the same context again. Thus, an infinite loop.

该解决方案不使用这个原型中查找。直接使用命名函数和原型,我在解决方案,并表现出的jsfiddle

The solution is not to use this in prototypal lookups. Use the named function and prototype directly, as I showed in the solution and JSFiddle.

这篇关于preventing无限循环利用骨干风格的原型继承时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆