软件原型是什么意思_当我们谈论原型时,我们真正的意思是

软件原型是什么意思

by Hayden Betts

海登·贝茨(Hayden Betts)

当我们谈论原型时,我们真正的意思是 (What we really mean when we talk about prototypes)

Beginning JavaScript devs often mistakenly use one word — “prototype” — to refer to two different concepts. But what exactly is the difference between an “object’s prototype” and the “prototype property” of JavaScript functions?

刚开始JavaScript开发人员经常错误地使用一个词(“原型”)来指代两个不同的概念。 但是JavaScript函数的“对象原型”和“原型属性”之间到底有什么区别?

I thought I understood the concept of “prototypes” and prototypal inheritance in JavaScript. But I continued to find myself confused by references to “prototype” in code and in the documentation.

我以为我了解JavaScript中“原型”和原型继承的概念。 但是我仍然发现自己对代码和文档中对“原型”的引用感到困惑。

A lot of my confusion disappeared when I realized that in writing about JavaScript, people often casually use “prototype” to describe two distinct but related concepts.

当我意识到在编写JavaScript时,人们经常随意使用“原型”来 描述两个截然不同但相关的概念时,我的许多困惑消失了。

  1. An object’s prototype: The template object from which another JavaScript object inherits methods and properties. (MDN)

    对象的原型 :另一个JavaScript对象从其继承方法和属性的模板对象。 ( MDN )

  2. The non-enumerable prototypeproperty on JavaScript functions: A convenience to facilitate a design pattern (that design pattern to be explained in-depth shortly!).

    JavaScript函数上的不可枚举的 prototype属性便利设计模式的便利 (该设计模式将在短期内详细解释!)

    Not meaningful in itself until deliberately set to have some inheritance-related function. Most useful when used with constructor functions and factory functions (explanation coming!). Though all JS functions have the property by default. Contains a

    故意将其设置为具有一些与继承相关的功能之前,它本身并不有意义。 与构造函数和工厂函数一起使用时最有用(解释即将到来!)。 尽管所有JS函数默认都具有该属性。 包含一个

    constructor property, which refers to the original function.

    constructor属性,它引用原始函数。

For a long time, I was comfortable with definition 1, but not with definition 2.

很长时间以来,我对定义1感到满意,但对定义2却不满意。

为什么这种区别很重要? (Why does this distinction matter?)

Before I understood the difference between “an object’s prototype,” and the “non-enumerable prototypeproperty on functions,” I found myself confused by expressions like the following:

在我理解“对象的原型”和“函数的不可枚举的prototype属性”之间的区别之前,我发现自己被如下表达式所迷惑:

Array.prototype.slice.call([1, 2], 0, 1);// [ 1 ]

(sidebar: the first — but not the only — step to understanding the above is understanding call(). Here’s a quick refresher just in case!)

(侧边栏:了解上述内容的第一步(但不是唯一的步骤call()是理解call() 。为以防万一,这里是一个快速的更新 !)

A question I was not previously able to answer:

我以前无法回答的问题:

  • “Why are we looking for slice in the Array constructor’s prototype? Shouldn’t the Array constructor itself contain the slice method, and its prototype just contain some really low-level methods that all objects share?”

    “为什么我们要在Array构造函数的原型中寻找sliceArray构造函数本身不应该包含slice方法,而其原型仅包含所有对象共享的某些真正的低层方法吗?”

These questions were totally cleared up as I came to understand the design pattern that the prototype property on Array constructor functions exists to enable.

当我了解Array构造函数上的prototype属性可以启用的设计模式时,这些问题已完全清除。

理解JS Functions上的prototype属性的3个步骤 (3 steps to understanding the prototype property on JS Functions)

In order to understand theprototype property on JS functions, you need to understand the design pattern it enables. I will build up an understanding of this pattern by first working through two less preferable alternatives.

为了了解JS函数的prototype属性,您需要了解其启用的设计模式。 我将通过首先研究两个较不受欢迎的替代方案来建立对这种模式的理解。

实现1:功能类模式 (Implementation 1: The Functional Class Pattern)

Imagine we want to create a game in which we interact with dogs. We want to quickly create many dogs that have access to common methods like pet and giveTreat.

想象我们要创建一个与狗互动的游戏。 我们希望快速创建许多可以使用诸如petGiveTreat之类的通用方法的狗。

We could start to implement our game using the Functional Class Pattern as follows:

我们可以开始使用Functional Class Pattern来实现我们的游戏,如下所示:

Let’s clean this up a bit by storing those methods in their own object. Then extend them inside of the createDog factory function.

让我们通过将这些方法存储在自己的对象中来对其进行清理。 然后将它们扩展到createDog工厂函数中。

Though this implementation is easy to reason about, and conveniently reflects class-based-inheritance in other languages, it has at least one major issue: we are copying our method definitions to every dog object we create using our factory functioncreateDog.

尽管此实现很容易推论,并方便地反映了其他语言中基于类的继承,但它至少存在一个主要问题:我们正在将方法定义复制到使用工厂函数createDog创建的每个dog对象。

This takes up more memory than necessary and is not DRY. Wouldn’t it be nice if instead of copying method definitions to zeus and casey, we could define our methods in one place. Then have zeus and casey point to that place?

这将占用不必要的更多内存,并且不是DRY 。 如果不是将方法定义复制到zeuscasey ,而是可以在一个地方定义方法,那不是很好。 然后让zeuscasey指向那个地方吗?

重构1:实现“原型类”设计模式 (Refactor 1: Implementing a “Prototypal Class” Design Pattern)

Prototypal inheritance gives us exactly what we asked for above. It will allow us to define our methods in one prototype object. Then have zeus, casey, and infinitely more objects like them point to that prototype. zeus and casey will then have access to all of the methods and properties of that prototype by reference.

原型继承完全可以满足我们的要求。 这将使我们能够在一个原型对象中定义我们的方法。 然后让zeuscasey和更多像它们那样的对象指向该原型。 然后, zeuscasey可以通过引用访问该原型的所有方法和属性。

NOTE: For the less familiar, there are many excellent tutorials out there that explain the concept of prototypal inheritance in much more depth than I do here!

注意:对于不太熟悉的人,有很多 很棒的 教程 ,它们比我在这里更深入地解释了原型继承的概念!

A NOTE ON MY EXAMPLES BELOW: For pedagogical clarity, I use factory functions named createDog, rather than ES5 constructor functions, to implement a prototypal model of inheritance. I choose to use factory functions because they have less ‘magic going on under the hood’ and ‘syntactic sugar’ than ES5 constructors. Hopefully, this makes it easier to stay focused on the issue at hand!

以下是我的示例的注释:为了教学上的清晰起见,我使用名为 createDog 工厂函数 (而不是ES5 构造函数 )来实现继承的原型模型 我之所以选择使用工厂函数,是因为与ES5构造函数相比,工厂函数的“幕后魔术”和“语法糖”更少。 希望这可以使您更轻松地关注当前的问题!

Great! Now the objects corresponding to zeus and casey do not themselves contain copies of the methods giveTreat and pet. Instead, the objects look up those methods in their prototypemethodsForShowingAffection.

大! 现在,与zeuscasey相对应的对象本身并不包含giveTreatpet方法的副本。 相反,对象在其原型methodsForShowingAffection查找这些方法。

But wouldn’t it be nice if methodsForShowingAffection were encapsulated in the createDog factory function? Doing so would make it clear that these methods are intended for use only with that function. So a simple refactor leaves us with:

但是,如果将methodsForShowingAffection封装在createDog工厂函数中会不会很好? 这样做可以清楚地表明这些方法仅适用于该功能。 因此,一个简单的重构使我们拥有:

重构2:原型继承+工厂函数上的prototype属性 (Refactor 2: Prototypal Inheritance + the prototype property on factory functions)

Great! But isn’t methodsForShowingAffection and long and strange name for a property? Why not use something more generic and predictable? It turns out that the designers of Javascript provide us with just what we are looking for. A built-in prototype property on every function, including one on our factory functioncreateDog.

大! 但是methodsForShowingAffection和属性的长而奇怪的名称不是吗? 为什么不使用更通用且可预测的东西? 事实证明,JavaScript的设计人员为我们提供了我们所寻找的东西。 每个函数都有一个内置的prototype属性,包括我们工厂函数createDog

Note that there is nothing special about this prototype property. As shown above, we could achieve exactly the same result by setting the prototype of createDog to a separate object called methodsForShowingAffection. The normalcy of theprototype property on functions in Javascript suggests its intended use-case: a convenience intended to facilitate a common design pattern. Nothing more, nothing less.

请注意,此prototype属性没有什么特别的。 如上所示,通过将createDog的原型设置为一个单独的对象,称为methodsForShowingAffection ,我们可以获得完全相同的结果。 Javascript函数中prototype属性的常态性表明了其预期的用例:旨在促进通用设计模式的便利。 仅此而已。

Further Reading:

进一步阅读:

For more about the prototype property on functions in JavaScript, see ‘the function prototype’ section in this blogpost by Sebastian Porto.

有关JavaScript函数的prototype属性的更多信息,请参见Sebastian Porto博客中的“函数原型”部分。

The MDN article on prototypes.

有关原型的MDN 文章

翻译自: https://www.freecodecamp.org/news/what-we-really-mean-when-we-talk-about-prototypes-165586f29fa9/

软件原型是什么意思

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值