“每个对象都有一个私有属性,它保存着一个指向另一个称为原型的对象的链接。该原型对象有自己的原型,依此类推,直到达到一个以null作为原型的对象为止。根据定义,null没有原型,并充当这个原型链中的最后一个环节。”
第一个问题--我希望“每个对象都包含 prototype ",作者的意思是”每个函数对象“包含公共prototype属性,因为像var myObj = {}这样的对象没有任何公共原型。
请查看下面的concole屏幕截图-注意使用{} -创建的对象,公共原型属性(而不是私有__proto__)是如何不存在的。

第二个问题--当我查看简单函数的原型链时,在阅读了上面提到的文献之后,它似乎变得无限深入--但后来我意识到,原型的构造器实际上是指它自己。与Mozilla的文件中提到的不同,这里的原型链似乎没有以null作为根来结束。
我想这是为了支持基于原型的继承而设计的。但是如果能解释的话,我会很感激,,这个原型构造函数中的自引用是如何帮助实现的?

发布于 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__)访问普通对象(或任何东西)的内部原型:
const obj = {};
console.log(
obj.__proto__ === Object.prototype,
Object.getPrototypeOf(obj) === Object.prototype,
);
函数的.prototype.constructor实际上只是对函数的自引用。
function foo(){};
console.log(
foo.prototype.constructor === foo
);
当您已经有了对构造函数的引用时,它不是很有用,但是当您有对实例的引用时,但是不知道它的构造函数--具有原型继承性,访问实例的.constructor属性将为您提供用于构造它的函数:
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);
发布于 2019-07-13 00:03:30
回答你的第二个问题:
原型对象有自己的原型..。
我认为,如果您实际查看了一个简单的多级别原型示例,以及它在实践中的工作方式,那么理解这个概念就容易得多:
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的原型链,您将看到以下内容:
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。等等,直到永远。但是认为是构造函数的原型,不是原始函数/对象的原型链的一部分。
https://stackoverflow.com/questions/57015001
复制相似问题