Javascript “我如何分享?”;建造商;Crockford'中的功能;什么是新的构造函数模式?
我已经看了好几次视频了,我很难把它应用到现实世界的例子中 Crockford的新构造函数模式如下所示:Javascript “我如何分享?”;建造商;Crockford'中的功能;什么是新的构造函数模式?,javascript,inheritance,Javascript,Inheritance,我已经看了好几次视频了,我很难把它应用到现实世界的例子中 Crockford的新构造函数模式如下所示: function constructor(spec) { let {member} = spec, {other} = other_constructor(spec), method = function () { // accesses member, other, method, spec }; return Object
function constructor(spec) {
let {member} = spec,
{other} = other_constructor(spec),
method = function () {
// accesses member, other, method, spec
};
return Object.freeze({
method,
other,
});
}
其中,spec
是一个选项散列,结果对象公开关闭所有内部成员的方法。忽略解构(因为这在当今的JS中可以以很长的形式完成,)如何在现实世界的示例中应用此模式?
我目前有一个带有基类模块(model,id)
的库,其中model
是一些引导数据
// constructor, original flavor
function Module(model, id) {
this.id = id;
this.model = model;
}
然后,我有几种风格的模块,它们继承自这个父模块模块。在Crockford的模式下,我会将其作为“构造函数”:
我如何使用Crockford的模式(它似乎根本不使用继承,而是从多个源组成一个对象)来在多个不同风格的模块之间共享这个基本结构
我知道id
和model
将成为每个模块“构造函数”中的局部变量;我本质上是在问如何避免对使用Crockford模式的每种风格的模块重复model=spec.model
。Crockford所谓的“无类继承”实际上仍然是原型继承。实际上,有许多原型继承机制:
通过委托的原型遗传(又称差异遗传)
通过克隆的原型遗传(又称串联遗传)
差异原型遗传的一个例子
这是我传统上编写面向对象JavaScript代码的方式:
var飞机=defclass({
构造函数:函数(模型、速度){
this.model=模型;
速度=速度;
},
描述飞机:功能(){
警报(“该“+this.model+”以“+this.speed+”速度飞行”);
}
});
var FighterRaircraft=延伸(飞机{
建造师:功能(型号、速度、雷达){
飞机。呼叫(这个,型号,速度);
这个雷达=雷达;
},
DescripteBighterAircraft:函数(){
这个。描述飞机();
警报(“它有一个“+this.radar+”雷达信号。”);
}
});
var superFlanker=新战机(“超级侧翼机”,“马赫数2.25”,“低”);
superFlanker.describeFighterAircraft()代码>
函数类(原型){
var constructor=prototype.constructor;
constructor.prototype=原型;
返回构造函数;
}
函数扩展(构造函数、属性){
var prototype=Object.create(constructor.prototype);
for(属性中的变量名)prototype[name]=属性[name];
返回类(原型);
}
我也想在这里首先指出,在另一个问题上,我得到了一个我不理解的答案:(你不能。你在这里混合隐喻;第三个框根本不像第二个框。第三个框返回一个没有proto的空白对象,第二个框返回一个带有proto和2 owns的自定义对象。crockford的框返回一个带有n owns的非proto对象。这就像拥有prototype的简单性一样。)(一次获取一组方法,在这种情况下是从其他方法而不是从原型中获取),但没有像我们现在通过extend()那样迭代它们)工具。@dandavis我知道第二个框中的属性是公开的,而第三个框中的属性是私有的。如果我们完全忽略第二个框,您的答案是一样的吗?无法避免重复在每个模块样式中分配私有成员所需的设置代码?您可以将它们放在原型中,或者将它们包含在输出中销毁tommorow。或者今天通过迭代来扩展它们。最后,也许是最好的,您可以通过单独的基本“构造函数”和base.apply(this,arguments)/base.call(this)来定义“继承的”属性。这样,您可以获得大量的所有权、无迭代和广泛的兼容性。apply()w/参数很好,因为它与其他语言将init args传递给子构造函数的方式更为匹配。它们也可以在自己的方法中以词汇形式引用,crockford的方法使之更容易。@dandavis你能举个例子作为答案吗?我认识到这种对象关系既不是原型继承,也不是经典继承,我正在努力理解如何正确地使用它(甚至如何正确地思考它,我的困惑就是明证)不使用this
就可以使用混入模式吗?Crockford的方法避免了this
和new
,我也希望能够实现这一点。是的,这确实是可能的。我更新了我的答案来说明如何操作。但是,我不认为有任何理由这样做。使用this
有什么问题吗?一般来说,n除此之外,我经常使用它。但我目前的项目是广告软件,我想尝试遵循这些指导原则(同时尝试转向更实用的编程实践,以纠正同事的一些不良编程习惯)
// constructor, Crockford's Cool Ranch
function module(spec) {
let id = spec.id,
model = spec.model;
return Object.freeze({});
}