这张图再次表明,每个对象都有一个原型。构造函数 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年)。


当前回答

简单来说:

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

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

其他回答

prototype是Function对象的一个属性。它是由该函数构造的对象的原型。

__proto__是一个对象的内部属性,指向它的原型。当前标准提供了等效的Object.getPrototypeOf(obj)方法,尽管事实上的标准__proto__更快。

你可以通过比较函数的原型和对象的__proto__链来找到instanceof关系,你也可以通过改变prototype来打破这些关系。

function Point(x, y) {
    this.x = x;
    this.y = y;
}

var myPoint = new Point();

// the following are all true
myPoint.__proto__ == Point.prototype
myPoint.__proto__.__proto__ == Object.prototype
myPoint instanceof Point;
myPoint instanceof Object;

这里Point是一个构造函数,它程序化地构建一个对象(数据结构)。myPoint是一个由Point()构造的对象,所以Point。原型保存到myPoint。解析:句意:在那个时候。

在声明函数时创建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。

对于静态方法使用__proto__怎么样?

function Foo(name){
  this.name = name
  Foo.__proto__.collection.push(this)
  Foo.__proto__.count++

}

Foo.__proto__.count=0
Foo.__proto__.collection=[]

var bar = new Foo('bar')
var baz = new Foo('baz')

Foo.count;//2
Foo.collection // [{...}, {...}]
bar.count // undefined

我知道,我迟到了,但让我试着简化一下。

假设有一个函数

    function Foo(message){

         this.message = message ; 
     };

     console.log(Foo.prototype);

Foo函数将有一个原型对象链接。所以,无论何时我们在JavaScript中创建一个函数,它总是有一个原型对象链接到它。

现在让我们继续使用函数Foo创建两个对象。

    var a = new Foo("a");
    var b = new Foo("b");
    console.log(a.message);
    console.log(b.message);

现在我们有两个对象,对象a和对象b。它们都被创建了 使用构造函数Foo。记住,构造函数在这里只是一个词。 对象a和b都有message属性的副本。 这两个对象a和b链接到构造函数Foo的原型对象。 在对象a和b上,我们可以在所有浏览器中使用__proto__属性访问Foo prototype,在IE中我们可以使用Object.getPrototypeOf(a)或Object.getPrototypeOf(b)

现在,Foo。Prototype, a.__proto__和b.__proto__都表示同一个对象。

    b.__proto__ === Object.getPrototypeOf(a);
    a.__proto__ ===  Foo.prototype;
    a.constructor.prototype  === a.__proto__;

所有这些都将返回true。

如我们所知,在JavaScript中属性可以动态添加。我们可以向对象添加属性

    Foo.prototype.Greet = function(){

         console.log(this.message);
    }
    a.Greet();//a
    b.Greet();//b
    a.constructor.prototype.Greet();//undefined 

如你所见,我们在Foo中添加了Greet()方法。但它可以在a和b或任何其他使用Foo构造的对象中访问。

在执行a.Greet()时,JavaScript将首先在对象a的属性列表中搜索Greet。如果没有找到,它将在a. Since a.__proto__和Foo的__proto__链中上升。prototype是同一个对象,JavaScript会找到Greet()方法并执行它。

我希望,现在prototype和__proto__被简化了一点。

!!!这是世界上最好的解释!!!!!

var q = {}
var prototype = {prop: 11}

q.prop // undefined
q.__proto__ = prototype
q.prop // 11

在函数构造函数中,当我们编写新Class时,javascript引擎会自动调用这个q.__proto__ = prototype,并在__proto__道具中设置Class.prototype

function Class(){}
Class.prototype = {prop: 999} // set prototype as we need, before call new

var q = new Class() // q.__proto__ = Class.prototype
q.prop // 999

享受%)