【问题标题】:Why cannot we call prototype functions?为什么我们不能调用原型函数?
【发布时间】:2016-07-17 10:58:45
【问题描述】:

最初我将函数对象分配给变量 Person。此时,Person 的 proto 指向 Function.prototype。然后我在 Person.prototype 中添加了一些函数。当我使用下面的 new 关键字调用 Person 构造函数并将其分配给 var test 时,据我所知,它将 test proto 设置为 Person.prototype。这个 Person.prototype 是一个对象,getName 映射到一个函数。因此,当我调用 test.getName() 时,它会在 test.prototype 中搜索该函数,如果在那里找不到,它将在其 proto 中搜索该函数,即 Person.prototype .

现在假设我创建另一个函数对象并将其分配给变量 Customer。它的 proto 将指向 Function.prototype。然后对于继承,我们应该做 Customer.prototype = new Person()。我很困惑为什么我应该这样做?是否将客户的 proto 设置为 Person.prototype。如果是这样,那么我不应该只写 Customer = new Person()。如果不是,那么 Customer proto 是否仍然指向 Function.prototype 还是我还缺少其他东西?

var Person = function(name) {
    this.name = name;
    console.log("Running the constructor of Person " + name)
}

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

var test = new Person("Yolo");
console.log(Person.prototype.getName.call(test))
console.log(test.getName());

var Customer = function(name) {
    this.name = name;
    console.log("Running the constructor of Customer " + name)
};

Customer.prototype = new Person();

提前致谢!

【问题讨论】:

  • 提示:var test = new Person()var Test.prototype = new Person() 有什么区别

标签: javascript class inheritance prototypal-inheritance


【解决方案1】:

这里有两个不同的概念:

  • __proto__ 是继承树中对象的父对象。
  • prototype 是一个函数的属性,它定义了 __proto__ 在用作构造函数时创建的任何对象的含义。

由于构造函数本身就是对象(函数对象),它们也位于继承树中,但该树与这些构造函数创建的对象的继承树无关。他们是两个不同的世界。

看看这段代码,它说明了客户对象的继承链:

var cust = new Customer('Jack');
console.log(cust.__proto__ === Customer.prototype); // true
console.log(cust.__proto__.__proto__ === Person.prototype); // true
console.log(cust.__proto__.__proto__.__proto__ === Object.prototype); // true

所以这里我们遵循cust 对象的原型链。这是与构造函数(函数)链完全不同的链:

console.log(Customer.__proto__ === Function.prototype); // true
console.log(Person.__proto__ === Function.prototype); // true
console.log(Object.__proto__ === Function.prototype); // true

这里没有什么不寻常的:它们是函数。此外,没有必要对此进行任何更改。如前所述,它与这些构造函数创建的对象的继承无关。

请注意,您永远不需要访问 __proto__ 属性。以上只是为了说明继承链。

【讨论】:

  • 终于到了启蒙时刻。非常感谢。
【解决方案2】:
Customer.___proto____ = Function.prototype 

它总是指向函数原型

Customer.prototype = new Person();

此语句将使 Customer.prototype._____proto_____ 指向 Person.Prototype

Customer._____proto_____ 永远不会只更改它的原型的 ____proto___ 通过继承进行的更改

【讨论】:

  • 这是一个不属于 javascript 标准的实现细节。始终使用.prototype
  • 这就是继承的工作原理。我只是在解释如何设置原始链接。显然这些原始链接没有在代码中使用
  • 但是当我这样做时, var test2 = new Customer();并调用test2.getName(),然后在test2.prototype中搜索函数,然后在test2 proto原型中,即Customer.prototype,它不会在那里找到它,所以它会搜索它在客户的 proto 中,即 Function.prototype。所以,这种方式永远不会达到真正的功能。
【解决方案3】:

我发现这张图片很有用。它清楚地显示了所有链接。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-28
    • 1970-01-01
    • 1970-01-01
    • 2018-06-30
    • 1970-01-01
    相关资源
    最近更新 更多