试图理解JavaScript中原型和构造函数之间的区别 [英] Trying to understand the difference between prototype and constructor in JavaScript

查看:71
本文介绍了试图理解JavaScript中原型和构造函数之间的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是JavaScript的新手,为了理解这个概念我已经阅读了很多关于原型和构造函数的文章,但是无论我走到哪里,我都会感到困惑。

I'm new to JavaScript ,to understand this concept i have read many articles regarding prototype and constructors but where ever i go i'm left with confusion.

当人们同时谈论构造函数和原型时会产生混淆。

The confusion arises when people talk about constructor and prototype simultaneously.

在以下示例中

var employee = function Emp(name) {
    this.name = name;
}
var jack = new employee("Jack Dwain");

employee.constructor //gives Function()

employee.prototype // gives  Emp {}

employee.prototype.constructor //gives Emp(name)

jack.constructor //gives Emp(name)

jack.prototype //gives undefined




  1. 原型是JS实现继承的一种方式,因为 Emp(name)是基函数原型被引用到同一个函数本身。这是怎么回事?

  1. prototype is a way JS achieves inheritance,since Emp(name) is the base function prototype is referenced to the same function itself. Is that what happened?

以什么方式 employee.constructor 员工.prototype.constructor 有区别吗?

In what way employee.constructor and employee.prototype.constructor differ?

为什么 jack.prototype undefined ie如果它继承自函数 Emp(name)为什么它没有引用该函数?

Why was jack.prototype is undefined i.e If it is inheriting from the function Emp(name) why it didn't reference that function?

如果不在控制台中输入原型或构造函数或者prototype.constructor ......产生的内容,我怎样才能清楚地预测自己

How can I clearly predict myself without typing in the console what the prototype or the constructor or the prototype.constructor ......yields


推荐答案

如果你已经习惯了用其他OOP语言扩展对象,但我会尽力解释它们的用途和用途。我假设您熟悉其他OOP语言。如果我错了,请纠正我。

Its a pretty hard thing to wrap your mind around if you are used to the ease of extending objects in other OOP languages, but I'll do my best to explain the uses of those and what is what. I am going to assume you are familiar with other OOP languages. Correct me if I'm wrong.

所有函数都有原型Function()。它们继承了函数中的所有基本功能,如toString()和valueOf()。

All functions have the prototype Function(). They are inheriting all base functionality from Function like toString() and valueOf().

然后有一个构造函数。这就是你用来初始化一个对象的原因。

Then there is a constructor. That is what you use to initialize an object with.

p = new Foo();

所以在这种情况下我们有两件事。

So in this case we have two things.


  • 一个函数Foo 功能作为原型(Foo)

  • A 功能对象 Foo()作为构造函数(p)

  • A function Foo with Function as prototype(Foo)
  • A Function object with Foo() as constructor(p)

(跟我来?)

Foo()构造函数可以覆盖<$ c $的一些基本功能c>函数构造函数,但也保持原样并充分利用它。

The Foo() constructor can override some base functionality of the Function constructor, but also leave it as it is and make good use of it.

如果您熟悉OOP原则, prototype是基类,是当前类的构造函数。在OOP中,上面将是类Foo扩展函数

If you are familiar with OOP principles, The prototype is the base class, the constructor your current class. in OOP the above would be class Foo extends Function

您也可以使用整个原型设置开始继承构建器在共享功能的同时制作更复杂的对象。

You can also start inheritance with this entire setup of prototype and constructor making more complex objects as you go whilst sharing functionality.

例如:

// make a object initialiser extending Function. in oop `class Foo extends Function`

function Foo(bar) {
    this.baz = bar;
}
Foo.prototype.append = function(what) {
    this.baz += " " + what;
};
Foo.prototype.get() {
    return this.baz
}

现在让我们说我们想要不同的方法让baz离开那里。一个用于控制台日志记录,一个用于将其放在标题栏上。
我们可以对我们的类Foo做一件大事,但我们不这样做,因为我们需要用新类完成不同的事情,但是为不同的实现做了。他们唯一需要分享的是baz项目以及setter和getter。

Now lets say we want different ways to get baz out of there. one for console logging and one for putting it on the title bar. We could make a big thing about our class Foo, but we dont do that, because we need to do wholly different things with the new classes but are made for different implementations. The only thing they need to share are the baz item and the setters and getters.

因此我们需要扩展它以使用OOP术语。在OOp中,这将是期望的最终结果 class Title extends Foo(){} 。所以让我们来看看如何到达那里。

So we need to extend it to use an OOP term. in OOp this would be the desired end result class Title extends Foo(){}. So lets take a look how to get there.

function Title(what) {
    this.message = what;
}

此时Title函数如下所示:

At this point the Title function looks like this:


  • 原型功能

  • 构造函数标题

因此,为了使它扩展到Foo,我们需要更改原型。

So, to make it extends Foo we need to change the prototype.

Title.prototype = new Foo();




  • 原型Foo

  • 构造函数Foo

  • 这是通过针对原型初始化一个新的Foo()对象来完成的。
    现在它基本上是一个名为Title的Foo对象。这不是我们想要的,因为现在我们无法访问Title中的消息部分。
    我们可以通过将构造函数重置为Title来正确扩展Foo()

    This is done by initializing a new Foo() object against the prototype. Now its basically a Foo object called Title. That is not what we want because now we cant access the message part in Title. We can make it properly extend Foo() by resetting the constructor to Title

    Title.prototype.constructor = Title;
    




    • 原型Foo

    • 构造函数标题

    • 现在我们又遇到了一个问题。 Foo的构造函数没有初始化,所以我们最终得到一个未定义的 this.baz

      Now we are faced with one more problem. The constructor of Foo doesn't get initialized so we end up with an undefined this.baz

      要解决这个问题我们需要打电话给父母。在java中,您可以使用 super(vars),在php $ parent-> __ construct($ vars)

      To resolve that we need to call the parent. In java you would do that with super(vars), in php $parent->__construct($vars).

      在javascript中,我们必须修改Title类构造函数来调用父对象的构造函数。

      In javascript we have to modify the Title class constructor to call the constructor of the parent object.

      因此Title类构造函数将变为

      So the Title class constructor would become

      function Title(what) {
          Foo.call(this,what);
          this.message = what;
      }
      

      通过使用函数对象属性Foo继承,我们可以初始化Foo对象标题对象。

      By using the Function object property Foo inherited we can initialism the Foo object in the Title object.

      现在你有一个正确继承的对象。

      And now you have a properly inherited object.

      所以不要使用像<的关键字code> extend 与其他OOP语言一样,它使用 prototype 构造函数

      So instead of using a keyword like extend like other OOP languages it uses prototype and constructor.

      这篇关于试图理解JavaScript中原型和构造函数之间的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆