【问题标题】:Why are the properties and methods created in a function not shown in the constructor property of the prototype of that function?为什么函数中创建的属性和方法没有显示在该函数原型的构造函数属性中?
【发布时间】:2021-07-21 12:50:30
【问题描述】:
function protoFunc(name) {
    this.name;
    this.getName = function () {
        return this.name;
    }
}

在这里我创建了一个构造函数。现在,这个构造函数有一个原型属性,其中包含一个对象,您可以在该对象上定义要继承的成员,即方法和属性。其中一个成员是“构造函数”属性,它指向函数本身。

那么,为什么在prototype属性内部和constructor属性内部都看不到我刚刚在函数内部创建的方法和属性?

我只看到这个:

arguments: null
caller: null
length: 1
name: "protoFunc"
prototype:
    constructor: ƒ protoFunc(name)
    __proto__: Object
__proto__: ƒ ()

我刚刚创建的方法在哪里?

【问题讨论】:

  • 因为这些没有被添加到原型中。它们直接添加到每个实例中。
  • @VLAZ 好的,我可以再问你 3 个问题吗?为什么实例没有prototype 属性?该属性是否仅对constructors 可用?另外,我知道,当我调用没有new 关键字的函数时,我将其作为函数调用,而不是构造函数,因此如果它只有属性和方法,它会返回“未定义”,但为什么当我这样做时对于像String()Number() 这样的内置对象也是如此,为什么我会得到我在括号中添加的值?为什么它不再返回undefined?最后,默认的Object 是一个类,还是只是一个函数构造函数?
  • prototype 仅适用于构造函数。构造函数将使用它来制作 more 项。所有构造的项目都获得构造函数的原型,并通过它访问方法和属性。实例可能有 __proto__ 属性,但它(有点)已被弃用。可以使用Object.getPrototypeOf(obj)获取实例的原型链。
  • NumberString 的实现方式不同。您可以实现类似的行为 - 有一些方法可以检查是否使用 new 调用了函数,例如 new.target,然后您可以在未使用 new 调用时提供不同的 return
  • 至于对象。你当然可以称它为一个类。它也是一个构造函数,但有点特殊,因为它在规范中并且通常是主机提供的。这意味着如果你想完全模仿它的功能,你需要阅读规范并做同样的事情。但它所做的动作并没有什么特别之处——它所做的任何事情都可以在 JS 中实现。

标签: javascript prototype


【解决方案1】:

您编写的代码不会向原型添加任何内容。相反,它为每个实例添加属性。换句话说,如果有人打电话

const a = new protoFunc('bob');

然后a 将直接在其上具有.name.getName 属性。它不会通过原型链获得这些,并且在您调用 new 之前它们不存在。

如果您希望getName 在原型链上,您需要将您的代码更改为:

function protoFunc(name) {
    this.name = name;
}

protoFunc.prototype.getName = function () {
    return this.name;
}

注意:我将 protoFunc 中 this.name 的行更改为 this.name = name,因为这可能是您的本意。

【讨论】:

  • 那么,constructor 属性只显示函数的方法和属性,但this.namethis.getName() 不在函数上,它们是..什么?我知道它们将被添加到每个新实例上,但它们不仍然存在于constructor 上吗?或者你是说,它们存在于函数的body 上,但它们不是方法和属性,这就是它们没有显示的原因?
  • 我可以再问你 3 个问题吗?为什么实例没有prototype 属性?该属性是否仅对构造函数可用?另外,我知道,当我调用没有 new 关键字的函数时,我将其作为函数调用,而不是构造函数,因此如果它只有属性和方法,它会返回 undefined,但是为什么当我这样做时对于像`String()`或Number()这样的内置对象也是如此,为什么我会得到我在括号中添加的值?为什么它不再返回undefined?最后,默认的Object 是一个类,还是只是一个函数构造函数?
  • the this.name and this.getName() are not on the function, they are .. what? 在您调用new protoFunc 之前,它们只是尚未运行的代码行。运行它们后,它们会将属性添加到this,这是对象的实例(即我的代码中的a)。
  • Why do instances not have the prototype property? 因为他们不需要它。 prototype 是构造函数需要的东西。当您调用new 时,新运算符将在函数上查找prototype 属性并在创建新对象时使用该属性。在那之后,使用与.prototype 不同的机制。如果您想找出实例的原型,请使用Object.getPrototypeOf()
  • why when I do the same for build-in objects like String() or Number(), why do I get the value that I added in the parentheses? 因为这就是语言定义字符串和数字函数的方式。我不确定我还能添加什么。 Lastly, is the default Object a Class, or just a function constructor again? 没有真正的区别。类(大部分)只是带有原型的构造函数的语法糖。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-07
  • 2015-03-24
  • 2019-07-11
  • 1970-01-01
  • 2010-10-07
  • 1970-01-01
相关资源
最近更新 更多