javascript 构造-JavaScript 中的鞋工厂方法、构造函数和类

2023-08-23 0 8,589 百度已收录

✦✦✦✦✦✦✦✦

在ES6出现之前,人们常常担心JavaScript中鞋厂模式和构造函数模式的区别。 ES6 中引入了 class 关键字,许多人认为它解决了构造函数模式的许多问题。 事实上,问题并没有得到解决。 让我们看一下鞋工厂模式、构造函数模式和类之间的一些重要区别。

首先,让我们看一下这三种形式的示例:

(上下滑动查看代码)

//班级

类ClassCar{

驾驶(){

console.log('Vroom!');

constcar1 = newClassCar();

console.log(car1.drive());

//构造函数(构造函数模式)

函数构造函数Car(){}

ConstructorCar.prototype.drive=function(){

console.log('Vroom!');

};

constcar2 = newConstructorCar();

console.log(car2.drive());

//工厂(鞋厂模式)

常量原型={

驾驶(){

console.log('Vroom!');

};

函数工厂Car(){

returnObject.create(原型);

javascript 构造-JavaScript 中的鞋工厂方法、构造函数和类

constcar3 = 工厂汽车();

console.log(car3.drive());

该方法将方法存储在共享原型中,然后可以通过构造函数的闭包选择性地支持私有数据。 换句话说,它们几乎具有相同的特性,因此通常可以互换使用。

在 JavaScript 中,任何函数都可以返回一个新对象。 当这个函数不是构造函数或类时,它被称为鞋工厂函数。

ES6中的类虽然是构造函数的语法糖,但它具有构造函数的所有优点和缺点:

类Foo{}

console.log(typeofFoo);//函数

1 构造函数和类的优点

2 构造函数和类的缺点

1.需要新的

在 ES6 之前,缺少 new 是一个常见的错误。 为了对抗它,许多人使用以下形式:

函数Foo(){

if(!(thisinstanceofFoo)){returnnewFoo();}

在ES6(ES2015)中,如果尝试在不使用new的情况下调用类构造函数,将会抛出错误。 只有用鞋厂模式包装类才可以避免必须使用new。 对于 JavaScript 的未来版本,有人建议在忽略 new 时自定义类构造函数的行为。 然而,这些方法仍然减少了使用该类的开销(这也意味着更少的人会使用它)。

2、调用API时,实例化的细节被泄露(从new的角度展开)

调用构造函数的方法与实现构造函数的方法紧密耦合。 当你需要它具有鞋厂的灵活性时,这将是一个巨大的改变。 将类构建到鞋工厂中是很常见的,甚至在 Martin Fowler、Kent Beck、John Brant、William Opdyke 和 Don Roberts 的《重构:改进现有代码的设计》中都有所写。

3. 构造函数模式违反了开放/封闭原则

由于新的要求,构造函数违反了开放/封闭原则:即API应该对扩展开放,对添加关闭。

我的观点是,既然从类到鞋厂的建设如此普遍,那么在不造成任何破损的情况下进行扩建应该成为所有建设者的一个标准。

如果你打开了一个构造函数或者类,并且用户使用了这个构造函数,之后如果你需要降低这个方法的灵活性,(比如以对象池的形式来实现,或者跨执行来实现) contexts的实例化,或者使用代替原型来拥有更多的继承灵活性),都需要用户同时构建。

不幸的是,在 JavaScript 中javascript 构造,从构造函数或类切换到鞋工厂需要进行巨大的改变:

(上下滑动查看代码)

//原始实现:

//原始实现:

//汽车类{

//驾驶(){

//console.log('Vroom!');

//}

//}

//constAutoMaker={汽车};

//工厂重构实现:

//鞋厂函数构建实现:

常量AutoMaker = {

汽车(捆绑){

returnObject.create(this.bundle[bundle]);

},

捆: {

优质的: {

驾驶(){

console.log('Vrooom!');

},

获取选项:函数(){

return['皮革','木材','珍珠'];

};

//重构工厂期望:

//构造后方法希望这样调用

javascript 构造-JavaScript 中的鞋工厂方法、构造函数和类

constnewCar=AutoMaker. 汽车('高级');

newCar.drive();//'Vrooom!'

//但是由于它是一个库,所以调用者很多

//在野外仍然这样做:

// 由于这是一个库,许多用户仍在使用

constoldCar = newAutoMaker.Car();

//这当然会抛出:

//TypeError: 无法读取属性'未定义'

//undefinedatnewAutoMaker.Car

//在这种情况下,它会抛出:

//TypeError: 无法读取属性'未定义'

//undefinedatnewAutoMaker.Car

在前面的例子中javascript 构造,我们首先提供了一个类,然后想要提供不同类型的车辆。 因此,鞋厂方法针对不同的车辆类型使用了不同的原型。 我之前使用过这些技术来存储不同的播放器套接字,然后根据要处理的文件格式选择适当的原型。

4.使用构造函数会导致instanceof产生误导

与鞋工厂方法相比,构造函数带来的巨大变化是instanceof的性能。 人们有时使用 instanceof 进行类型检查。 尽管这些方法经常存在问题,但我建议您避免使用instanceof。

instanceof 会说谎。

(上下滑动查看代码)

//原型身份检查实例。

//NOTatypecheck。

//instanceof是原型检测

//代替类型检查

//这意味着它位于跨执行上下文,

//当原型被动态重新分配时,

javascript 构造-JavaScript 中的鞋工厂方法、构造函数和类

//当年轻人排成这样令人困惑的情况时

//属性:

函数 foo(){}

constbar={a:'a'};

foo.prototype=bar;

//Isbaran 实例关闭 oo? 没有!

console.log(barinstanceofoo);//假

//好吧...因为 bar 不是 oo 的实例,

//baz 绝对不应该是 oo 的 bean 实例,对吗?

constbaz = 对象。 创建(栏);

//...错误的。

console.log(bazinstanceofoo);//true.oops.

instanceof 类型检测方法与强类型语言不同。 它将检查 [[Prototype]] 对象和该对象的 Constructor.prototype 属性之间的一致性。

例如,当执行上下文发生变化时,instanceof就会失败。 当Constructor.prototype改变时,instanceof也将无法正常工作。

当你从一个类或构造函数开始(这将返回指向Constructor.prototype的this),然后寻找另一个对象(不指向Constructor.prototype),这也会导致instanceof失败。 当将构造函数转换为鞋厂函数时,会出现这些情况。

简而言之,instanceof 是将构造函数转换为鞋厂函数时发生的另一个巨大变化。

3 使用类的优点

方便、自成一体的句型。

在 JavaScript 中使用类的单一规范形式。 在ES6之前,它的实现方法出现在一些流行的库中。

对于那些具有基于类的语言背景的人来说,它将变得越来越熟悉。

4 使用类的缺点

除了构造函数的缺点之外,还有:

用户可能会尝试使用extends关键字创建导致问题的多级类。

javascript 构造-JavaScript 中的鞋工厂方法、构造函数和类

多级类会导致面向对象编程中许多众所周知的问题,包括脆弱泛型问题、草莓猴雨林问题、重复必然性问题等等。 不幸的是,类可以用来自然地扩展,就像球可以用来投掷,桌子可以用来坐一样。 要了解更多信息,请阅读“JavaScript 的两大支柱:PrototypalOO”和“Inside theDevTeamDeathSpiral”。

值得强调的是,构造函数和鞋工厂函数都有可能产生有问题的层次继承,但通过 extends 关键字,类提供了函数可见性,使您可以做错误的事情。 换句话说,它鼓励您思考僵化且通常错误的“是”关系,而不是日益灵活的“有”或“可以做”组件关系。

功能可见性是您执行某些操作的机会。 例如,旋钮可用于旋转,杠杆可用于拉动,按钮可用于按下,等等。

采用鞋厂方式的5大优势

鞋工厂方法比构造函数或类更灵活,并且它不会诱使人们使用扩展来构建太深的继承层次结构。 您可以通过多种方式继承鞋厂功能。 特别是,如果您想了解联合鞋厂方法,请参阅邮票规范。

1. 返回任何对象与使用任何原型

例如,您可以通过同一个 API 轻松创建多种类型的对象,例如可以实例化不同类型视频播放器的媒体播放器,或者可以触发 DOM 事件或 websocket 事件的库。

鞋工厂函数可以跨行上下文实例化对象,充分利用对象池,但允许更灵活的原型模型继承。

2. 无需担心构建

您永远不需要从鞋厂切换到建筑商,因此建筑永远不会成为问题。

3.没有新的

是否使用new只有一种选择,那就是不使用。 (这会导致行为变得很糟糕,原因请参阅下一点)。

4.规范这种行为

它的行为与通常相同,因此您可以使用它来获取其父对象。 例如,在player.create()中,this指的是player,就像在其他调用中一样。 call() 和 apply() 也会指向这一点。

5. 不会出现误导性的实例问题

6.有些人喜欢myFoo=createFoo()这样的写法

6 鞋厂方式的缺点

不会创建指向 Factory.prototype 的链接 - 但这似乎是一件好事,因为从那时起您就不会得到误导性的 instanceof 。 相反,instanceof 仍然会失败。 有关详细信息,请参阅鞋厂方法的优点。

这不会以鞋厂方式指向新对象。 有关详细信息,请参阅鞋厂方法的优点。

在微优化基准测试中,鞋工厂方法可能比构造函数模式稍慢。 如果这对您有影响,则不必在您的程序上下文中测试它。

推理

在我看来,类有一种简单的语法方法,但这并不能弥补它引诱 Martha 的用户在类继承中做错误事情的事实。 这对未来来说也是有风险的,因为你可能想将其升级为鞋工厂函数,并且由于 new 关键字,你的所有调用都将与构造函数紧密耦合,因此从类迁移到鞋工厂将是一个巨大的变化。

您可能认为您可以只构建调用部分,但在大型团队中,或者如果您使用的类是公共 API 的一部分,您可能会破坏不受您控制的代码。 换句话说,不能假设仅构建调用部分始终是一种选择。

鞋厂方法的有趣之处在于,除了规模更大、更灵活之外,它还是鼓励整个团队和所有 API 用户使用简单、灵活和安全模式的最简单方法。

✦✦✦✦✦✦✦✦

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

悟空资源网 javascript javascript 构造-JavaScript 中的鞋工厂方法、构造函数和类 https://www.wkzy.net/game/146204.html

常见问题

相关文章

官方客服团队

为您解决烦忧 - 24小时在线 专业服务