gpt4 book ai didi

javascript - 这种寄生遗传模式好不好?

转载 作者:行者123 更新时间:2023-11-29 22:28:27 27 4
gpt4 key购买 nike

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

对于涉及原型(prototype)的对象创建模式,我遇到的主要问题是无法绕过对 this 的需求。主要原因是任何超出非常原始范围的对象,例如通过异步 API 调用填充自身的对象,this 由于范围的变化而崩溃。

因此,我使用原型(prototype)对象创建来创建我从一开始就了解的所有对象。

但对于需要执行 API 调用等操作以保持自身更新的对象,我完全跳过原型(prototype)并直接使用对象字面量。

当我觉得需要扩展这些对象之一时,我使用了寄生继承:

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 中的代码,这种模式会带来挑战。我不能这样做:

ROOT.Child = function () {
var self = ROOT.Parent();

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

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

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.

好的,所以我应该问一个问题。我在这里完全偏离目标还是我在做什么?有哪些明显的缺点?

最佳答案

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

这是一个很好的模式,很好地使用闭包来保持私有(private)和 protected 。但是,仍然取决于您喜欢哪种模式(普通原型(prototype)继承、伪经典)。

使用 ES5 和新的可能性,如 Object.create()Object.defineProperties()Object.freeze() 来命名一个很少,我们也有很好的方法通过更原型(prototype)的方法来保护和隐私。就个人而言,我仍然更喜欢伪经典方式,使用闭包来做事。

警告仍然可能是函数调用开销,您通常可以避免使用普通原型(prototype)继承。我们需要打更多的电话才能把事情做好(如果事情发展了)。尽管如此,闭包仍被认为有点贪婪内存,如果我们草率地使用它们或忘记清理各处的引用,则可能成为泄漏的原因。我现在对此没有任何引用,但我坚信最新的 js 引擎使用闭包不会慢很多。

关于javascript - 这种寄生遗传模式好不好?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8165181/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com