这张图再次表明,每个对象都有一个原型。构造函数
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年)。
正如这句话所说
__proto__是用于查找链的实际对象
原型是用来构建的对象
当你用new创建一个对象时:
(新的Foo)。__proto__ === Foo.prototype;
(新的Foo)。原型=== undefined;
我们可以进一步注意到,使用函数构造函数创建的对象的__proto__属性指向相应构造函数的prototype属性所指向的内存位置。
如果我们改变构造函数的prototype的内存位置,派生对象的__proto__仍将继续指向原始地址空间。因此,要使公共属性沿着继承链向下可用,总是将属性附加到构造函数函数原型,而不是重新初始化它(这会改变它的内存地址)。
考虑下面的例子:
function Human(){
this.speed = 25;
}
var himansh = new Human();
Human.prototype.showSpeed = function(){
return this.speed;
}
himansh.__proto__ === Human.prototype; //true
himansh.showSpeed(); //25
//now re-initialzing the Human.prototype aka changing its memory location
Human.prototype = {lhs: 2, rhs:3}
//himansh.__proto__ will still continue to point towards the same original memory location.
himansh.__proto__ === Human.prototype; //false
himansh.showSpeed(); //25
在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是它的值。这是所有。
为了让它更容易理解,看看这篇文章顶部的图表(由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的值(它的原型)。
我希望现在大家都明白了。