首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >这种寄生遗传模式有什么好处吗?

这种寄生遗传模式有什么好处吗?
EN

Stack Overflow用户
提问于 2011-11-17 17:56:48
回答 1查看 261关注 0票数 2

JavaScript中的原型对象创建被认为是强大的(我听说它很高效,如果使用得当,它的表现力非常强)。但出于某种原因,我发现它经常让我绊倒,而不是它对我有帮助。

对于涉及原型的对象创建模式,我遇到的主要问题是没有办法绕过对this的需要。主要原因是除了非常原始之外的任何对象,例如通过异步API调用填充自身的对象,this由于作用域的改变而崩溃。

因此,我使用原型对象创建对象,我从一开始就知道所有的东西。

但对于需要这样做的对象,例如API调用以使自己保持最新,我完全跳过prototype,直接使用对象字面量。

当我觉得需要扩展其中一个对象时,我使用了寄生继承:

代码语言:javascript
复制
var ROOT = ROOT || {};

ROOT.Parent = function () {
    var self = {
        func1 : function () {
            alert("func1")
        };
    }
    return self;
};

ROOT.Child = function () {
    var self = ROOT.Parent(); // This is the parasitizing

    self.func2 = function () {
        alert("func2")
    };

    return self;
};

var myChild = ROOT.Child();
myChild.func1(); // alerts "func1"
myChild.func2(); // alerts "func2"

使用这个模式,我可以在ROOT.Child对象中重用func1的代码。但是,如果我想在func1中扩展代码,我就遇到了一个问题。也就是说,如果我既要调用父func1中的代码,又要调用我自己的func1中的代码,那么这个模式就是一个挑战。我不能这样做:

代码语言:javascript
复制
ROOT.Child = function () {
    var self = ROOT.Parent();

    self.func1 = function () {
        alert("func2")
    };
};

因为这将完全替换该函数。为了解决这个问题,我提出了以下解决方案(您也可以在这里查看:http://jsfiddle.net/pellepim/mAGUg/9/)。

代码语言:javascript
复制
var ROOT = {};

/**
 * This is the base function for Parasitic Inheritence
 */
ROOT.Inheritable = function () {
    var self = {
        /**
         * takes the name of a function that should exist on "self", and
         * rewires it so that it executes both the original function, and the method
         * supplied as second parameter.
         */
        extend : function (functionName, func) {
            if (self.hasOwnProperty(functionName)) {
                var superFunction = self[functionName];
                self[functionName] = function () {
                    superFunction();
                    func();
                };
            }
        },

        /**
         * Takes the name of a function and reassigns it to the function supplied
         * as second parameter.
         */
        replace : function (methodName, func) {
            self[methodName] = func;
        } 
    };

    return self;
};

/**
 * "Inherits" from ROOT.Inheritable
 */
ROOT.Action = function () {
    var self = ROOT.Inheritable();
    /**
     * I intend to extend this method in an inheriting object
     */
    self.methodToExtend = function () {
        alert("I should be seen first, since I get extended");  
    };
    /**
     * I intend to replace this method in an inheriting object
     */
    self.methodToReplace = function () {
        alert("I should never be seen, since I get replaced.");
    };
    return self;
};

/**
 * "Inherits" from ROOT.Action.
 */
ROOT.Task = function () {
    var self = ROOT.Action();

    self.extend('methodToExtend', function () {
       alert("I successfully ran the extended code too.");
    });

    /** 
     * I know it is completely unecessary to have a replace method, 
     * I could just as easily just type self.methodToReplace = function () ...
     * but I like that you see that you are actually replacing something.
     */
    self.replace('methodToReplace', function () {
        alert("I successfully replaced the \"super\" method.");
    });

    return self;
};

var task = ROOT.Task();

task.methodToExtend(); // I expect both the "base" and "child" method to run.
task.methodToReplace(); // I expect only the "child" method to run.

好了,我要问一个问题。我是不是完全偏离目标了,还是我说对了?明显的缺点是什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-11-17 18:14:18

不,你没有偏离目标。但那个轮子也不是你发明的。这种类型的ECMAscript继承在Doug Crockfords的书Javascript: The good parts中变得非常有名。

这是一个很好的模式,它很好地使用了闭包来保护私密性。但是,您仍然可以选择您喜欢的模式(纯原型继承、伪经典模式)。

有了ES5和新的可能性,如Object.create()Object.defineProperties()Object.freeze()等等,我们也有更多原型方法的保护和隐私的好方法。就我个人而言,我仍然更喜欢并喜欢伪经典的方式,使用闭包来做事情。

警告仍然可能是函数调用开销,这通常可以避免使用简单的原型继承。我们需要进行更多的调用才能将事情做好(如果事情变得更好的话)。尽管如此,闭包仍然被认为是有点贪婪的内存,如果我们草率地使用它们或者忘记清理这里和那里的引用,可能会导致泄漏。我现在没有这方面的任何参考资料,但我坚信最新的js引擎使用闭包并不会像很多一样慢很多。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8165181

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档