这张图再次表明,每个对象都有一个原型。构造函数 function Foo也有自己的__proto__,也就是function .prototype, 而它又通过__proto__属性再次引用 Object.prototype。因此,重复,Foo。原型只是一个显式 Foo的属性,引用b和c对象的原型。

var b = new Foo(20);
var c = new Foo(30);

__proto__和prototype之间有什么区别?

这一数据来自dmitrysoshnikov.com网站。

注:上述2010年的文章现在有第二版(2017年)。


当前回答

在声明函数时创建Prototype属性。

例如:

 function Person(dob){
    this.dob = dob
 }; 

的人。Prototype属性在声明上述函数后在内部创建。 可以向Person添加许多属性。由使用new Person()创建的Person实例共享的原型。

// adds a new method age to the Person.prototype Object.
Person.prototype.age = function(){return date-dob}; 

值得注意的是,Person。prototype默认是Object字面量(可以根据需要更改)。

使用new Person()创建的每个实例都有一个指向Person.prototype的__proto__属性。这是用于遍历查找特定对象的属性的链。

var person1 = new Person(somedate);
var person2 = new Person(somedate);

创建2个Person实例,这2个对象可以调用Person的age方法。原型作为人物1。年龄,person2.age。

在你的问题的上图中,你可以看到Foo是一个函数对象,因此它有一个__proto__链接到函数。prototype是Object的一个实例,并且有一个指向Object.prototype的__proto__链接。原型链接在这里以对象中的__proto__结束。原型指向null。

任何对象都可以访问其原型链中的所有属性,通过__proto__链接,从而形成原型继承的基础。

__proto__不是访问原型链的标准方法,标准但类似的方法是使用Object.getPrototypeOf(obj)。

下面的instanceof操作符代码提供了更好的理解:

当一个对象是一个类的实例时,更具体地说,如果Class,则返回true。prototype是在该对象的原型链中找到的,那么该对象就是该类的实例。

function instanceOf(Func){
  var obj = this;
  while(obj !== null){
    if(Object.getPrototypeOf(obj) === Func.prototype)
      return true;
    obj = Object.getPrototypeOf(obj);
  }
  return false;
}      

上面的方法可以调用为:instanceOf。调用(object, Class),如果object是Class的实例则返回true。

其他回答

这个问题有很多很好的答案,但为了概括和紧凑形式的答案,我添加了以下内容:

我们必须考虑的第一件事是,当JS发明的时候,计算机的内存非常低,所以如果我们需要一个进程来创建新的对象类型,我们必须考虑内存性能。

因此,他们在内存的独立部分,定位由特定对象类型创建的对象需要的方法,而不是每次我们创建一个新对象时,在对象之外存储方法。 因此,如果我们用JS的新特性重新定义新的运算符和构造函数概念,我们有以下步骤:

和空对象。(这将是对象类型实例化的最终结果)

let empty={}

我们已经知道,由于内存性能原因,对象类型实例所需的所有方法都位于构造函数的prototype属性上。(函数也是对象,所以它们可以有属性) 因此,我们将空对象的__protp__引用到这些方法存在的位置。 (我们将概念上作为构造函数使用的函数命名为构造函数。

empty.__proto__ = constructor.prototype

我们必须初始化对象类型值。 在JS中的函数与对象断开连接。使用点表示法或函数对象的bind call apply等方法,我们必须知道“函数的上下文是什么”。

let newFunc = constructor.bind(empty)

现在我们有了一个新函数,它有一个空对象作为这个context。 执行此函数后。空对象将被填充,如果定义的构造函数函数没有返回,类型object的实例化结果将是这个空对象(就好像这将是该过程的结果一样)

所以正如你所看到的,__proto__是一个对象的属性,它引用了其他对象(在JS中函数也是对象)原型对象属性,它由跨特定对象类型的实例使用的属性组成。

正如你可以从短语中猜到的那样,函数是对象,函数也有__proto__属性,因此它们可以引用其他对象的prototype属性。这就是原型继承的实现方式。

只有一个对象用于原型链接。该对象显然有一个名称和值:__proto__是它的名称,prototype是它的值。这是所有。

为了让它更容易理解,看看这篇文章顶部的图表(由dmitry soshnikov绘制的图表),你永远不会发现__proto__的值指向prototype以外的其他东西。

要点是:__proto__是引用原型对象的名称,prototype是实际的原型对象。

这就像是在说:

let x = {name: 'john'};

X是对象名称(指针),{name: 'john'}是实际对象(数据值)。

注意:这只是一个非常简单的提示,说明它们在较高的水平上是如何相互关联的。

更新:下面是一个简单具体的javascript示例,以便更好地说明:

let x = new String("testing") // Or any other javascript object you want to create

Object.getPrototypeOf(x) === x.__proto__; // true

这意味着当Object.getPrototypeOf(x)为我们获取x的实际值(这是它的原型)时,正是x的__proto__所指向的。因此__proto__确实指向x的原型。因此__proto__引用x (x的指针),而prototype是x的值(它的原型)。

我希望现在大家都明白了。

在JavaScript中,函数可以用作构造函数。这意味着我们可以使用new关键字从它们中创建对象。每个构造函数都带有一个内置对象。这个内置对象称为原型。构造函数的实例使用__proto__来访问其构造函数的prototype属性。

First we created a constructor: function Foo(){}. To be clear, Foo is just another function. But we can create an object from it with the new keyword. That's why we call it the constructor function Every function has a unique property which is called the prototype property. So, Constructor function Foo has a prototype property which points to its prototype, which is Foo.prototype (see image). Constructor functions are themselves a function which is an instance of a system constructor called the [[Function]] constructor. So we can say that function Foo is constructed by a [[Function]] constructor. So, __proto__ of our Foo function will point to the prototype of its constructor, which is Function.prototype. Function.prototype is itself is nothing but an object which is constructed from another system constructor called [[Object]]. So, [[Object]] is the constructor of Function.prototype. So, we can say Function.prototype is an instance of [[Object]]. So __proto__ of Function.prototype points to Object.prototype. Object.prototype is the last man standing in the prototype chain. I mean it has not been constructed. It's already there in the system. So its __proto__ points to null. Now we come to instances of Foo. When we create an instance using new Foo(), it creates a new object which is an instance of Foo. That means Foo is the constructor of these instances. Here we created two instances (x and y). __proto__ of x and y thus points to Foo.prototype.

__proto__是构造prototype和构造函数的基础,例如:function human(){}拥有prototype,该prototype在构造函数的新实例中通过__proto__共享。这里有更详细的阅读

简单来说:

> var a = 1
undefined
> a.__proto__
[Number: 0]
> Number.prototype
[Number: 0]
> Number.prototype === a.__proto__
true

这允许你在X类型的对象实例化之后将属性附加到X.prototype,并且它们仍然可以通过javascript引擎使用的__proto__引用访问这些新属性。