首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么prototype的构造函数要引用它自己?

为什么prototype的构造函数要引用它自己?
EN

Stack Overflow用户
提问于 2019-07-12 23:26:51
回答 2查看 258关注 0票数 3

来自Mozilla-javascript-docs

“每个对象都有一个私有属性,它保存着一个指向另一个称为原型的对象的链接。该原型对象有自己的原型,依此类推,直到达到一个以null作为原型的对象为止。根据定义,null没有原型,并充当这个原型链中的最后一个环节。”

第一个问题--我希望“每个对象都包含 prototype ",作者的意思是”每个函数对象“包含公共prototype属性,因为像var myObj = {}这样的对象没有任何公共原型。

请查看下面的concole屏幕截图-注意使用{} -创建的对象,公共原型属性(而不是私有__proto__)是如何不存在的。

第二个问题--当我查看简单函数的原型链时,在阅读了上面提到的文献之后,它似乎变得无限深入--但后来我意识到,原型的构造器实际上是指它自己。与Mozilla的文件中提到的不同,这里的原型链似乎没有以null作为根来结束。

我想这是为了支持基于原型的继承而设计的。但是如果能解释的话,我会很感激,,这个原型构造函数中的自引用是如何帮助实现的?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-07-12 23:33:56

如果您想查找下面描述的原型链:

每个对象都有一个私有属性,该属性包含指向另一个称为原型的对象的链接。这个原型对象有自己的原型,依此类推,直到达到一个以null作为原型的对象为止。根据定义,null没有原型,并充当这个原型链中的最后一个环节。

您应该查看__proto__属性(它将指向正在检查的对象的内部原型)。

在这里,您可以看到myFunctionObj的内部原型是Function.prototype,上一层__proto__将带您到Object.prototype,它没有__proto__ (原型链的末尾)。

prototype属性myFunctionObj引用实例化对象的内部原型(比如const obj = new myFunctionObj();,然后是obj.__proto__ === myFunctionObj.prototype),而不是myFunctionObj本身的内部原型。

通常,只有function具有一个.prototype属性,它们的.prototype将引用用new创建的实例的内部原型。普通对象没有.prototype属性(因为不能调用普通对象来实例化某物),但是仍然可以使用Object.getPrototypeOf (或.__proto__)访问普通对象(或任何东西)的内部原型:

代码语言:javascript
复制
const obj = {};
console.log(
  obj.__proto__ === Object.prototype,
  Object.getPrototypeOf(obj) === Object.prototype,
);

函数的.prototype.constructor实际上只是对函数的自引用。

代码语言:javascript
复制
function foo(){};
console.log(
  foo.prototype.constructor === foo
);

当您已经有了对构造函数的引用时,它不是很有用,但是当您有对实例的引用时,但是不知道它的构造函数--具有原型继承性,访问实例的.constructor属性将为您提供用于构造它的函数:

代码语言:javascript
复制
const bar = (() => {
  function Bar(){}
  const bar = new Bar();
  return bar;
})();

// now Bar is out of scope
// but you can still reference it because you have an instance:
const Bar = bar.constructor;
console.log(Bar);

票数 4
EN

Stack Overflow用户

发布于 2019-07-13 00:03:30

回答你的第二个问题:

原型对象有自己的原型..。

我认为,如果您实际查看了一个简单的多级别原型示例,以及它在实践中的工作方式,那么理解这个概念就容易得多:

代码语言:javascript
复制
function ClassA() {
  this.a = 1;
}
ClassA.prototype.getA = function(){
  return this.a;
};

function ClassB() {
  this.b = 2
}
ClassB.prototype = new ClassA();
ClassB.prototype.getB = function(){
  return this.b;
};

var b = new ClassB();
console.log(b.getA());
> 1
console.log(b.getB());
> 2

现在您将注意到,在定义类(函数)时,我们扩展(或添加)了一个prototype。但是,当我们查看类的一个实例(在我的示例中是b)时,没有prototype;它被称为@CertainPerformance (@CertainPerformance已经解释过)。因此,看看b的原型链,您将看到以下内容:

代码语言:javascript
复制
b.__proto__
> ClassA {a: 1, getB: ƒ}
b.__proto__.__proto__
> {getA: ƒ, constructor: ƒ}
b.__proto__.__proto__.__proto__
> {constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}
b.__proto__.__proto__.__proto__.__proto__
> null

因此,当您键入b.getB()时,JavaScript引擎首先查看b对象中的直接属性,而没有看到getB。然后它查看b.__proto__,并找到它,它就完成了。

对于b.getA(),它做同样的事情,但在第一个原型中找不到它。所以它继续b.__proto__.__proto__,并在那里找到它。

你看到的不一样。您首先要查看函数的prototype,并看到函数中有另一个名为constructor的函数。因为constructor也是一个函数,所以它里面有一个prototype。等等,直到永远。但是认为是构造函数的原型,不是原始函数/对象的原型链的一部分。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57015001

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档