如何用JavaScript制作原型的原型?
我正在尝试用Javascript创建一个原型的原型。我希望我的原型继承某些方法,而不必将它们添加到每个方法中,而不是使用从零开始构建的普通原型来实现以下功能 因此,与此代码不同,我在原型中添加了一个方法如何用JavaScript制作原型的原型?,javascript,prototype,Javascript,Prototype,我正在尝试用Javascript创建一个原型的原型。我希望我的原型继承某些方法,而不必将它们添加到每个方法中,而不是使用从零开始构建的普通原型来实现以下功能 因此,与此代码不同,我在原型中添加了一个方法logDependencies(),以检查Car实例中是否存在Dependency: function Dependency(data) { this.data = data; } function Car(color) { this.color = new Dependency
logDependencies()
,以检查Car
实例中是否存在Dependency
:
function Dependency(data) {
this.data = data;
}
function Car(color) {
this.color = new Dependency(color);
this.logDependencies = function () {
for (var key in this)
if (this.hasOwnProperty(key))
if (this[key] instanceof Dependency)
console.log("Dependency: " + key);
};
}
var lamborghini = new Car("red");
lamborghini.logDependencies();
我希望我的所有原型都继承函数logDependencies()
,而无需手动添加它
我该怎么做?
更新: 对于那些对我的措辞感到困惑的人: 我正在尝试创建一个原型函数,该函数允许我创建继承某些属性和方法的原型,并将它们传递给继承链。 道格拉斯·克罗克福德(Douglas Crockford)(强调我自己)的相关文章: 我的旅程是曲折的,因为JavaScript本身在原型性质上存在冲突。在原型系统中,对象从对象继承。然而,JavaScript缺少执行该操作的操作符。相反,它有一个新的操作符,
new f()
生成一个从f.prototype
继承的新对象
这种间接方式的目的是让受过经典训练的程序员更熟悉这种语言,但没有做到这一点,正如我们从Java程序员对JavaScript的极低评价中所看到的那样。JavaScript的构造器模式对经典的人群没有吸引力。它还模糊了JavaScript的真正原型性质。因此,很少有程序员知道如何有效地使用该语言
幸运的是,创建一个实现真正原型继承的操作符很容易。这是我工具包中的一个标准功能,我强烈建议您使用它
function object(o) {
function F() {}
F.prototype = o;
return new F();
}
对象函数解开JavaScript的构造函数模式,实现真正的原型继承。它将旧对象作为参数,并返回从旧对象继承的空新对象。如果我们试图从新对象获取一个成员,但它缺少该键,那么旧对象将提供该成员。对象从对象继承。还有什么比这更面向对象的呢
因此,您不需要创建类,而是创建原型对象,然后使用object函数创建新实例。对象在JavaScript中是可变的,因此我们可以增加新实例,为它们提供新的字段和方法。然后,这些可以作为甚至更新对象的原型。我们不需要类来创建许多类似的对象
为了方便起见,我们可以创建函数来为我们调用对象函数,并提供其他定制,例如使用特权函数扩充新对象我有时称这些生成器函数为。如果我们有一个maker函数调用另一个maker函数而不是调用对象函数,那么我们就有一个寄生继承模式。
我发现,通过使用这些工具,再加上JavaScript的lambda和对象准文本,我可以编写结构良好的大型、复杂且高效的程序。到目前为止,经典对象模型是最流行的,但我认为原型对象模型更有能力,并且提供了更多的表达能力
听起来你只是想增加汽车的原型?或者你想把它添加到你所创造的一切的原型中(不明智) 下面是让一个优秀的JavaScript开发人员生气的原因:
Object.prototype.logDependencies = function(){ return "I just don't give a..."; }
var anything = new Object();
anything.logDependencies(); // I just don't give a...
为了澄清这一点,您在文章中解释了上述情况不好的原因:
对象函数的问题是它是全局的,而且是全局的
这显然是有问题的。Object.prototype的问题。[somethod]
是因为它让不称职的程序出错,而且它可以产生
重写[someMethod]时出现意外结果
读了你的评论后,我觉得你好像在追求某种魔杖。也许您来自Java世界?还是动作脚本3世界?其中类型更强,继承更经典。JavaScript是一种非常灵活的语言,我们都设法以某种形式从中挤出其他语言的一些方面。但是,如果您要求JavaScript执行某种基于类的继承系统,而不需要调用一些方法和到处声明一些变量,那么您就会失望
我建议您阅读Douglas Crockford的书,他在书中解释了JavaScript的原型系统是多么有用,并暗示了如何利用经典的继承特性。如果您想要继承的东西,其中
car
具有父类
原型的所有功能,那么您可以使用:
car.prototype = Object.create(parent.prototype);
基本上,
Object.create(obj)
返回一个新对象,其原型设置为obj
。car
的所有实例的原型都设置为car.prototype
。因此,他们可以通过原型链访问父级功能。您可以随时使用mixin来共享功能。例如:
var mixinLogger = (function () {
return function (that) {
that.logDependencies = logDependencies;
return that;
};
function logDependencies() {
for (var key in this)
if (this.hasOwnProperty(key) &&
this[key] instanceof Dependency)
console.log("Dependency: " + key);
}
}());
您可以按如下方式使用它:
function Dependency(data) {
this.data = data;
}
function Car(color) {
this.color = new Dependency(color);
}
mixinLogger(Car.prototype);
mixinA(mixinB(Something.prototype));
使用mixin的优点是它们是可组合的。例如,如果您有两个mixin(mixinA
和mixinB
),则可以按如下方式链接它们:
function Dependency(data) {
this.data = data;
}
function Car(color) {
this.color = new Dependency(color);
}
mixinLogger(Car.prototype);
mixinA(mixinB(Something.prototype));
您甚至可以创建一个新的mixin,它由以下两部分组成:
function compose() {
var fs = arguments;
var length = fs.length;
return function (x) {
var index = length;
while (index > 0) x = fs[--index](x);
return x;
};
}
var mixinC = compose(mixinA, mixinB);
事实上,您可以根据自己的意愿组合任意多个mixin,以创建新的mixin
如果您想了解更多信息,那么您应该阅读博客文章“。如果
依赖项
被用作构造函数,那么为什么它有一个返回语句?您是说希望logDependencies全局可用,还是说希望logDependencies可用